[Vm-dev] [commit] r2592 - update to version 4.10.2
commits at squeakvm.org
commits at squeakvm.org
Wed Sep 12 22:00:41 UTC 2012
Author: piumarta
Date: 2012-09-12 15:00:41 -0700 (Wed, 12 Sep 2012)
New Revision: 2592
Modified:
trunk/platforms/unix/src/vm/interp.c
trunk/platforms/unix/src/vm/interp.h
Log:
update to version 4.10.2
Modified: trunk/platforms/unix/src/vm/interp.c
===================================================================
--- trunk/platforms/unix/src/vm/interp.c 2012-09-12 21:59:25 UTC (rev 2591)
+++ trunk/platforms/unix/src/vm/interp.c 2012-09-12 22:00:41 UTC (rev 2592)
@@ -1,5 +1,5 @@
-/* Automatically generated from Squeak on 30 July 2012 4:52:23 pm
- by VMMaker 4.9.8
+/* Automatically generated from Squeak on 13 September 2012 6:51:39 am
+ by VMMaker 4.10.2
*/
#if 1
# define SQ_USE_GLOBAL_STRUCT 1
@@ -111,7 +111,9 @@
#define ClassFloat 9
#define ClassInteger 5
#define ClassLargeNegativeInteger 42
+#define ClassLargeNegativeIntegerCompactIndex 4
#define ClassLargePositiveInteger 13
+#define ClassLargePositiveIntegerCompactIndex 5
#define ClassMessage 15
#define ClassMethodContext 10
#define ClassPoint 12
@@ -156,7 +158,7 @@
#define InitialIPIndex 4
#define InstanceSpecificationIndex 2
#define InstructionPointerIndex 1
-#define InterpreterSourceVersion "4.9.8"
+#define InterpreterSourceVersion "4.10.2"
#define InvokeCallbackSelector 53
#define LargeContextBit 262144
#define LastLinkIndex 1
@@ -393,6 +395,7 @@
sqInt isIndexable(sqInt oop);
sqInt isIntegerObject(sqInt objectPointer);
sqInt isIntegerValue(sqInt intValue);
+sqInt isNegativeIntegerValueOf(sqInt oop);
sqInt isPointers(sqInt oop);
sqInt isWeak(sqInt oop);
sqInt isWords(sqInt oop);
@@ -410,6 +413,8 @@
sqInt lookupMethodInDictionary(sqInt dictionary);
sqInt lookupMethodNoMNUEtcInClass(sqInt class);
sqInt lowestFreeAfter(sqInt chunk);
+sqInt magnitude64BitIntegerForneg(usqLong magnitude, sqInt isNegative);
+usqLong magnitude64BitValueOf(sqInt oop);
sqInt makePointwithxValueyValue(sqInt xValue, sqInt yValue);
sqInt mapPointersInObjectsFromto(sqInt memStart, sqInt memEnd);
sqInt markAndTrace(sqInt oop);
@@ -599,6 +604,9 @@
sqInt primitiveListExternalModule(void);
sqInt primitiveLoadImageSegment(void);
sqInt primitiveLoadInstVar(void);
+#pragma export on
+EXPORT(sqInt) primitiveLocalMicrosecondClock(void);
+#pragma export off
sqInt primitiveLogN(void);
sqInt primitiveLowSpaceSemaphore(void);
sqInt primitiveMakePoint(void);
@@ -658,6 +666,9 @@
EXPORT(sqInt) primitiveQuoLargeIntegers(void);
#pragma export off
sqInt primitiveRelinquishProcessor(void);
+#pragma export on
+EXPORT(sqInt) primitiveRemLargeIntegers(void);
+#pragma export off
sqInt primitiveResponse(void);
sqInt primitiveResume(void);
#pragma export on
@@ -707,6 +718,9 @@
sqInt primitiveTestDisplayDepth(void);
sqInt primitiveTimesTwoPower(void);
sqInt primitiveTruncated(void);
+#pragma export on
+EXPORT(sqInt) primitiveUTCMicrosecondClock(void);
+#pragma export off
sqInt primitiveUnloadModule(void);
#pragma export on
EXPORT(sqInt) primitiveUtcWithOffset(void);
@@ -1160,8 +1174,8 @@
/* 237*/ (void *)primitiveFail,
/* 238*/ (void *)primitiveFail,
/* 239*/ (void *)primitiveFail,
- /* 240*/ (void *)primitiveFail,
- /* 241*/ (void *)primitiveFail,
+ /* 240*/ (void *)primitiveUTCMicrosecondClock,
+ /* 241*/ (void *)primitiveLocalMicrosecondClock,
/* 242*/ (void *)primitiveFail,
/* 243*/ (void *)primitiveFail,
/* 244*/ (void *)primitiveFail,
@@ -13036,6 +13050,60 @@
}
+/* Answer true if integer object is negative.
+ Fail if object pointed by oop i not an integer. */
+
+sqInt isNegativeIntegerValueOf(sqInt oop) {
+register struct foo * foo = &fum;
+ sqInt ok;
+ sqInt smallInt;
+ sqInt classOop;
+ sqInt ccIndex;
+ sqInt classOop1;
+ sqInt ccIndex1;
+ sqInt oop1;
+ sqInt oop2;
+
+ if ((oop & 1)) {
+ smallInt = (oop >> 1);
+ return smallInt < 0;
+ }
+ /* begin isClassOfNonImm:equalTo:compactClassIndex: */
+ /* begin fetchPointer:ofObject: */
+ oop1 = foo->specialObjectsOop;
+ classOop = longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger << (SHIFT_FOR_WORD)));
+ assert(!((oop & 1)));
+ ccIndex = (((usqInt) (longAt(oop))) >> 12) & 31;
+ ok = (ClassLargePositiveIntegerCompactIndex == 0
+ ? (ccIndex == 0
+ ? ((longAt(oop - (BASE_HEADER_SIZE))) & (ALL_BUT_TYPE_MASK)) == classOop
+ : 0)
+ : ClassLargePositiveIntegerCompactIndex == ccIndex);
+ if (ok) {
+ return 0;
+ }
+ /* begin isClassOfNonImm:equalTo:compactClassIndex: */
+ /* begin fetchPointer:ofObject: */
+ oop2 = foo->specialObjectsOop;
+ classOop1 = longAt((oop2 + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)));
+ assert(!((oop & 1)));
+ ccIndex1 = (((usqInt) (longAt(oop))) >> 12) & 31;
+ ok = (ClassLargeNegativeIntegerCompactIndex == 0
+ ? (ccIndex1 == 0
+ ? ((longAt(oop - (BASE_HEADER_SIZE))) & (ALL_BUT_TYPE_MASK)) == classOop1
+ : 0)
+ : ClassLargeNegativeIntegerCompactIndex == ccIndex1);
+ if (ok) {
+ return 1;
+ }
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ return 0;
+}
+
+
/* Answer true if the argument has only fields that can hold oops. See comment in formatOf: */
sqInt isPointers(sqInt oop) {
@@ -13529,6 +13597,160 @@
}
+/* Return a Large Integer object for the given integer magnitude and sign */
+
+sqInt magnitude64BitIntegerForneg(usqLong magnitude, sqInt isNegative) {
+register struct foo * foo = &fum;
+ usqInt highWord;
+ sqInt i;
+ sqInt intValue;
+ sqInt isSmall;
+ sqInt largeClass;
+ sqInt newLargeInteger;
+ sqInt smallVal;
+ sqInt sz;
+ sqInt oop;
+ sqInt oop1;
+
+ isSmall = (isNegative
+ ? magnitude <= 1073741824
+ : magnitude < 1073741824);
+ if (isSmall) {
+ smallVal = ((sqInt) magnitude);
+ if (isNegative) {
+ smallVal = 0 - smallVal;
+ }
+ return ((smallVal << 1) | 1);
+ }
+ if (isNegative) {
+ /* begin fetchPointer:ofObject: */
+ oop = foo->specialObjectsOop;
+ largeClass = longAt((oop + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)));
+ } else {
+ /* begin fetchPointer:ofObject: */
+ oop1 = foo->specialObjectsOop;
+ largeClass = longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger << (SHIFT_FOR_WORD)));
+ }
+
+ /* shift is coerced to usqInt otherwise */
+
+ highWord = magnitude >> 32;
+ if (highWord == 0) {
+ sz = 4;
+ } else {
+ sz = 5;
+ if (!(((highWord = ((usqInt) highWord) >> 8)) == 0)) {
+ sz += 1;
+ }
+ if (!(((highWord = ((usqInt) highWord) >> 8)) == 0)) {
+ sz += 1;
+ }
+ if (!(((highWord = ((usqInt) highWord) >> 8)) == 0)) {
+ sz += 1;
+ }
+ }
+ newLargeInteger = instantiateClassindexableSize(largeClass, sz);
+ for (i = 0; i <= (sz - 1); i += 1) {
+ intValue = (magnitude >> (i * 8)) & 255;
+ byteAtput((newLargeInteger + (BASE_HEADER_SIZE)) + i, intValue);
+ }
+ return newLargeInteger;
+}
+
+
+/* Convert the given object into an integer value.
+ The object may be either a positive SmallInteger or a eight-byte LargeInteger. */
+
+usqLong magnitude64BitValueOf(sqInt oop) {
+register struct foo * foo = &fum;
+ sqInt i;
+ sqInt ok;
+ sqInt smallIntValue;
+ sqInt sz;
+ usqLong value;
+ sqInt classOop;
+ sqInt ccIndex;
+ sqInt classOop1;
+ sqInt ccIndex1;
+ sqInt header;
+ sqInt oop1;
+ sqInt oop2;
+ sqInt sz1;
+
+ if ((oop & 1)) {
+ smallIntValue = (oop >> 1);
+ if (smallIntValue < 0) {
+ smallIntValue = 0 - smallIntValue;
+ }
+ return ((usqLong) smallIntValue);
+ }
+ /* begin isClassOfNonImm:equalTo:compactClassIndex: */
+ /* begin fetchPointer:ofObject: */
+ oop2 = foo->specialObjectsOop;
+ classOop1 = longAt((oop2 + (BASE_HEADER_SIZE)) + (ClassLargePositiveInteger << (SHIFT_FOR_WORD)));
+ assert(!((oop & 1)));
+ ccIndex1 = (((usqInt) (longAt(oop))) >> 12) & 31;
+ ok = (ClassLargePositiveIntegerCompactIndex == 0
+ ? (ccIndex1 == 0
+ ? ((longAt(oop - (BASE_HEADER_SIZE))) & (ALL_BUT_TYPE_MASK)) == classOop1
+ : 0)
+ : ClassLargePositiveIntegerCompactIndex == ccIndex1);
+ if (!(ok)) {
+ /* begin isClassOfNonImm:equalTo:compactClassIndex: */
+ /* begin fetchPointer:ofObject: */
+ oop1 = foo->specialObjectsOop;
+ classOop = longAt((oop1 + (BASE_HEADER_SIZE)) + (ClassLargeNegativeInteger << (SHIFT_FOR_WORD)));
+ assert(!((oop & 1)));
+ ccIndex = (((usqInt) (longAt(oop))) >> 12) & 31;
+ ok = (ClassLargeNegativeIntegerCompactIndex == 0
+ ? (ccIndex == 0
+ ? ((longAt(oop - (BASE_HEADER_SIZE))) & (ALL_BUT_TYPE_MASK)) == classOop
+ : 0)
+ : ClassLargeNegativeIntegerCompactIndex == ccIndex);
+ if (!(ok)) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ return null;
+ }
+ }
+ /* begin lengthOf: */
+ header = longAt(oop);
+ /* begin lengthOf:baseHeader:format: */
+ if ((header & TypeMask) == HeaderTypeSizeAndClass) {
+ sz1 = (longAt(oop - ((BYTES_PER_WORD) * 2))) & (LONG_SIZE_MASK);
+ } else {
+ sz1 = header & (SIZE_MASK);
+ }
+ sz1 -= header & (SIZE_4_BIT);
+ if (((((usqInt) header) >> 8) & 15) <= 4) {
+ sz = ((usqInt) (sz1 - (BASE_HEADER_SIZE))) >> (SHIFT_FOR_WORD);
+ goto l1;
+ }
+ if (((((usqInt) header) >> 8) & 15) < 8) {
+ sz = ((usqInt) (sz1 - (BASE_HEADER_SIZE))) >> 2;
+ goto l1;
+ } else {
+ sz = (sz1 - (BASE_HEADER_SIZE)) - (((((usqInt) header) >> 8) & 15) & 3);
+ goto l1;
+ }
+l1: /* end lengthOf:baseHeader:format: */;
+ if (sz > (sizeof(sqLong))) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ return null;
+ }
+ value = 0;
+ for (i = 0; i <= (sz - 1); i += 1) {
+ value += (((sqLong) (byteAt((oop + (BASE_HEADER_SIZE)) + i)))) << (i * 8);
+ }
+ return value;
+}
+
+
/* make a Point xValue at yValue.
We know both will be integers so no value nor root checking is needed */
@@ -15172,34 +15394,46 @@
EXPORT(sqInt) primitiveAddLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong result;
+ usqLong result;
+ sqInt resultIsNegative;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
if (!(!foo->primFailCode)) {
return null;
}
-
- /* Now check overflow conditions. First is whether rcvr and arg are of the same sign.
- If they are we need to check for overflow more carefully. */
-
- result = integerRcvr + integerArg;
- if (!((integerRcvr ^ integerArg) < 0)) {
- if ((integerRcvr ^ result) < 0) {
+ if (aIsNegative == bIsNegative) {
+ if (a > (18446744073709551615U - b)) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
}
+ return null;
}
+ result = a + b;
+ resultIsNegative = aIsNegative;
+ } else {
+ if (a >= b) {
+ result = a - b;
+ resultIsNegative = aIsNegative;
+ } else {
+ result = b - a;
+ resultIsNegative = bIsNegative;
+ }
}
- if (!(!foo->primFailCode)) {
- return null;
- }
- oopResult = signed64BitIntegerFor(result);
+ oopResult = magnitude64BitIntegerForneg(result, resultIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -15863,14 +16097,16 @@
}
-/* Primitive logical operations for large integers in 64 bit range */
+/* Primitive arithmetic operations for large integers in 64 bit range */
EXPORT(sqInt) primitiveBitShiftLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong shifted;
+ usqLong result;
+ sqInt shift;
sqInt sp;
sqInt integerPointer;
@@ -15878,48 +16114,50 @@
integerPointer = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
/* begin checkedIntegerValueOf: */
if ((integerPointer & 1)) {
- integerArg = (integerPointer >> 1);
+ shift = (integerPointer >> 1);
goto l1;
} else {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
}
- integerArg = 0;
+ shift = 0;
goto l1;
}
- integerArg = null;
+ shift = null;
l1: /* end stackIntegerValue: */;
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
- if (!foo->primFailCode) {
- if (integerArg >= 0) {
- /* begin success: */
- if (!(integerArg < 64)) {
- if (!foo->primFailCode) {
- foo->primFailCode = 1;
- }
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ a = magnitude64BitValueOf(oopRcvr);
+ if (!(!foo->primFailCode)) {
+ return null;
+ }
+ if (shift >= 0) {
+
+ /* Protect against overflow */
+ /* This is to avoid undue (usqInt) cast */
+
+ result = 18446744073709551615U;
+ if ((shift >= 64) || (a > (((usqInt) result) >> shift))) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
}
- shifted = integerRcvr << integerArg;
- /* begin success: */
- if (!((shifted >> integerArg) == integerRcvr)) {
- if (!foo->primFailCode) {
- foo->primFailCode = 1;
- }
- }
+ return null;
+ }
+ result = a << shift;
+ } else {
+ shift = 0 - shift;
+ if (shift >= 64) {
+ result = 0;
} else {
- /* begin success: */
- if (!(integerArg > -64)) {
- if (!foo->primFailCode) {
- foo->primFailCode = 1;
- }
- }
- shifted = integerRcvr >> (0 - integerArg);
+ result = ((usqInt) a) >> shift;
}
+ if (aIsNegative && ((result << shift) != a)) {
+ result += 1;
+ }
}
- if (!(!foo->primFailCode)) {
- return null;
- }
- oopResult = signed64BitIntegerFor(shifted);
+ oopResult = magnitude64BitIntegerForneg(result, aIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -16876,17 +17114,24 @@
EXPORT(sqInt) primitiveDivLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong posArg;
- sqLong posRcvr;
- sqLong result;
+ usqLong rem;
+ usqLong result;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
- if (integerArg == 0) {
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
+ if (b == 0) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
@@ -16895,50 +17140,23 @@
if (!(!foo->primFailCode)) {
return null;
}
- if (integerRcvr > 0) {
- if (integerArg > 0) {
- result = integerRcvr / integerArg;
- } else {
+ result = a / b;
+ if (!(a == 0)) {
+ if (!(bIsNegative == aIsNegative)) {
- /* round negative result toward negative infinity */
+ /* Round toward negative infinity */
- posArg = 0 - integerArg;
+ rem = a % b;
+ if (!(rem == 0)) {
- /* can overflow! */
+ /* This can not overflow, because b > 1, otherwise rem = 0 */
- posRcvr = integerRcvr + (posArg - 1);
- if (posRcvr < 0) {
- /* begin primitiveFail */
- if (foo->primFailCode == 0) {
- foo->primFailCode = 1;
- }
+ result += 1;
}
- result = 0 - (posRcvr / posArg);
}
- } else {
- posRcvr = 0 - integerRcvr;
- if (integerArg > 0) {
-
- /* round negative result toward negative infinity */
- /* can overflow! */
-
- posRcvr += integerArg - 1;
- if (posRcvr < 0) {
- /* begin primitiveFail */
- if (foo->primFailCode == 0) {
- foo->primFailCode = 1;
- }
- }
- result = 0 - (posRcvr / integerArg);
- } else {
- posArg = 0 - integerArg;
- result = posRcvr / posArg;
- }
}
+ oopResult = magnitude64BitIntegerForneg(result, bIsNegative != aIsNegative);
if (!foo->primFailCode) {
- oopResult = signed64BitIntegerFor(result);
- }
- if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
foo->stackPointer = sp;
@@ -17018,25 +17236,34 @@
EXPORT(sqInt) primitiveDivideLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong result;
+ usqLong result;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
- if (!((integerArg != 0) && ((integerRcvr % integerArg) == 0))) {
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
+ if (!(!foo->primFailCode)) {
+ return null;
+ }
+ if (!((b != 0) && ((a % b) == 0))) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
}
- }
- if (!(!foo->primFailCode)) {
return null;
}
- result = integerRcvr / integerArg;
- oopResult = signed64BitIntegerFor(result);
+ result = a / b;
+ oopResult = magnitude64BitIntegerForneg(result, aIsNegative != bIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -20354,6 +20581,45 @@
}
+/* Answer the local microseconds since the Smalltalk epoch. The value is
+ derived from the Posix epoch (see primitiveUTCMicrosecondClock) with a
+ constant offset corresponding to elapsed microseconds between the two
+ epochs according to RFC 868, and with an offset duration corresponding to
+ the current offset of local time from UTC. */
+
+EXPORT(sqInt) primitiveLocalMicrosecondClock(void) {
+register struct foo * foo = &fum;
+ usqLong clock;
+ static usqLong epochDelta= 2177452800000000ULL;
+ int offset;
+ usqLong offsetMillis;
+ sqInt uSecs;
+ sqInt sp;
+
+ if ((ioUtcWithOffset(&clock, &offset)) == -1) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ return null;
+ }
+
+ /* adjust for nominal Smalltalk epoch */
+
+ clock += epochDelta;
+ offsetMillis = offset;
+ offsetMillis = offsetMillis * 1000000;
+
+ /* adjust for local time offset */
+
+ clock += offsetMillis;
+ uSecs = positive64BitIntegerFor(clock);
+ /* begin pop:thenPush: */
+ longAtput((sp = foo->stackPointer - ((1 - 1) * (BYTES_PER_WORD))), uSecs);
+ foo->stackPointer = sp;
+}
+
+
/* Natural log. */
sqInt primitiveLogN(void) {
@@ -20583,15 +20849,23 @@
EXPORT(sqInt) primitiveModLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong result;
+ usqLong result;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
- if (integerArg == 0) {
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
+ if (b == 0) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
@@ -20601,19 +20875,15 @@
return null;
}
- /* ensure that the result has the same sign as the integerArg */
+ /* Handle remainder of same sign as argument */
- result = integerRcvr % integerArg;
- if (integerArg < 0) {
- if (result > 0) {
- result += integerArg;
+ result = a % b;
+ if (!(result == 0)) {
+ if (!(bIsNegative == aIsNegative)) {
+ result = b - result;
}
- } else {
- if (result < 0) {
- result += integerArg;
- }
}
- oopResult = signed64BitIntegerFor(result);
+ oopResult = magnitude64BitIntegerForneg(result, bIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -20763,31 +21033,34 @@
EXPORT(sqInt) primitiveMultiplyLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqInt r;
- sqLong result;
- sqInt twoToThe64;
+ usqLong result;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
if (!(!foo->primFailCode)) {
return null;
}
-
- /* check for C overflow by seeing if computation is reversible */
-
- result = integerRcvr * integerArg;
- if ((integerArg == 0) || ((result / integerArg) == integerRcvr)) {
- oopResult = signed64BitIntegerFor(result);
- } else {
+ if ((a > 1) && ((b > 1) && (a > (18446744073709551615U / b)))) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
}
+ return null;
}
+ result = a * b;
+ oopResult = magnitude64BitIntegerForneg(result, aIsNegative != bIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -22260,15 +22533,23 @@
EXPORT(sqInt) primitiveQuoLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong result;
+ usqLong result;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
- if (integerArg == 0) {
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
+ if (b == 0) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
@@ -22277,20 +22558,8 @@
if (!(!foo->primFailCode)) {
return null;
}
- if (integerRcvr > 0) {
- if (integerArg > 0) {
- result = integerRcvr / integerArg;
- } else {
- result = 0 - (integerRcvr / (0 - integerArg));
- }
- } else {
- if (integerArg > 0) {
- result = 0 - ((0 - integerRcvr) / integerArg);
- } else {
- result = (0 - integerRcvr) / (0 - integerArg);
- }
- }
- oopResult = signed64BitIntegerFor(result);
+ result = a / b;
+ oopResult = magnitude64BitIntegerForneg(result, bIsNegative != aIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -22329,6 +22598,45 @@
}
}
+
+/* Primitive arithmetic operations for large integers in 64 bit range */
+
+EXPORT(sqInt) primitiveRemLargeIntegers(void) {
+register struct foo * foo = &fum;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
+ sqInt oopResult;
+ usqLong result;
+ sqInt sp;
+
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
+ if (b == 0) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ }
+ if (!(!foo->primFailCode)) {
+ return null;
+ }
+ result = a % b;
+ oopResult = magnitude64BitIntegerForneg(result, aIsNegative != bIsNegative);
+ if (!foo->primFailCode) {
+ /* begin pop:thenPush: */
+ longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
+ foo->stackPointer = sp;
+ }
+}
+
sqInt primitiveResponse(void) {
register struct foo * foo = &fum;
sqInt delta;
@@ -24670,49 +24978,46 @@
EXPORT(sqInt) primitiveSubtractLargeIntegers(void) {
register struct foo * foo = &fum;
- sqLong integerArg;
- sqLong integerArgNegated;
- sqLong integerRcvr;
+ usqLong a;
+ sqInt aIsNegative;
+ usqLong b;
+ sqInt bIsNegative;
+ sqInt oopArg;
+ sqInt oopRcvr;
sqInt oopResult;
- sqLong result;
+ usqLong result;
+ sqInt resultIsNegative;
sqInt sp;
- integerArg = signed64BitValueOf(longAt(foo->stackPointer - (0 * (BYTES_PER_WORD))));
- integerRcvr = signed64BitValueOf(longAt(foo->stackPointer - (1 * (BYTES_PER_WORD))));
+ oopArg = longAt(foo->stackPointer - (0 * (BYTES_PER_WORD)));
+ oopRcvr = longAt(foo->stackPointer - (1 * (BYTES_PER_WORD)));
+ aIsNegative = isNegativeIntegerValueOf(oopRcvr);
+ bIsNegative = isNegativeIntegerValueOf(oopArg);
+ a = magnitude64BitValueOf(oopRcvr);
+ b = magnitude64BitValueOf(oopArg);
if (!(!foo->primFailCode)) {
return null;
}
- if (integerArg == 0) {
- result = integerRcvr;
- } else {
-
- /* Reverse the argument so that we can recycle the overflow code from addition.
- But the most -ve 64-bit value can overflow, so check; 0 - most -ve = most -ve */
-
- integerArgNegated = 0 - integerArg;
- if (integerArgNegated == integerArg) {
+ if (aIsNegative != bIsNegative) {
+ if (a > (18446744073709551615U - b)) {
/* begin primitiveFail */
if (foo->primFailCode == 0) {
foo->primFailCode = 1;
}
return null;
}
-
- /* Now check overflow conditions. First is whether rcvr and arg are of the same sign.
- If they are we need to check for overflow more carefully. */
-
- result = integerRcvr + integerArgNegated;
- if (!((integerRcvr ^ integerArgNegated) < 0)) {
- if ((integerRcvr ^ result) < 0) {
- /* begin primitiveFail */
- if (foo->primFailCode == 0) {
- foo->primFailCode = 1;
- }
- return null;
- }
+ result = a + b;
+ resultIsNegative = aIsNegative;
+ } else {
+ if (a >= b) {
+ result = a - b;
+ resultIsNegative = aIsNegative;
+ } else {
+ result = b - a;
+ resultIsNegative = !aIsNegative;
}
}
- oopResult = signed64BitIntegerFor(result);
+ oopResult = magnitude64BitIntegerForneg(result, resultIsNegative);
if (!foo->primFailCode) {
/* begin pop:thenPush: */
longAtput((sp = foo->stackPointer - ((2 - 1) * (BYTES_PER_WORD))), oopResult);
@@ -24989,6 +25294,34 @@
}
+/* Answer the UTC microseconds since the Smalltalk epoch. The value is
+ derived from the Posix epoch (see primitiveUTCMicrosecondClock) with a
+ constant offset corresponding to elapsed microseconds between the two
+ epochs according to RFC 868. */
+
+EXPORT(sqInt) primitiveUTCMicrosecondClock(void) {
+register struct foo * foo = &fum;
+ usqLong clock;
+ static usqLong epochDelta= 2177452800000000ULL;
+ int offset;
+ sqInt uSecs;
+ sqInt sp;
+
+ if ((ioUtcWithOffset(&clock, &offset)) == -1) {
+ /* begin primitiveFail */
+ if (foo->primFailCode == 0) {
+ foo->primFailCode = 1;
+ }
+ return null;
+ }
+ clock += epochDelta;
+ uSecs = positive64BitIntegerFor(clock);
+ /* begin pop:thenPush: */
+ longAtput((sp = foo->stackPointer - ((1 - 1) * (BYTES_PER_WORD))), uSecs);
+ foo->stackPointer = sp;
+}
+
+
/* Primitive. Unload the module with the given name. */
/* Reloading of the module will happen *later* automatically, when a
function from it is called. This is ensured by invalidating current sessionID. */
@@ -29052,6 +29385,7 @@
{"", "primitiveRootTable", (void*)primitiveRootTable},
{"", "primitiveImageFormatVersion", (void*)primitiveImageFormatVersion},
{"", "dumpImage", (void*)dumpImage},
+ {"", "primitiveLocalMicrosecondClock", (void*)primitiveLocalMicrosecondClock},
{"", "callInterpreter", (void*)callInterpreter},
{"", "primitiveDivLargeIntegers", (void*)primitiveDivLargeIntegers},
{"", "primitiveMillisecondClockMask", (void*)primitiveMillisecondClockMask},
@@ -29070,8 +29404,10 @@
{"", "primitiveMultiplyLargeIntegers", (void*)primitiveMultiplyLargeIntegers},
{"", "primitiveIsRoot", (void*)primitiveIsRoot},
{"", "moduleUnloaded", (void*)moduleUnloaded},
+ {"", "primitiveUTCMicrosecondClock", (void*)primitiveUTCMicrosecondClock},
+ {"", "addGCRoot", (void*)addGCRoot},
{"", "primitiveRootTableAt", (void*)primitiveRootTableAt},
- {"", "addGCRoot", (void*)addGCRoot},
+ {"", "primitiveRemLargeIntegers", (void*)primitiveRemLargeIntegers},
{"", "getStackPointer", (void*)getStackPointer},
{"", "primitiveNotEqualLargeIntegers", (void*)primitiveNotEqualLargeIntegers},
{"", "callbackEnter", (void*)callbackEnter},
Modified: trunk/platforms/unix/src/vm/interp.h
===================================================================
--- trunk/platforms/unix/src/vm/interp.h 2012-09-12 21:59:25 UTC (rev 2591)
+++ trunk/platforms/unix/src/vm/interp.h 2012-09-12 22:00:41 UTC (rev 2592)
@@ -1,12 +1,12 @@
-/* Automatically generated from Squeak on 30 July 2012 4:52:16 pm
- by VMMaker 4.9.8
+/* Automatically generated from Squeak on 13 September 2012 6:51:36 am
+ by VMMaker 4.10.2
*/
#ifndef HAVE_INTERP_H
# define HAVE_INTERP_H
#endif
-#define VMMAKER_VERSION "4.9.8"
+#define VMMAKER_VERSION "4.10.2"
#define VM_PROXY_MAJOR 1
#define VM_PROXY_MINOR 9
More information about the Vm-dev
mailing list