[Vm-dev] [commit][3627] CogVM source as per VMMaker.oscog-eem.1692

commits at squeakvm.org commits at squeakvm.org
Mon Feb 22 19:11:27 UTC 2016


Revision: 3627
Author:   eliot
Date:     2016-02-22 11:11:27 -0800 (Mon, 22 Feb 2016)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1692

ThreadedFFIPlugin fixes for 64 bits.
Make ffiAddressOf:startingAt:size: & primitiveFFIIntegerAt[Put] 64-bit capable.
Use signedMachineIntegerFor: to answer result of primitiveCreateManualSurface.
Fix slips in testing for float and/or double in the ARM & X64
ffiCalloutTo:SpecOnStack:in: methods.

Mac OS makefiles.  Include dependencies to try and get plugins to be rebuilt
when things change.

Modified Paths:
--------------
    branches/Cog/README
    branches/Cog/build.macos32x86/common/Makefile.vm
    branches/Cog/build.macos64x64/common/Makefile.vm
    branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/README
===================================================================
--- branches/Cog/README	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/README	2016-02-22 19:11:27 UTC (rev 3627)
@@ -45,7 +45,8 @@
 Spur, as described on the www.mirandabanda.org blog, is a faster object
 representation which uses generation scavenging, lazy forwarding for fast
 become, a single object header format common to 32 and 64 bit versions, and a
-segmented heap that can grow and shrink, releasign memory back to the host OS.
+segmented heap that can grow and shrink, releasing memory back to the host OS.
+Newspeak, Squeak 5.0 and Pharo 5 use Spur.
 
 Another distinction is between normal single-threaded VMs that schedule "green"
 Smalltalk light-weight processes above a single-threaded VM, and multi-threaded
@@ -88,7 +89,9 @@
 can be found in Cog, or in various Monticello packages in various repositories.
 
 Each vm source directory contains several files, a subset of the following:
-	cogit.c				- the JIT; a Cogit cooperates with a CoInterpreter
+	cogit.c				- the JIT; a Cogit cooperates with a CoInterpreter.
+                          This simply includes a proessor-specific JIT file
+	cogitIA32.c et al   - relevant processor-specific JIT, selected by cogit.c
 	cogit.h				- the Cogit's API, as used by the CoInterpreter
 	cogmethod.h			- the structure of a CogMethod, the output of the Cogit
 	cointerp.c			- the CoInterpreter's source file
@@ -105,20 +108,15 @@
 
 Platform build directories
 --------------------------
-Build directories are in flux.  Currently there exist some old build directories
-such as unixbuild, cygwinbuild et al.  These are deprecated and will be removed
-before the end of 2014.  The current "official" buikd directories are of the
-form build.OS_WordSize_Processor, and include
+The current "official" build directories are of the form
+build.OS_WordSize_Processor, and include
 	build.linux32x86	- uses autoconf, gcc and make
 	build.macos32x86	- 32-bit Mac OS X using XCode and clang
 	build.macos64x64	- 64-bit Mac OS X using XCode and clang
 	build.win32x86		- uses cygwin, gcc and make
 More can be added as required.  In each there is a HowToBuild that describes
-the necessary steps to produce a VM.
+the necessary steps to compile a VM.
 
-In addition, there is a set of build directories that use the CMake build
-configuration system.  These are not yet ready to describe as of this writing.
-
 The scripts directory contains various scripts for validating and checking-in
 generated sources, packaging builds into installable artifacts (tar, msi, zip),
 and so on.  The linux builds and the packaging scripts produce outputs in the
@@ -148,8 +146,6 @@
 
 	platforms/Cross/plugins
 		- http://squeakvm.org/svn/squeak/trunk/platforms/Cross/plugins
-	platforms/iOS
-		- http://squeakvm.org/svn/squeak/trunk/platforms/iOS
 	platforms/win32/plugins
 		- http://squeakvm.org/svn/squeak/trunk/platforms/win32/plugins
 

Modified: branches/Cog/build.macos32x86/common/Makefile.vm
===================================================================
--- branches/Cog/build.macos32x86/common/Makefile.vm	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/build.macos32x86/common/Makefile.vm	2016-02-22 19:11:27 UTC (rev 3627)
@@ -210,7 +210,10 @@
 # Internal plugin.  Build as lib then link in lib
 # Check for Makefile in iOS plugins directory otherwise use default Makefile
 # N.B.  PLATDIR *must* be a relative path for this to work
-$(OBJDIR)/%.lib: getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore)
+$(OBJDIR)/%.lib: getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore) \
+					$(wildcard $(PLUGINSRCDIR)/$(*F)/*.c) \
+					$(wildcard $(PLATDIR)/Cross/plugins/$(*F)/*.*) \
+					$(wildcard $(OSXPLUGINSDIR)/$(*F)/*.*)
 	@-mkdir -p $(BLDDIR)/$(*F)
 	test $@ -ot $(call plugin-makefile,$(*F)) && rm $(BUILD)/vm/$(*F).lib || true
 	rm -f $(BUILD)/vm/$(*F).ignore
@@ -228,7 +231,10 @@
 
 # External plugin.  Build as bundle and copy to vm dir ($(OBJDIR)).
 # Check for Makefile in iOS plugins directory otherwise use default Makefile
-$(OBJDIR)/%.bundle:	getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore)
+$(OBJDIR)/%.bundle:	getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore) \
+					$(wildcard $(PLUGINSRCDIR)/$(*F)/*.c) \
+					$(wildcard $(PLATDIR)/Cross/plugins/$(*F)/*.*) \
+					$(wildcard $(OSXPLUGINSDIR)/$(*F)/*.*)
 	@-mkdir -p $(BLDDIR)/$(*F)
 	test $@ -ot $(call plugin-makefile,$(*F)) && rm -rf $(BUILD)/vm/$(*F).bundle || true
 	rm -f $(BUILD)/vm/$(*F).ignore

Modified: branches/Cog/build.macos64x64/common/Makefile.vm
===================================================================
--- branches/Cog/build.macos64x64/common/Makefile.vm	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/build.macos64x64/common/Makefile.vm	2016-02-22 19:11:27 UTC (rev 3627)
@@ -210,7 +210,10 @@
 # Internal plugin.  Build as lib then link in lib
 # Check for Makefile in iOS plugins directory otherwise use default Makefile
 # N.B.  PLATDIR *must* be a relative path for this to work
-$(OBJDIR)/%.lib: getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore)
+$(OBJDIR)/%.lib: getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore) \
+					$(wildcard $(PLUGINSRCDIR)/$(*F)/*.c) \
+					$(wildcard $(PLATDIR)/Cross/plugins/$(*F)/*.*) \
+					$(wildcard $(OSXPLUGINSDIR)/$(*F)/*.*)
 	@-mkdir -p $(BLDDIR)/$(*F)
 	test $@ -ot $(call plugin-makefile,$(*F)) && rm $(BUILD)/vm/$(*F).lib || true
 	rm -f $(BUILD)/vm/$(*F).ignore
@@ -228,7 +231,10 @@
 
 # External plugin.  Build as bundle and copy to vm dir ($(OBJDIR)).
 # Check for Makefile in iOS plugins directory otherwise use default Makefile
-$(OBJDIR)/%.bundle:	getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore)
+$(OBJDIR)/%.bundle:	getversion $(call plugin-makefile,$(*F)) $(wildcard $(*F).ignore) \
+					$(wildcard $(PLUGINSRCDIR)/$(*F)/*.c) \
+					$(wildcard $(PLATDIR)/Cross/plugins/$(*F)/*.*) \
+					$(wildcard $(OSXPLUGINSDIR)/$(*F)/*.*)
 	@-mkdir -p $(BLDDIR)/$(*F)
 	test $@ -ot $(call plugin-makefile,$(*F)) && rm -rf $(BUILD)/vm/$(*F).bundle || true
 	rm -f $(BUILD)/vm/$(*F).ignore


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Sat Feb 20 20:55:51 PST 2016
   + Mon Feb 22 11:10:17 PST 2016

Modified: branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c	2016-02-22 19:11:27 UTC (rev 3627)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	VMPluginCodeGenerator VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
    from
-	ThreadedARMFFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	ThreadedARMFFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
  */
-static char __buildInfo[] = "ThreadedARMFFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed " __DATE__ ;
+static char __buildInfo[] = "ThreadedARMFFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5 " __DATE__ ;
 
 
 
@@ -286,6 +286,7 @@
 static sqInt registerArgsSlop(void);
 static sqInt returnStructInRegisters(sqInt returnStructSize);
 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+static sqInt signedMachineIntegerFor(unsigned long value);
 static sqInt sizeField(sqInt oop);
 static sqInt startOfData(sqInt oop);
 
@@ -359,7 +360,6 @@
 static sqInt (*pushInteger)(sqInt integerValue);
 static sqInt (*pushRemappableOop)(sqInt oop);
 static sqInt (*signed32BitIntegerFor)(sqInt integerValue);
-static int (*signed32BitValueOf)(sqInt oop);
 static sqInt (*signed64BitIntegerFor)(sqLong integerValue);
 static sqLong (*signed64BitValueOf)(sqInt oop);
 static long (*signedMachineIntegerValueOf)(sqInt oop);
@@ -447,7 +447,6 @@
 extern sqInt pushInteger(sqInt integerValue);
 extern sqInt pushRemappableOop(sqInt oop);
 extern sqInt signed32BitIntegerFor(sqInt integerValue);
-extern int signed32BitValueOf(sqInt oop);
 extern sqInt signed64BitIntegerFor(sqLong integerValue);
 extern sqLong signed64BitValueOf(sqInt oop);
 extern long signedMachineIntegerValueOf(sqInt oop);
@@ -464,9 +463,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"ARM32FFIPlugin VMMaker.oscog-eem.1689 (i)"
+	"ARM32FFIPlugin VMMaker.oscog-eem.1692 (i)"
 #else
-	"ARM32FFIPlugin VMMaker.oscog-eem.1689 (e)"
+	"ARM32FFIPlugin VMMaker.oscog-eem.1692 (e)"
 #endif
 ;
 
@@ -509,11 +508,11 @@
 }
 
 
-/*	return an int of the address of the byteSize slot (byte, short, int,
-	whatever) at byteOffset in rcvr. Nominally intended for use with
-	ExternalAddress objects, this code will work (for obscure historical
-	reasons) with plain Byte or Word Arrays as well.
- */
+/*	Answer a long of the address of the byteSize slot (byte, short, int,
+	whatever) at byteOffset in rcvr.
+	Nominally intended for use with ExternalAddress objects, this code will
+	work (for obscure historical
+	reasons) with plain Byte or Word Arrays as well. */
 
 	/* ThreadedFFIPlugin>>#ffiAddressOf:startingAt:size: */
 static sqInt
@@ -523,7 +522,6 @@
     sqInt rcvrClass;
     sqInt rcvrSize;
 
-	flag("This needs more thought.  It is 32-bit specific.  What about 64-bit platforms?");
 	if (!(isBytes(rcvr))) {
 		return primitiveFail();
 	}
@@ -533,10 +531,11 @@
 	rcvrClass = fetchClassOf(rcvr);
 	rcvrSize = byteSizeOf(rcvr);
 	if (rcvrClass == (classExternalAddress())) {
-		if (!(rcvrSize == 4)) {
+		if (!(rcvrSize == BytesPerWord)) {
 			return primitiveFail();
 		}
 
+		/* Hack!! */
 		/* don't you dare to read from object memory (unless is pinned)! */
 		addr = fetchPointerofObject(0, rcvr);
 		if (addr == 0) {
@@ -549,7 +548,7 @@
 		if (!(((byteOffset + byteSize) - 1) <= rcvrSize)) {
 			return primitiveFail();
 		}
-		addr = ((int) (firstIndexableField(rcvr)));
+		addr = ((long) (firstIndexableField(rcvr)));
 	}
 	addr = (addr + byteOffset) - 1;
 	return addr;
@@ -1694,7 +1693,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 		}
@@ -1854,7 +1853,7 @@
 		}
 		return oop;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop = floatObjectOf(floatRet);
 	}
 	else {
@@ -2163,7 +2162,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 		}
@@ -2324,7 +2323,7 @@
 		result = oop3;
 		goto l7;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop3 = floatObjectOf(floatRet);
 	}
 	else {
@@ -4077,7 +4076,7 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			if (atomicType == FFITypeSingleFloat) {
 				floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 			}
@@ -4238,7 +4237,7 @@
 			result1 = oop3;
 			goto l13;
 		}
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			oop3 = floatObjectOf(floatRet);
 		}
 		else {
@@ -4503,7 +4502,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec2 = (calloutState1->ffiRetHeader);
 	atomicType2 = ((usqInt) (typeSpec2 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType2 == FFITypeSingleFloat) {
 			floatRet1 = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
 		}
@@ -4664,7 +4663,7 @@
 		result2 = oop4;
 		goto l16;
 	}
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop4 = floatObjectOf(floatRet1);
 	}
 	else {
@@ -5069,7 +5068,7 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			if (atomicType == FFITypeSingleFloat) {
 				floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 			}
@@ -5230,7 +5229,7 @@
 			result1 = oop3;
 			goto l13;
 		}
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			oop3 = floatObjectOf(floatRet);
 		}
 		else {
@@ -5501,7 +5500,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec2 = (calloutState1->ffiRetHeader);
 	atomicType2 = ((usqInt) (typeSpec2 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType2 == FFITypeSingleFloat) {
 			floatRet1 = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
 		}
@@ -5662,7 +5661,7 @@
 		result2 = oop4;
 		goto l16;
 	}
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop4 = floatObjectOf(floatRet1);
 	}
 	else {
@@ -5744,7 +5743,7 @@
     sqInt width;
 
 	if (!((methodArgumentCount()) == 5)) {
-		return primitiveFail();
+		return primitiveFailFor(PrimErrBadNumArgs);
 	}
 	width = stackIntegerValue(4);
 	height = stackIntegerValue(3);
@@ -5759,7 +5758,9 @@
 	if (result < 0) {
 		return primitiveFail();
 	}
-	result = signed32BitIntegerFor(result);
+	result = (BytesPerWord == 8
+		? signed64BitIntegerFor(result)
+		: signed32BitIntegerFor(result));
 	return popthenPush(6, result);
 }
 
@@ -5979,7 +5980,8 @@
 }
 
 
-/*	Return a (signed or unsigned) n byte integer from the given byte offset. */
+/*	Answer a (signed or unsigned) n byte integer from the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAt */
 EXPORT(sqInt)
@@ -5989,9 +5991,10 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt mask;
+    usqLong mask;
     sqInt rcvr;
-    sqInt value;
+    usqLong value;
+    sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
 	byteSize = stackIntegerValue(1);
@@ -6001,45 +6004,52 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
-
-		/* short/byte */
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
-			value = byteAt(addr);
+			value = ((unsigned char) (byteAt(addr)));
 		}
 		else {
-			value = *((unsigned short int *) addr);
+			value = ((unsigned short) (shortAt(addr)));
 		}
+	}
+	else {
+		if (byteSize == 4) {
+			value = ((unsigned int) (long32At(addr)));
+		}
+		else {
+			value = long64At(addr);
+		}
+	}
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 
 			/* sign extend value */
 			mask = 1 << ((byteSize * 8) - 1);
 			value = (value & (mask - 1)) - (value & mask);
 		}
-		value = integerObjectOf(value);
+		valueOop = integerObjectOf(value);
 	}
 	else {
 
-		/* general 32 bit integer */
-		value = longAt(addr);
-		value = (isSigned
-			? signed32BitIntegerFor(value)
-			: positive32BitIntegerFor(value));
+		/* general 64 bit integer; note these never fail */
+		valueOop = (isSigned
+			? signed64BitIntegerFor(value)
+			: positive64BitIntegerFor(value));
 	}
-	return popthenPush(4, value);
+	return popthenPush(4, valueOop);
 }
 
 
-/*	Store a (signed or unsigned) n byte integer at the given byte offset. */
+/*	Store a (signed or unsigned) n byte integer at the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAtPut */
 EXPORT(sqInt)
@@ -6049,9 +6059,9 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt max;
+    sqLong max;
     sqInt rcvr;
-    sqInt value;
+    sqLong value;
     sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
@@ -6063,9 +6073,8 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
@@ -6073,38 +6082,43 @@
 		return 0;
 	}
 	if (isSigned) {
-		value = signed32BitValueOf(valueOop);
+		value = signedMachineIntegerValueOf(valueOop);
 	}
 	else {
-		value = positive32BitValueOf(valueOop);
+		value = positiveMachineIntegerValueOf(valueOop);
 	}
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 			max = 1 << ((8 * byteSize) - 1);
-			if (value >= max) {
+			if (!((value >= (0 - max))
+				 && (value < max))) {
 				return primitiveFail();
 			}
-			if (value < (0 - max)) {
-				return primitiveFail();
-			}
 		}
 		else {
-			if (value >= (1 << (8 * byteSize))) {
+			if (!((((unsigned long long)value)) < (1 << (8 * byteSize)))) {
 				return primitiveFail();
 			}
 		}
+	}
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
 			byteAtput(addr, value);
 		}
 		else {
-			*((short int *) addr) = value;
+			shortAtput(addr, value);
 		}
 	}
 	else {
-		longAtput(addr, value);
+		if (byteSize == 4) {
+			long32Atput(addr, value);
+		}
+		else {
+			long64Atput(addr, value);
+		}
 	}
 	return popthenPush(5, valueOop);
 }
@@ -6379,7 +6393,6 @@
 		pushInteger = interpreterProxy->pushInteger;
 		pushRemappableOop = interpreterProxy->pushRemappableOop;
 		signed32BitIntegerFor = interpreterProxy->signed32BitIntegerFor;
-		signed32BitValueOf = interpreterProxy->signed32BitValueOf;
 		signed64BitIntegerFor = interpreterProxy->signed64BitIntegerFor;
 		signed64BitValueOf = interpreterProxy->signed64BitValueOf;
 		signedMachineIntegerValueOf = interpreterProxy->signedMachineIntegerValueOf;
@@ -6396,7 +6409,16 @@
 	return ok;
 }
 
+	/* InterpreterPlugin>>#signedMachineIntegerFor: */
+static sqInt
+signedMachineIntegerFor(unsigned long value)
+{
+	return (BytesPerWord == 8
+		? signed64BitIntegerFor(value)
+		: signed32BitIntegerFor(value));
+}
 
+
 /*	Answer the first field of oop which is assumed to be an Alien of at least
 	8 bytes
  */

Modified: branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c	2016-02-22 19:11:27 UTC (rev 3627)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	VMPluginCodeGenerator VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
    from
-	ThreadedIA32FFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	ThreadedIA32FFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
  */
-static char __buildInfo[] = "ThreadedIA32FFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed " __DATE__ ;
+static char __buildInfo[] = "ThreadedIA32FFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5 " __DATE__ ;
 
 
 
@@ -277,6 +277,7 @@
 EXPORT(sqInt) primitiveSetManualSurfacePointer(void);
 static sqInt registerArgsSlop(void);
 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+static sqInt signedMachineIntegerFor(unsigned long value);
 static sqInt sizeField(sqInt oop);
 static sqInt startOfData(sqInt oop);
 
@@ -350,7 +351,6 @@
 static sqInt (*pushInteger)(sqInt integerValue);
 static sqInt (*pushRemappableOop)(sqInt oop);
 static sqInt (*signed32BitIntegerFor)(sqInt integerValue);
-static int (*signed32BitValueOf)(sqInt oop);
 static sqInt (*signed64BitIntegerFor)(sqLong integerValue);
 static sqLong (*signed64BitValueOf)(sqInt oop);
 static long (*signedMachineIntegerValueOf)(sqInt oop);
@@ -438,7 +438,6 @@
 extern sqInt pushInteger(sqInt integerValue);
 extern sqInt pushRemappableOop(sqInt oop);
 extern sqInt signed32BitIntegerFor(sqInt integerValue);
-extern int signed32BitValueOf(sqInt oop);
 extern sqInt signed64BitIntegerFor(sqLong integerValue);
 extern sqLong signed64BitValueOf(sqInt oop);
 extern long signedMachineIntegerValueOf(sqInt oop);
@@ -455,9 +454,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"IA32FFIPlugin VMMaker.oscog-eem.1689 (i)"
+	"IA32FFIPlugin VMMaker.oscog-eem.1692 (i)"
 #else
-	"IA32FFIPlugin VMMaker.oscog-eem.1689 (e)"
+	"IA32FFIPlugin VMMaker.oscog-eem.1692 (e)"
 #endif
 ;
 
@@ -501,11 +500,11 @@
 }
 
 
-/*	return an int of the address of the byteSize slot (byte, short, int,
-	whatever) at byteOffset in rcvr. Nominally intended for use with
-	ExternalAddress objects, this code will work (for obscure historical
-	reasons) with plain Byte or Word Arrays as well.
- */
+/*	Answer a long of the address of the byteSize slot (byte, short, int,
+	whatever) at byteOffset in rcvr.
+	Nominally intended for use with ExternalAddress objects, this code will
+	work (for obscure historical
+	reasons) with plain Byte or Word Arrays as well. */
 
 	/* ThreadedFFIPlugin>>#ffiAddressOf:startingAt:size: */
 static sqInt
@@ -515,7 +514,6 @@
     sqInt rcvrClass;
     sqInt rcvrSize;
 
-	flag("This needs more thought.  It is 32-bit specific.  What about 64-bit platforms?");
 	if (!(isBytes(rcvr))) {
 		return primitiveFail();
 	}
@@ -525,10 +523,11 @@
 	rcvrClass = fetchClassOf(rcvr);
 	rcvrSize = byteSizeOf(rcvr);
 	if (rcvrClass == (classExternalAddress())) {
-		if (!(rcvrSize == 4)) {
+		if (!(rcvrSize == BytesPerWord)) {
 			return primitiveFail();
 		}
 
+		/* Hack!! */
 		/* don't you dare to read from object memory (unless is pinned)! */
 		addr = fetchPointerofObject(0, rcvr);
 		if (addr == 0) {
@@ -541,7 +540,7 @@
 		if (!(((byteOffset + byteSize) - 1) <= rcvrSize)) {
 			return primitiveFail();
 		}
-		addr = ((int) (firstIndexableField(rcvr)));
+		addr = ((long) (firstIndexableField(rcvr)));
 	}
 	addr = (addr + byteOffset) - 1;
 	return addr;
@@ -5236,7 +5235,7 @@
     sqInt width;
 
 	if (!((methodArgumentCount()) == 5)) {
-		return primitiveFail();
+		return primitiveFailFor(PrimErrBadNumArgs);
 	}
 	width = stackIntegerValue(4);
 	height = stackIntegerValue(3);
@@ -5251,7 +5250,9 @@
 	if (result < 0) {
 		return primitiveFail();
 	}
-	result = signed32BitIntegerFor(result);
+	result = (BytesPerWord == 8
+		? signed64BitIntegerFor(result)
+		: signed32BitIntegerFor(result));
 	return popthenPush(6, result);
 }
 
@@ -5471,7 +5472,8 @@
 }
 
 
-/*	Return a (signed or unsigned) n byte integer from the given byte offset. */
+/*	Answer a (signed or unsigned) n byte integer from the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAt */
 EXPORT(sqInt)
@@ -5481,9 +5483,10 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt mask;
+    usqLong mask;
     sqInt rcvr;
-    sqInt value;
+    usqLong value;
+    sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
 	byteSize = stackIntegerValue(1);
@@ -5493,45 +5496,52 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
-
-		/* short/byte */
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
-			value = byteAt(addr);
+			value = ((unsigned char) (byteAt(addr)));
 		}
 		else {
-			value = *((unsigned short int *) addr);
+			value = ((unsigned short) (shortAt(addr)));
 		}
+	}
+	else {
+		if (byteSize == 4) {
+			value = ((unsigned int) (long32At(addr)));
+		}
+		else {
+			value = long64At(addr);
+		}
+	}
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 
 			/* sign extend value */
 			mask = 1 << ((byteSize * 8) - 1);
 			value = (value & (mask - 1)) - (value & mask);
 		}
-		value = integerObjectOf(value);
+		valueOop = integerObjectOf(value);
 	}
 	else {
 
-		/* general 32 bit integer */
-		value = longAt(addr);
-		value = (isSigned
-			? signed32BitIntegerFor(value)
-			: positive32BitIntegerFor(value));
+		/* general 64 bit integer; note these never fail */
+		valueOop = (isSigned
+			? signed64BitIntegerFor(value)
+			: positive64BitIntegerFor(value));
 	}
-	return popthenPush(4, value);
+	return popthenPush(4, valueOop);
 }
 
 
-/*	Store a (signed or unsigned) n byte integer at the given byte offset. */
+/*	Store a (signed or unsigned) n byte integer at the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAtPut */
 EXPORT(sqInt)
@@ -5541,9 +5551,9 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt max;
+    sqLong max;
     sqInt rcvr;
-    sqInt value;
+    sqLong value;
     sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
@@ -5555,9 +5565,8 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
@@ -5565,38 +5574,43 @@
 		return 0;
 	}
 	if (isSigned) {
-		value = signed32BitValueOf(valueOop);
+		value = signedMachineIntegerValueOf(valueOop);
 	}
 	else {
-		value = positive32BitValueOf(valueOop);
+		value = positiveMachineIntegerValueOf(valueOop);
 	}
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 			max = 1 << ((8 * byteSize) - 1);
-			if (value >= max) {
+			if (!((value >= (0 - max))
+				 && (value < max))) {
 				return primitiveFail();
 			}
-			if (value < (0 - max)) {
-				return primitiveFail();
-			}
 		}
 		else {
-			if (value >= (1 << (8 * byteSize))) {
+			if (!((((unsigned long long)value)) < (1 << (8 * byteSize)))) {
 				return primitiveFail();
 			}
 		}
+	}
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
 			byteAtput(addr, value);
 		}
 		else {
-			*((short int *) addr) = value;
+			shortAtput(addr, value);
 		}
 	}
 	else {
-		longAtput(addr, value);
+		if (byteSize == 4) {
+			long32Atput(addr, value);
+		}
+		else {
+			long64Atput(addr, value);
+		}
 	}
 	return popthenPush(5, valueOop);
 }
@@ -5860,7 +5874,6 @@
 		pushInteger = interpreterProxy->pushInteger;
 		pushRemappableOop = interpreterProxy->pushRemappableOop;
 		signed32BitIntegerFor = interpreterProxy->signed32BitIntegerFor;
-		signed32BitValueOf = interpreterProxy->signed32BitValueOf;
 		signed64BitIntegerFor = interpreterProxy->signed64BitIntegerFor;
 		signed64BitValueOf = interpreterProxy->signed64BitValueOf;
 		signedMachineIntegerValueOf = interpreterProxy->signedMachineIntegerValueOf;
@@ -5877,7 +5890,16 @@
 	return ok;
 }
 
+	/* InterpreterPlugin>>#signedMachineIntegerFor: */
+static sqInt
+signedMachineIntegerFor(unsigned long value)
+{
+	return (BytesPerWord == 8
+		? signed64BitIntegerFor(value)
+		: signed32BitIntegerFor(value));
+}
 
+
 /*	Answer the first field of oop which is assumed to be an Alien of at least
 	8 bytes
  */

Modified: branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c	2016-02-22 19:11:27 UTC (rev 3627)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	VMPluginCodeGenerator VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
    from
-	ThreadedX64SysVFFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	ThreadedX64SysVFFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
  */
-static char __buildInfo[] = "ThreadedX64SysVFFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed " __DATE__ ;
+static char __buildInfo[] = "ThreadedX64SysVFFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5 " __DATE__ ;
 
 
 
@@ -294,6 +294,7 @@
 static sqInt registerArgsSlop(void);
 static sqInt returnStructInRegisters(sqInt returnStructSize);
 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+static sqInt signedMachineIntegerFor(unsigned long value);
 static sqInt sizeField(sqInt oop);
 static sqInt startOfData(sqInt oop);
 
@@ -367,7 +368,6 @@
 static sqInt (*pushInteger)(sqInt integerValue);
 static sqInt (*pushRemappableOop)(sqInt oop);
 static sqInt (*signed32BitIntegerFor)(sqInt integerValue);
-static int (*signed32BitValueOf)(sqInt oop);
 static sqInt (*signed64BitIntegerFor)(sqLong integerValue);
 static sqLong (*signed64BitValueOf)(sqInt oop);
 static long (*signedMachineIntegerValueOf)(sqInt oop);
@@ -455,7 +455,6 @@
 extern sqInt pushInteger(sqInt integerValue);
 extern sqInt pushRemappableOop(sqInt oop);
 extern sqInt signed32BitIntegerFor(sqInt integerValue);
-extern int signed32BitValueOf(sqInt oop);
 extern sqInt signed64BitIntegerFor(sqLong integerValue);
 extern sqLong signed64BitValueOf(sqInt oop);
 extern long signedMachineIntegerValueOf(sqInt oop);
@@ -472,9 +471,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"X64SysVFFIPlugin VMMaker.oscog-eem.1689 (i)"
+	"X64SysVFFIPlugin VMMaker.oscog-eem.1692 (i)"
 #else
-	"X64SysVFFIPlugin VMMaker.oscog-eem.1689 (e)"
+	"X64SysVFFIPlugin VMMaker.oscog-eem.1692 (e)"
 #endif
 ;
 
@@ -517,11 +516,11 @@
 }
 
 
-/*	return an int of the address of the byteSize slot (byte, short, int,
-	whatever) at byteOffset in rcvr. Nominally intended for use with
-	ExternalAddress objects, this code will work (for obscure historical
-	reasons) with plain Byte or Word Arrays as well.
- */
+/*	Answer a long of the address of the byteSize slot (byte, short, int,
+	whatever) at byteOffset in rcvr.
+	Nominally intended for use with ExternalAddress objects, this code will
+	work (for obscure historical
+	reasons) with plain Byte or Word Arrays as well. */
 
 	/* ThreadedFFIPlugin>>#ffiAddressOf:startingAt:size: */
 static sqInt
@@ -531,7 +530,6 @@
     sqInt rcvrClass;
     sqInt rcvrSize;
 
-	flag("This needs more thought.  It is 32-bit specific.  What about 64-bit platforms?");
 	if (!(isBytes(rcvr))) {
 		return primitiveFail();
 	}
@@ -541,10 +539,11 @@
 	rcvrClass = fetchClassOf(rcvr);
 	rcvrSize = byteSizeOf(rcvr);
 	if (rcvrClass == (classExternalAddress())) {
-		if (!(rcvrSize == 4)) {
+		if (!(rcvrSize == BytesPerWord)) {
 			return primitiveFail();
 		}
 
+		/* Hack!! */
 		/* don't you dare to read from object memory (unless is pinned)! */
 		addr = fetchPointerofObject(0, rcvr);
 		if (addr == 0) {
@@ -557,7 +556,7 @@
 		if (!(((byteOffset + byteSize) - 1) <= rcvrSize)) {
 			return primitiveFail();
 		}
-		addr = ((int) (firstIndexableField(rcvr)));
+		addr = ((long) (firstIndexableField(rcvr)));
 	}
 	addr = (addr + byteOffset) - 1;
 	return addr;
@@ -1851,7 +1850,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3], ((calloutState->integerRegisters))[4], ((calloutState->integerRegisters))[5]);
 		}
@@ -2013,7 +2012,7 @@
 		}
 		return oop;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop = floatObjectOf(floatRet);
 	}
 	else {
@@ -2324,7 +2323,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3], ((calloutState->integerRegisters))[4], ((calloutState->integerRegisters))[5]);
 		}
@@ -2487,7 +2486,7 @@
 		result = oop3;
 		goto l7;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop3 = floatObjectOf(floatRet);
 	}
 	else {
@@ -4471,7 +4470,7 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			if (atomicType == FFITypeSingleFloat) {
 				floatRet = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3], ((calloutState->integerRegisters))[4], ((calloutState->integerRegisters))[5]);
 			}
@@ -4634,7 +4633,7 @@
 			result1 = oop3;
 			goto l13;
 		}
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			oop3 = floatObjectOf(floatRet);
 		}
 		else {
@@ -4900,7 +4899,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec2 = (calloutState1->ffiRetHeader);
 	atomicType2 = ((usqInt) (typeSpec2 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType2 == FFITypeSingleFloat) {
 			floatRet1 = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3], ((calloutState1->integerRegisters))[4], ((calloutState1->integerRegisters))[5]);
 		}
@@ -5063,7 +5062,7 @@
 		result2 = oop4;
 		goto l16;
 	}
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop4 = floatObjectOf(floatRet1);
 	}
 	else {
@@ -5471,7 +5470,7 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			if (atomicType == FFITypeSingleFloat) {
 				floatRet = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3], ((calloutState->integerRegisters))[4], ((calloutState->integerRegisters))[5]);
 			}
@@ -5634,7 +5633,7 @@
 			result1 = oop3;
 			goto l13;
 		}
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			oop3 = floatObjectOf(floatRet);
 		}
 		else {
@@ -5906,7 +5905,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec2 = (calloutState1->ffiRetHeader);
 	atomicType2 = ((usqInt) (typeSpec2 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType2 == FFITypeSingleFloat) {
 			floatRet1 = dispatchFunctionPointerwithwithwithwithwithwith(((float (*)(long, long, long, long, long, long)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3], ((calloutState1->integerRegisters))[4], ((calloutState1->integerRegisters))[5]);
 		}
@@ -6069,7 +6068,7 @@
 		result2 = oop4;
 		goto l16;
 	}
-	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop4 = floatObjectOf(floatRet1);
 	}
 	else {
@@ -6152,7 +6151,7 @@
     sqInt width;
 
 	if (!((methodArgumentCount()) == 5)) {
-		return primitiveFail();
+		return primitiveFailFor(PrimErrBadNumArgs);
 	}
 	width = stackIntegerValue(4);
 	height = stackIntegerValue(3);
@@ -6167,7 +6166,9 @@
 	if (result < 0) {
 		return primitiveFail();
 	}
-	result = signed32BitIntegerFor(result);
+	result = (BytesPerWord == 8
+		? signed64BitIntegerFor(result)
+		: signed32BitIntegerFor(result));
 	return popthenPush(6, result);
 }
 
@@ -6387,7 +6388,8 @@
 }
 
 
-/*	Return a (signed or unsigned) n byte integer from the given byte offset. */
+/*	Answer a (signed or unsigned) n byte integer from the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAt */
 EXPORT(sqInt)
@@ -6397,9 +6399,10 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt mask;
+    usqLong mask;
     sqInt rcvr;
-    sqInt value;
+    usqLong value;
+    sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
 	byteSize = stackIntegerValue(1);
@@ -6409,45 +6412,52 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
-
-		/* short/byte */
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
-			value = byteAt(addr);
+			value = ((unsigned char) (byteAt(addr)));
 		}
 		else {
-			value = *((unsigned short int *) addr);
+			value = ((unsigned short) (shortAt(addr)));
 		}
+	}
+	else {
+		if (byteSize == 4) {
+			value = ((unsigned int) (long32At(addr)));
+		}
+		else {
+			value = long64At(addr);
+		}
+	}
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 
 			/* sign extend value */
 			mask = 1 << ((byteSize * 8) - 1);
 			value = (value & (mask - 1)) - (value & mask);
 		}
-		value = integerObjectOf(value);
+		valueOop = integerObjectOf(value);
 	}
 	else {
 
-		/* general 32 bit integer */
-		value = longAt(addr);
-		value = (isSigned
-			? signed32BitIntegerFor(value)
-			: positive32BitIntegerFor(value));
+		/* general 64 bit integer; note these never fail */
+		valueOop = (isSigned
+			? signed64BitIntegerFor(value)
+			: positive64BitIntegerFor(value));
 	}
-	return popthenPush(4, value);
+	return popthenPush(4, valueOop);
 }
 
 
-/*	Store a (signed or unsigned) n byte integer at the given byte offset. */
+/*	Store a (signed or unsigned) n byte integer at the given byte offset
+	in the receiver, using the platform's endianness. */
 
 	/* ThreadedFFIPlugin>>#primitiveFFIIntegerAtPut */
 EXPORT(sqInt)
@@ -6457,9 +6467,9 @@
     sqInt byteOffset;
     sqInt byteSize;
     sqInt isSigned;
-    sqInt max;
+    sqLong max;
     sqInt rcvr;
-    sqInt value;
+    sqLong value;
     sqInt valueOop;
 
 	isSigned = booleanValueOf(stackValue(0));
@@ -6471,9 +6481,8 @@
 		return 0;
 	}
 	if (!((byteOffset > 0)
-		 && ((byteSize == 1)
-		 || ((byteSize == 2)
-		 || (byteSize == 4))))) {
+		 && ((((byteSize >= 1) && (byteSize <= 8)))
+		 && ((byteSize & (byteSize - 1)) == 0)))) {
 		return primitiveFail();
 	}
 	addr = ffiAddressOfstartingAtsize(rcvr, byteOffset, byteSize);
@@ -6481,38 +6490,43 @@
 		return 0;
 	}
 	if (isSigned) {
-		value = signed32BitValueOf(valueOop);
+		value = signedMachineIntegerValueOf(valueOop);
 	}
 	else {
-		value = positive32BitValueOf(valueOop);
+		value = positiveMachineIntegerValueOf(valueOop);
 	}
 	if (failed()) {
 		return 0;
 	}
-	if (byteSize < 4) {
+	if (byteSize < BytesPerWord) {
 		if (isSigned) {
 			max = 1 << ((8 * byteSize) - 1);
-			if (value >= max) {
+			if (!((value >= (0 - max))
+				 && (value < max))) {
 				return primitiveFail();
 			}
-			if (value < (0 - max)) {
-				return primitiveFail();
-			}
 		}
 		else {
-			if (value >= (1 << (8 * byteSize))) {
+			if (!((((unsigned long long)value)) < (1 << (8 * byteSize)))) {
 				return primitiveFail();
 			}
 		}
+	}
+	if (byteSize <= 2) {
 		if (byteSize == 1) {
 			byteAtput(addr, value);
 		}
 		else {
-			*((short int *) addr) = value;
+			shortAtput(addr, value);
 		}
 	}
 	else {
-		longAtput(addr, value);
+		if (byteSize == 4) {
+			long32Atput(addr, value);
+		}
+		else {
+			long64Atput(addr, value);
+		}
 	}
 	return popthenPush(5, valueOop);
 }
@@ -6787,7 +6801,6 @@
 		pushInteger = interpreterProxy->pushInteger;
 		pushRemappableOop = interpreterProxy->pushRemappableOop;
 		signed32BitIntegerFor = interpreterProxy->signed32BitIntegerFor;
-		signed32BitValueOf = interpreterProxy->signed32BitValueOf;
 		signed64BitIntegerFor = interpreterProxy->signed64BitIntegerFor;
 		signed64BitValueOf = interpreterProxy->signed64BitValueOf;
 		signedMachineIntegerValueOf = interpreterProxy->signedMachineIntegerValueOf;
@@ -6804,7 +6817,16 @@
 	return ok;
 }
 
+	/* InterpreterPlugin>>#signedMachineIntegerFor: */
+static sqInt
+signedMachineIntegerFor(unsigned long value)
+{
+	return (BytesPerWord == 8
+		? signed64BitIntegerFor(value)
+		: signed32BitIntegerFor(value));
+}
 
+
 /*	Answer the first field of oop which is assumed to be an Alien of at least
 	8 bytes
  */

Modified: branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c	2016-02-22 18:51:24 UTC (rev 3626)
+++ branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c	2016-02-22 19:11:27 UTC (rev 3627)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	VMPluginCodeGenerator VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
    from
-	ThreadedX64Win64FFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed
+	ThreadedX64Win64FFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5
  */
-static char __buildInfo[] = "ThreadedX64Win64FFIPlugin VMMaker.oscog-eem.1689 uuid: 4c473a09-7e78-4c59-b779-f2ad17e318ed " __DATE__ ;
+static char __buildInfo[] = "ThreadedX64Win64FFIPlugin VMMaker.oscog-eem.1692 uuid: 57b2f552-72d3-4db7-99d8-ef9872eb93f5 " __DATE__ ;
 
 
 
@@ -286,6 +286,7 @@
 static sqInt registerArgsSlop(void);
 static sqInt returnStructInRegisters(sqInt returnStructSize);
 EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
+static sqInt signedMachineIntegerFor(unsigned long value);
 static sqInt sizeField(sqInt oop);
 static sqInt startOfData(sqInt oop);
 
@@ -359,7 +360,6 @@
 static sqInt (*pushInteger)(sqInt integerValue);
 static sqInt (*pushRemappableOop)(sqInt oop);
 static sqInt (*signed32BitIntegerFor)(sqInt integerValue);
-static int (*signed32BitValueOf)(sqInt oop);
 static sqInt (*signed64BitIntegerFor)(sqLong integerValue);
 static sqLong (*signed64BitValueOf)(sqInt oop);
 static long (*signedMachineIntegerValueOf)(sqInt oop);
@@ -447,7 +447,6 @@
 extern sqInt pushInteger(sqInt integerValue);
 extern sqInt pushRemappableOop(sqInt oop);
 extern sqInt signed32BitIntegerFor(sqInt integerValue);
-extern int signed32BitValueOf(sqInt oop);
 extern sqInt signed64BitIntegerFor(sqLong integerValue);
 extern sqLong signed64BitValueOf(sqInt oop);
 extern long signedMachineIntegerValueOf(sqInt oop);
@@ -464,9 +463,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"X64Win64FFIPlugin VMMaker.oscog-eem.1689 (i)"
+	"X64Win64FFIPlugin VMMaker.oscog-eem.1692 (i)"
 #else
-	"X64Win64FFIPlugin VMMaker.oscog-eem.1689 (e)"
+	"X64Win64FFIPlugin VMMaker.oscog-eem.1692 (e)"
 #endif
 ;
 
@@ -509,11 +508,11 @@
 }
 
 
-/*	return an int of the address of the byteSize slot (byte, short, int,
-	whatever) at byteOffset in rcvr. Nominally intended for use with
-	ExternalAddress objects, this code will work (for obscure historical
-	reasons) with plain Byte or Word Arrays as well.
- */
+/*	Answer a long of the address of the byteSize slot (byte, short, int,
+	whatever) at byteOffset in rcvr.
+	Nominally intended for use with ExternalAddress objects, this code will
+	work (for obscure historical
+	reasons) with plain Byte or Word Arrays as well. */
 
 	/* ThreadedFFIPlugin>>#ffiAddressOf:startingAt:size: */
 static sqInt
@@ -523,7 +522,6 @@
     sqInt rcvrClass;
     sqInt rcvrSize;
 
-	flag("This needs more thought.  It is 32-bit specific.  What about 64-bit platforms?");
 	if (!(isBytes(rcvr))) {
 		return primitiveFail();
 	}
@@ -533,10 +531,11 @@
 	rcvrClass = fetchClassOf(rcvr);
 	rcvrSize = byteSizeOf(rcvr);
 	if (rcvrClass == (classExternalAddress())) {
-		if (!(rcvrSize == 4)) {
+		if (!(rcvrSize == BytesPerWord)) {
 			return primitiveFail();
 		}
 
+		/* Hack!! */
 		/* don't you dare to read from object memory (unless is pinned)! */
 		addr = fetchPointerofObject(0, rcvr);
 		if (addr == 0) {
@@ -549,7 +548,7 @@
 		if (!(((byteOffset + byteSize) - 1) <= rcvrSize)) {
 			return primitiveFail();
 		}
-		addr = ((int) (firstIndexableField(rcvr)));
+		addr = ((long) (firstIndexableField(rcvr)));
 	}
 	addr = (addr + byteOffset) - 1;
 	return addr;
@@ -1666,7 +1665,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 		}
@@ -1826,7 +1825,7 @@
 		}
 		return oop;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop = floatObjectOf(floatRet);
 	}
 	else {
@@ -2135,7 +2134,7 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		if (atomicType == FFITypeSingleFloat) {
 			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(long, long, long, long)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 		}
@@ -2296,7 +2295,7 @@
 		result = oop3;
 		goto l7;
 	}
-	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+	if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 		oop3 = floatObjectOf(floatRet);
 	}
 	else {
@@ -4012,7 +4011,7 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSingleFloat) >> 1)) {
 			if (atomicType == FFITypeSingleFloat) {

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list