Context.st
changeset 18412 dc22d0d82e28
parent 18408 6f1d5142cbc3
child 18413 1ae6dae275a2
child 18437 c59fbf8e7b3a
--- a/Context.st	Wed May 27 16:28:15 2015 +0200
+++ b/Context.st	Wed May 27 21:09:55 2015 +0200
@@ -824,10 +824,18 @@
      invalid until needed."
 
 %{  /* NOCONTEXT */
+#ifdef __SCHTEAM__
+    if (((STContinuation)self).caller == null) {
+	return __c__._RETURN_true();
+    }
+    return __c__._RETURN_false();
+    /* NOTREACHED */
+#else
     if ( __INST(sender_) == nil ) {
 	RETURN (true);
     }
     RETURN (false);
+#endif
 %}.
     ^ self sender isNil
 !
@@ -2030,7 +2038,9 @@
      and prevents a crash in such a case."
 
 %{
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+    return __c__._RETURN( ((STContinuation)self).stSelf(__c__) );
+#else
     /*
      * special handling for (invalid) free objects.
      * these only appear if some primitiveCode does not correctly use SEND macros,
@@ -2055,7 +2065,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    return context._RETURN (self.asSTContinuation().isMarkedForUnwind() ? STObject.True : STObject.False);
+    return context._RETURN ( ((STContinuation)self).isMarkedForUnwind() );
 #else
     RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__UNWIND_MARK)) ? true : false );
 #endif
@@ -2072,7 +2082,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().markForHandle();
+    ((STContinuation)self).markForHandle();
 #else
      __INST(flags) = (OBJ)((INT)__INST(flags) | __MASKSMALLINT(__HANDLE_MARK));
 #endif
@@ -2088,7 +2098,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().markForInterrupt();
+    ((STContinuation)self).markForInterrupt();
 #else
      __markInterrupted(__ContextInstPtr(self));
 #endif
@@ -2103,7 +2113,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().markForInterruptOnUnwind();
+    ((STContinuation)self).markForInterruptOnUnwind();
 #else
      __INST(flags) = (OBJ)((INT)__INST(flags) | __MASKSMALLINT(__IRQ_ON_UNWIND));
 #endif
@@ -2117,7 +2127,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().markForRaise();
+    ((STContinuation)self).markForRaise();
 #else
      __INST(flags) = (OBJ)((INT)__INST(flags) | __MASKSMALLINT(__RAISE_MARK));
 #endif
@@ -2133,7 +2143,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().markForUnwind();
+    ((STContinuation)self).markForUnwind();
 #else
      __INST(flags) = (OBJ)((INT)__INST(flags) | __MASKSMALLINT(__UNWIND_MARK));
 #endif
@@ -2155,7 +2165,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    ((STContinuation)self).caller = aContext.asSTContinuation();
 #else
     __INST(sender_) = aContext;
 #endif
@@ -2169,7 +2179,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    self.asSTContinuation().unmarkForUnwind();
+    ((STContinuation)self).unmarkForUnwind();
 #else
     __INST(flags) = (OBJ)((INT)__INST(flags) & ~__MASKSMALLINT(__UNWIND_MARK));
 #endif
@@ -2203,13 +2213,16 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     {
-	STContinuation caller = self.sender();
+	STContinuation lastCallee = (STContinuation)self;
+	STContinuation caller = lastCallee.caller;
 
 	while (caller != null) {
 	    if (caller.isExceptionalSmalltalkContext()) {
+		caller = lastCallee.sender();   // exposed
 		return context._RETURN(caller);
 	    }
-	    caller = caller.sender();
+	    lastCallee = caller;
+	    caller = lastCallee.caller;
 	}
 	return context._RETURN( STObject.Nil );
     }
@@ -2269,7 +2282,9 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     {
-	STContinuation cont = self.sender();
+	STContinuation lastCallee = (STContinuation)self;
+	STContinuation cont = lastCallee.caller;
+
 	STObject sel1 = context.stArg(0);
 	STObject sel2 = context.stArg(1);
 	STObject sel3 = context.stArg(2);
@@ -2284,11 +2299,13 @@
 		    break;
 		}
 	    }
-	    cont = cont.sender();
+	    lastCallee = cont;
+	    cont = lastCallee.caller;
 	}
 	if (cont == null) {
 	    return __c__._RETURN_nil();
 	}
+	cont = lastCallee.sender();     // exposed
 	return __c__._RETURN(cont);
     }
     /* NOTREACHED */
@@ -2376,14 +2393,17 @@
 	    return __c__._RETURN(self);
 	}
 
-	STContinuation theContext = self.sender();
+	STContinuation lastCallee = (STContinuation)self;
+	STContinuation theContext = lastCallee.caller;
 
 	while (theContext != null) {
 	    if ((theContext == aContext)
 	     || theContext.isMarkedForUnwind()) {
+		theContext = lastCallee.sender();   // exposed
 		return __c__._RETURN(theContext);
 	    }
-	    theContext = theContext.sender();
+	    lastCallee = theContext;
+	    theContext = lastCallee.caller;
 	}
     }
 #else
@@ -2446,19 +2466,24 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     {
-	STContinuation theContext = self.sender();
+	STContinuation lastCallee = (STContinuation)self;
+	STContinuation theContext = lastCallee.caller;
+
 	while (theContext != null) {
 	    if (theContext.isMarkedSpecial()) {
 		if ((findHandleContext == STObject.True)
 		    && theContext.isMarkedForHandle()) {
+		    theContext = lastCallee.sender();   // exposed
 		    return __c__._RETURN(theContext);
 		}
 		if ((findRaiseContext == STObject.True)
 		    && theContext.isMarkedForRaise()) {
+		    theContext = lastCallee.sender();   // exposed
 		    return __c__._RETURN(theContext);
 		}
 	    }
-	    theContext = theContext.sender();
+	    lastCallee = theContext;
+	    theContext = lastCallee.caller;
 	}
     }
 #else
@@ -2622,8 +2647,8 @@
 
 canResume
     "return true, if the receiver allows to be resumed.
-     Due to the implementation, this requires that the context which
-     is right below the receiver is returnable."
+     In ST/X, due to the implementation, this requires that the context which
+     is right below the receiver is returnable and still active."
 
     |theContext|
 
@@ -2633,6 +2658,7 @@
     "
 %{
 #ifdef __SCHTEAM__
+    // in the SCHTEAM-engine, all contexts are resumable
     return context._RETURN_true();
 #else
     OBJ sndr;
@@ -2666,10 +2692,16 @@
      non returnable, unless a return-pragma was present in the method.
      Since this saves some administrative work in every method
      invocation and makes overall execution faster, the system classes
-     are all compiled with this flag turned on."
+     are all compiled with this flag turned on.
+     This means, that by default, it is not possible to walk up the
+     calling chain and return to an arbitrary context.
+     For contexts which are known to require this (i.e. handlers as found
+     by the exception walkers, these are marked specially (markForReturn),
+     so compilers know that they should create full featured contexts."
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
+    // in the SCHTEAM-engine, all contexts can be returned from
     return context._RETURN_true();
 #else
     RETURN ( ((INT)(__INST(flags)) & __MASKSMALLINT(__CANNOT_RETURN)) ? false : true );
@@ -2694,7 +2726,7 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ((STContinuation)self).isMarkedForHandle() );
 #else
      RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__HANDLE_MARK)) ? true : false );
 #endif
@@ -2706,12 +2738,12 @@
      A nonLifo context is one that is still on the machine stack,
      but has a reference taken and needs to be converted to a real
      object (in objectMemory) when the method/block returns.
-     You dont have to understand this - this is a special ST/X
+     You don't have to understand this - this is a special ST/X
      debug query, which may be removed without notice."
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ((STContinuation)self).isNonLifo() );
 #else
      RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__NONLIFO)) ? true : false );
 #endif
@@ -2720,15 +2752,15 @@
 
 isOnMachineStack
     "return true, if this is a machine stack context as opposed to a
-     real heap context.
-     You dont have to understand this - this is a special ST/X
+     real heap context (i.e. if it has not been captured and returned from).
+     You don't have to understand this - this is a special ST/X
      debug query, which may be removed without notice."
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ! ((STContinuation)self).isCopiedToHeap() );
 #else
-     RETURN ( (__qSpace(self) >= STACKSPACE) ? true : false );
+    RETURN ( (__qSpace(self) >= STACKSPACE) ? true : false );
 #endif
 %}
 !
@@ -2738,9 +2770,9 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ((STContinuation)self).isMarkedForRaise() );
 #else
-     RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__RAISE_MARK)) ? true : false );
+    RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__RAISE_MARK)) ? true : false );
 #endif
 %}
 !
@@ -2750,9 +2782,9 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ((STContinuation)self).isMarkedSpecial() );
 #else
-     RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__SPECIAL)) ? true : false );
+    RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__SPECIAL)) ? true : false );
 #endif
 %}
 !
@@ -2762,9 +2794,9 @@
 
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
-    ERROR("unimplemented");
+    return __c__._RETURN ( ((STContinuation)self).isMarkedForUnwind() );
 #else
-     RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__UNWIND_MARK)) ? true : false );
+    RETURN ( ((INT)__INST(flags) & __MASKSMALLINT(__UNWIND_MARK)) ? true : false );
 #endif
 %}
 !
@@ -2890,11 +2922,11 @@
 !Context class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Context.st,v 1.223 2015-05-26 18:55:30 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Context.st,v 1.224 2015-05-27 19:09:55 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic/Context.st,v 1.223 2015-05-26 18:55:30 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Context.st,v 1.224 2015-05-27 19:09:55 cg Exp $'
 !
 
 version_HG