--- a/Context.st Wed May 27 06:37:28 2015 +0200
+++ b/Context.st Thu May 28 06:50:45 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
--- a/Method.st Wed May 27 06:37:28 2015 +0200
+++ b/Method.st Thu May 28 06:50:45 2015 +0200
@@ -947,9 +947,12 @@
!
annotations
+ "return (a copy) of the annotations array"
+
| retval |
annotations isNil ifTrue:[^ #()].
+
retval := Array new: annotations size.
1 to: annotations size do: [:i|
retval at: i put: (self annotationAtIndex: i).
@@ -1994,11 +1997,14 @@
annotationAtIndex: index
"return the annotation at given index.
- any raw annotation array is lazily initialized"
+ any raw annotation array (as generated by the compiler)
+ is lazily initialized from the 2-element format to real annotation instances here.
+ This is done to avoid the need for knowledge about annotation instances in the stc compiler."
| annotationOrArray annotation args |
annotations isNil ifTrue:[^nil].
+
annotationOrArray := annotation := annotations at: index.
annotationOrArray isArray ifTrue:[
args := annotationOrArray size == 2
@@ -3904,11 +3910,11 @@
!Method class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.460 2015-05-18 15:19:10 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.461 2015-05-27 14:28:15 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.460 2015-05-18 15:19:10 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Method.st,v 1.461 2015-05-27 14:28:15 cg Exp $'
!
version_SVN
--- a/SmallInteger.st Wed May 27 06:37:28 2015 +0200
+++ b/SmallInteger.st Thu May 28 06:50:45 2015 +0200
@@ -1871,12 +1871,18 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
- int idx = index.intValue() - 1;
-
- if (idx <= 7) {
- int byteVal = (int)((self.longValue() >> (idx * 8)) & 0xFF);
-
- return context._RETURN( STInteger._new(byteVal) );
+ int idx0Based = index.intValue() - 1;
+
+ if (idx0Based <= 7) {
+ long myVal = self.longValue();
+ if (myVal < 0) {
+ myVal = -myVal;
+ }
+ int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
+ return __c__._RETURN( STInteger._qnew(byteVal) );
+ }
+ if (idx0Based > 0) {
+ return __c__._RETURN( STInteger._0 );
}
#else
REGISTER INT val;
@@ -1945,7 +1951,22 @@
for negative ones, the actual bit representation is returned."
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ int idx0Based = index.intValue() - 1;
+ long myVal = self.longValue();
+
+ if (idx0Based <= 7) {
+ int byteVal = (int)((myVal >> (idx0Based * 8)) & 0xFF);
+ return __c__._RETURN( STInteger._qnew(byteVal) );
+ }
+ if (idx0Based > 0) {
+ if (myVal < 0) {
+ return __c__._RETURN( STInteger._M1 );
+ } else {
+ return __c__._RETURN( STInteger._0 );
+ }
+ }
+#else
REGISTER INT val;
INT idx;
@@ -2007,7 +2028,7 @@
!
digitBytes
- "return a byteArray filled with the receivers bits
+ "return a byteArray filled with the receiver's bits
(8 bits of the absolute value per element),
least significant byte is first"
@@ -2115,7 +2136,7 @@
!
digitBytesMSB
- "return a byteArray filled with the receivers bits
+ "return a byteArray filled with the receiver's bits
(8 bits of the absolute value per element),
most significant byte is first"
@@ -2228,44 +2249,57 @@
is returned."
%{ /* NOCONTEXT */
-#ifndef __SCHTEAM__
+#ifdef __SCHTEAM__
+ long val = self.longValue();
+ int offs = 0;
+
+ if (val < 0) val = -val;
+ if ((val & 0xFFFFFFFF00000000L) != 0) {
+ val >>= 32;
+ offs = 4;
+ }
+ if ((val & 0xFFFF0000) != 0) {
+ if ((val & 0xFF000000) != 0) {
+ offs += 4;
+ } else {
+ offs += 3;
+ }
+ } else {
+ if ((val & 0x0000FF00)!= 0) {
+ offs += 2;
+ } else {
+ offs += 1;
+ }
+ }
+ return __c__._RETURN( STInteger._qnew(offs) );
+#else
INT val = __intVal(self);
+ int offs = 0;
if (val < 0) {
val = -val;
}
# if __POINTER_SIZE__ == 8
if (val & 0xFFFFFFFF00000000L) {
- if (val & 0xFFFF000000000000L) {
- if (val & 0xFF00000000000000L) {
- RETURN ( __mkSmallInteger(8));
- } else {
- RETURN ( __mkSmallInteger(7));
- }
- } else {
- if (val & 0x0000FF0000000000L) {
- RETURN ( __mkSmallInteger(6));
- } else {
- RETURN ( __mkSmallInteger(5));
- }
- }
+ val >>= 32;
+ offs = 4;
}
# endif
if (val & 0xFFFF0000) {
if (val & 0xFF000000) {
- RETURN ( __mkSmallInteger(4));
+ RETURN ( __mkSmallInteger(4+offs));
} else {
- RETURN ( __mkSmallInteger(3));
+ RETURN ( __mkSmallInteger(3+offs));
}
} else {
if (val & 0x0000FF00) {
- RETURN ( __mkSmallInteger(2));
+ RETURN ( __mkSmallInteger(2+offs));
} else {
- RETURN ( __mkSmallInteger(1));
+ RETURN ( __mkSmallInteger(1+offs));
}
}
-#endif
+#endif /* not SCHTEAM */
%}.
^ self abs highBit - 1 // 8 + 1
@@ -2589,7 +2623,7 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
- return context._RETURN( self.eqP( aNumber ));
+ return context._RETURN( self.eqvP( aNumber ));
#else
if (aNumber == self) {
@@ -2766,7 +2800,7 @@
%{ /* NOCONTEXT */
#ifdef __SCHTEAM__
- return context._RETURN( (self.eqP( aNumber ) == STObject.True) ? STObject.False : STObject.True);
+ return context._RETURN( (self.eqvP( aNumber ) == STObject.True) ? STObject.False : STObject.True);
/* NOTREACHED */
#else
@@ -3743,12 +3777,17 @@
asBCD
"return an integer which represents the BCD encoded value of the receiver;
that is: each digit of its decimal representation is placed into a nibble
- of the result. (aka 162 -> 0x162).
+ of the result. (aka 162 -> 0x162). The BCD hex string looks like the original decimal.
This conversion is useful for some communication protocols,
or control systems, which represent numbers this way..."
%{ /* NOCONTEXT */
#ifndef __SCHTEAM__
+ // the following code is a leftover from times when division was expensive;
+ // in modern cpu's, conditional branches are often more expensive than divisions,
+ // so it is questionable, if the effort below is still worth it.
+ // (and asBCD is really used seldom in some serial communication protocols
+ // for control systems)
int i;
INT _10000000s = 0, _1000000s = 0;
INT _100000s = 0, _10000s = 0, _1000s = 0;
@@ -4941,11 +4980,11 @@
!SmallInteger class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.238 2015-05-24 12:52:47 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.239 2015-05-27 12:49:13 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.238 2015-05-24 12:52:47 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/SmallInteger.st,v 1.239 2015-05-27 12:49:13 cg Exp $'
! !