Author: Lars Wassermann <[email protected]>
Branch:
Changeset: r435:9471f0ad6d08
Date: 2013-06-03 11:33 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/9471f0ad6d08/
Log: changed wrapping mechanism of interpreterProxy functions(ipfs):
signature is now given from (int, float, oop, ...) and
unwrapping/wrapping/default return values are now supplied by the
wrapping method failure state is set by the wrapper, not
each function added list of all missing ipfs
diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -8,6 +8,8 @@
# plugin setInterpreter: proxy.
# (plugin respondsTo: #initialiseModule) ifTrue:[plugin initialiseModule].
# plugin perform: primitiveName asSymbol.
+import inspect
+
from rpython.rlib.entrypoint import entrypoint
from rpython.rtyper.annlowlevel import llhelper
from rpython.rlib.exports import export_struct
@@ -20,49 +22,92 @@
sqInt = rffi.INT
sqLong = rffi.LONG
sqDouble = rffi.DOUBLE
-sqIntArray = rffi.CArray(sqInt)
+sqIntArrayPtr = Ptr(rffi.CArray(sqInt))
major = minor = 0
functions = []
-def expose_on_virtual_machine_proxy(signature, minor=0, major=1):
- f_ptr = Ptr(signature)
+oop = object()
+
+class ProxyFunctionFailed(error.PrimitiveFailedError):
+ pass
+
+def expose_on_virtual_machine_proxy(unwrap_spec, result_type, minor=0,
major=1):
+ mapping = {oop: sqInt, int: sqInt, list: sqIntArrayPtr, bool: sqInt,
float: sqDouble}
+ f_ptr = Ptr(FuncType([mapping[spec] for spec in unwrap_spec],
mapping[result_type]))
if minor < minor:
minor = minor
if major < major:
major = major
def decorator(func):
- functions.append(("c_" + func.func_name, f_ptr, func))
- return func
+ len_unwrap_spec = len(unwrap_spec)
+ assert (len_unwrap_spec == len(inspect.getargspec(func)[0]) + 1,
+ "wrong number of arguments")
+ unrolling_unwrap_spec = unrolling_iterable(enumerate(unwrap_spec))
+ def wrapped(*c_arguments):
+ assert len_unwrap_spec == len(c_arguments)
+ args = ()
+ try:
+ for i, spec in unrolling_unwrap_spec:
+ c_arg = c_arguments[i]
+ if spec is oop:
+ args += (IProxy.oop_to_object(c_arg), )
+ else:
+ args += (c_arg, )
+ result = func(*args)
+ if result_type is oop:
+ assert isinstance(result, model.W_Object)
+ return IProxy.object_to_oop(result)
+ elif result_type is list:
+ assert isinstance(result, list)
+ return IProxy.list_to_carray(result)
+ elif result_type in (int, float, bool):
+ assert isinstance(result, result_type)
+ return result
+ else:
+ return result
+ except error.PrimitiveFailedError:
+ IProxy.success_flag = False
+ if mapping[result_type] is sqInt:
+ return 0
+ elif mapping[result_type] is sqDouble:
+ return 0.0
+ elif mapping[result_type] is sqIntArrayPtr:
+ return rffi.cast(sqIntArrayPtr, 0)
+ else:
+ raise NotImplementedError(
+ "InterpreterProxy: unknown result_type %s" %
(result_type, ))
+ functions.append(("c_" + func.func_name, f_ptr, wrapped))
+ return wrapped
return decorator
-@expose_on_virtual_machine_proxy(FuncType([], sqInt))
+@expose_on_virtual_machine_proxy([], int)
def minorVersion():
return minor
-@expose_on_virtual_machine_proxy(FuncType([], sqInt))
+@expose_on_virtual_machine_proxy([], int)
def majorVersion():
return major
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([int], int)
def pop(nItems):
IProxy.s_frame.pop_n(nItems)
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqInt, sqInt], sqInt))
-def popthenPush(nItems, oop):
+@expose_on_virtual_machine_proxy([int, oop], int)
+def popthenPush(nItems, w_object):
s_frame = IProxy.s_frame
s_frame.pop_n(nItems)
- s_frame.push(IProxy.oop_to_object(oop))
+ s_frame.push(w_object)
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
-def push(oop):
+@expose_on_virtual_machine_proxy([oop], int)
+def push(w_object):
s_frame = IProxy.s_frame
- s_frame.push(IProxy.oop_to_object(oop))
+ s_frame.push(w_object)
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([bool], int)
def pushBool(trueOrFalse):
s_frame = IProxy.s_frame
if trueOrFalse:
@@ -71,71 +116,60 @@
s_frame.push(IProxy.interp.space.w_false)
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqDouble], sqInt))
+@expose_on_virtual_machine_proxy([float], int)
def pushFloat(f):
s_frame = IProxy.s_frame
s_frame.push(IProxy.space.wrap_float(f))
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([int], int)
def pushInteger(n):
s_frame = IProxy.s_frame
s_frame.push(IProxy.space.wrap_int(n))
return 0
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqDouble))
+@expose_on_virtual_machine_proxy([int], float)
def stackFloatValue(offset):
s_frame = IProxy.s_frame
f = s_frame.peek(offset)
if isinstance(f, model.W_Float):
return f.value
else:
- IProxy.successFlag = False
- return 0.0
+ raise ProxyFunctionFailed
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([int], int)
def stackIntegerValue(offset):
s_frame = IProxy.s_frame
n = s_frame.peek(offset)
- try:
- return IProxy.space.unwrap_int(n)
- except error.PrimitiveFailedError:
- IProxy.successFlag = False
- return 0
+ return IProxy.space.unwrap_int(n)
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([int], oop)
def stackObjectValue(offset):
s_frame = IProxy.s_frame
w_object = s_frame.peek(offset)
if not isinstance(w_object, model.W_SmallInteger):
- return IProxy.object_to_oop(w_object)
- IProxy.successFlag = False
- return 0
+ return w_object
+ raise ProxyFunctionFailed
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
+@expose_on_virtual_machine_proxy([int], oop)
def stackValue(offset):
s_frame = IProxy.s_frame
- return IProxy.object_to_oop(s_frame.peek(offset))
+ return s_frame.peek(offset)
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
-def argumentCountOf(methodOOP):
- w_method = IProxy.oop_to_object(methodOOP)
+@expose_on_virtual_machine_proxy([oop], int)
+def argumentCountOf(w_method):
if isinstance(w_method, model.W_CompiledMethod):
return w_method.argsize
- IProxy.successFlag = False
- return 0
+ raise ProxyFunctionFailed
-@expose_on_virtual_machine_proxy(FuncType([sqInt], Ptr(sqIntArray)))
-def arrayValueOf(oop):
- w_array = IProxy.oop_to_object(oop)
- if isinstance(w_array, model.W_WordsObject) or isinstance(w_array,
model.W_BytesObject):
+@expose_on_virtual_machine_proxy([oop], list)
+def arrayValueOf(w_array):
+ if w_array.is_array_object():
raise NotImplementedError
- IProxy.successFlag = False
- return rffi.cast(Ptr(sqIntArray), 0)
+ raise ProxyFunctionFailed
-@expose_on_virtual_machine_proxy(FuncType([sqInt], sqInt))
-def byteSizeOf(oop):
- w_object = IProxy.oop_to_object(oop)
+@expose_on_virtual_machine_proxy([oop], int)
+def byteSizeOf(w_object):
s_class = w_object.shadow_of_my_class(IProxy.space)
size = s_class.instsize()
if s_class.isvariable():
@@ -144,6 +178,263 @@
size *= 4
return size
+@expose_on_virtual_machine_proxy([int, oop], list)
+def fetchArrayofObject(fieldIndex, w_object):
+ # arrayOop := self fetchPointer: fieldIndex ofObject: objectPointer.
+ # ^ self arrayValueOf: arrayOop
+ w_array = w_object.fetch(IProxy.space, fieldIndex)
+ if w_array.is_array_object():
+ raise NotImplementedError
+ raise ProxyFunctionFailed
+
+@expose_on_virtual_machine_proxy([oop], oop)
+def fetchClassOf(w_object):
+ w_class = w_object.getclass(IProxy.space)
+ return w_class
+# sqInt (*fetchClassOf)(sqInt oop);
+# double (*fetchFloatofObject)(sqInt fieldIndex, sqInt objectPointer);
+# sqInt (*fetchIntegerofObject)(sqInt fieldIndex, sqInt objectPointer);
+# sqInt (*fetchPointerofObject)(sqInt fieldIndex, sqInt oop);
+# sqInt (*obsoleteDontUseThisFetchWordofObject)(sqInt fieldFieldIndex,
sqInt oop);
+# void *(*firstFixedField)(sqInt oop);
+# void *(*firstIndexableField)(sqInt oop);
+# sqInt (*literalofMethod)(sqInt offset, sqInt methodPointer);
+# sqInt (*literalCountOf)(sqInt methodPointer);
+# sqInt (*methodArgumentCount)(void);
+# sqInt (*methodPrimitiveIndex)(void);
+# sqInt (*primitiveIndexOf)(sqInt methodPointer);
+# sqInt (*sizeOfSTArrayFromCPrimitive)(void *cPtr);
+# sqInt (*slotSizeOf)(sqInt oop);
+# sqInt (*stObjectat)(sqInt array, sqInt fieldIndex);
+# sqInt (*stObjectatput)(sqInt array, sqInt fieldIndex, sqInt value);
+# sqInt (*stSizeOf)(sqInt oop);
+# sqInt (*storeIntegerofObjectwithValue)(sqInt fieldIndex, sqInt oop,
sqInt integer);
+# sqInt (*storePointerofObjectwithValue)(sqInt fieldIndex, sqInt oop,
sqInt valuePointer);
+
+# /* InterpreterProxy methodsFor: 'testing' */
+
+# sqInt (*isKindOf)(sqInt oop, char *aString);
+# sqInt (*isMemberOf)(sqInt oop, char *aString);
+# sqInt (*isBytes)(sqInt oop);
+# sqInt (*isFloatObject)(sqInt oop);
+# sqInt (*isIndexable)(sqInt oop);
+# sqInt (*isIntegerObject)(sqInt objectPointer);
+# sqInt (*isIntegerValue)(sqInt intValue);
+# sqInt (*isPointers)(sqInt oop);
+# sqInt (*isWeak)(sqInt oop);
+# sqInt (*isWords)(sqInt oop);
+# sqInt (*isWordsOrBytes)(sqInt oop);
+
+# /* InterpreterProxy methodsFor: 'converting' */
+
+# sqInt (*booleanValueOf)(sqInt obj);
+# sqInt (*checkedIntegerValueOf)(sqInt intOop);
+# sqInt (*floatObjectOf)(double aFloat);
+# double (*floatValueOf)(sqInt oop);
+# sqInt (*integerObjectOf)(sqInt value);
+# sqInt (*integerValueOf)(sqInt oop);
+# sqInt (*positive32BitIntegerFor)(sqInt integerValue);
+# sqInt (*positive32BitValueOf)(sqInt oop);
+
+# /* InterpreterProxy methodsFor: 'special objects' */
+
+# sqInt (*characterTable)(void);
+# sqInt (*displayObject)(void);
+# sqInt (*falseObject)(void);
+# sqInt (*nilObject)(void);
+# sqInt (*trueObject)(void);
+
+# /* InterpreterProxy methodsFor: 'special classes' */
+
+# sqInt (*classArray)(void);
+# sqInt (*classBitmap)(void);
+# sqInt (*classByteArray)(void);
+# sqInt (*classCharacter)(void);
+# sqInt (*classFloat)(void);
+# sqInt (*classLargePositiveInteger)(void);
+# sqInt (*classPoint)(void);
+# sqInt (*classSemaphore)(void);
+# sqInt (*classSmallInteger)(void);
+# sqInt (*classString)(void);
+
+# /* InterpreterProxy methodsFor: 'instance creation' */
+
+# sqInt (*clone)(sqInt oop);
+# sqInt (*instantiateClassindexableSize)(sqInt classPointer, sqInt size);
+# sqInt (*makePointwithxValueyValue)(sqInt xValue, sqInt yValue);
+# sqInt (*popRemappableOop)(void);
+# sqInt (*pushRemappableOop)(sqInt oop);
+
+# /* InterpreterProxy methodsFor: 'other' */
+
+# sqInt (*becomewith)(sqInt array1, sqInt array2);
+# sqInt (*byteSwapped)(sqInt w);
+# sqInt (*failed)(void);
+# sqInt (*fullDisplayUpdate)(void);
+# sqInt (*fullGC)(void);
+# sqInt (*incrementalGC)(void);
+# sqInt (*primitiveFail)(void);
+# sqInt (*showDisplayBitsLeftTopRightBottom)(sqInt aForm, sqInt l, sqInt
t, sqInt r, sqInt b);
+# sqInt (*signalSemaphoreWithIndex)(sqInt semaIndex);
+# sqInt (*success)(sqInt aBoolean);
+# sqInt (*superclassOf)(sqInt classPointer);
+
+# /* InterpreterProxy methodsFor: 'compiler' */
+
+# CompilerHook *(*compilerHookVector)(void);
+# sqInt (*setCompilerInitialized)(sqInt initFlag);
+
+# #if VM_PROXY_MINOR > 1
+
+# /* InterpreterProxy methodsFor: 'BitBlt support' */
+
+# sqInt (*loadBitBltFrom)(sqInt bbOop);
+# sqInt (*copyBits)(void);
+# sqInt (*copyBitsFromtoat)(sqInt leftX, sqInt rightX, sqInt yValue);
+
+# #endif
+
+# #if VM_PROXY_MINOR > 2
+
+# sqInt (*classLargeNegativeInteger)(void);
+# sqInt (*signed32BitIntegerFor)(sqInt integerValue);
+# sqInt (*signed32BitValueOf)(sqInt oop);
+# sqInt (*includesBehaviorThatOf)(sqInt aClass, sqInt aSuperClass);
+# sqInt (*primitiveMethod)(void);
+
+# /* InterpreterProxy methodsFor: 'FFI support' */
+
+# sqInt (*classExternalAddress)(void);
+# sqInt (*classExternalData)(void);
+# sqInt (*classExternalFunction)(void);
+# sqInt (*classExternalLibrary)(void);
+# sqInt (*classExternalStructure)(void);
+# sqInt (*ioLoadModuleOfLength)(sqInt modIndex, sqInt modLength);
+# sqInt (*ioLoadSymbolOfLengthFromModule)(sqInt fnIndex, sqInt fnLength,
sqInt handle);
+# sqInt (*isInMemory)(sqInt address);
+
+# #endif
+
+# #if VM_PROXY_MINOR > 3
+
+# void *(*ioLoadFunctionFrom)(char *fnName, char *modName);
+# sqInt (*ioMicroMSecs)(void);
+
+# #endif
+
+# #if VM_PROXY_MINOR > 4
+
+# # if !defined(sqLong)
+# # if _MSC_VER
+# # define sqLong __int64
+# # define usqLong unsigned __int64
+# # else
+# # define sqLong long long
+# # define usqLong unsigned long long
+# # endif
+# # endif
+
+# sqInt (*positive64BitIntegerFor)(sqLong integerValue);
+# sqLong (*positive64BitValueOf)(sqInt oop);
+# sqInt (*signed64BitIntegerFor)(sqLong integerValue);
+# sqLong (*signed64BitValueOf)(sqInt oop);
+
+# #endif
+
+# #if VM_PROXY_MINOR > 5
+# sqInt (*isArray)(sqInt oop);
+# sqInt (*forceInterruptCheck)(void);
+# #endif
+
+# #if VM_PROXY_MINOR > 6
+# sqInt (*fetchLong32ofObject)(sqInt fieldFieldIndex, sqInt oop);
+# sqInt (*getThisSessionID)(void);
+# sqInt (*ioFilenamefromStringofLengthresolveAliases)(char*
aCharBuffer, char* filenameIndex, sqInt filenameLength, sqInt resolveFlag);
+# sqInt (*vmEndianness)(void);
+# #endif
+
+# #if VM_PROXY_MINOR > 7
+# /* New methods for proxy version 1.8 */
+
+# /* callbackEnter: Re-enter the interpreter loop for a callback.
+# Arguments:
+# callbackID: Pointer to a location receiving the callback ID
+# used in callbackLeave
+# Returns: True if successful, false otherwise */
+# sqInt (*callbackEnter)(sqInt *callbackID);
+
+# /* callbackLeave: Leave the interpreter from a previous callback
+# Arguments:
+# callbackID: The ID of the callback received from callbackEnter()
+# Returns: True if succcessful, false otherwise. */
+# sqInt (*callbackLeave)(sqInt callbackID);
+
+# /* addGCRoot: Add a variable location to the garbage collector.
+# The contents of the variable location will be updated accordingly.
+# Arguments:
+# varLoc: Pointer to the variable location
+# Returns: True if successful, false otherwise. */
+# sqInt (*addGCRoot)(sqInt *varLoc);
+
+# /* removeGCRoot: Remove a variable location from the garbage collector.
+# Arguments:
+# varLoc: Pointer to the variable location
+# Returns: True if successful, false otherwise.
+# */
+# sqInt (*removeGCRoot)(sqInt *varLoc);
+# #endif
+
+# #if VM_PROXY_MINOR > 8
+# /* See interp.h and above for standard error codes. */
+# sqInt (*primitiveFailFor)(sqInt code);
+# void (*(*setInterruptCheckChain)(void (*aFunction)(void)))();
+# sqInt (*classAlien)(void);
+# sqInt (*classUnsafeAlien)(void);
+# sqInt (*sendInvokeCallbackStackRegistersJmpbuf)(sqInt thunkPtrAsInt,
sqInt stackPtrAsInt, sqInt regsPtrAsInt, sqInt jmpBufPtrAsInt);
+# sqInt (*reestablishContextPriorToCallback)(sqInt callbackContext);
+# sqInt *(*getStackPointer)(void);
+# sqInt (*isOopImmutable)(sqInt oop);
+# sqInt (*isOopMutable)(sqInt oop);
+# #endif
+
+# #if VM_PROXY_MINOR > 9
+# sqInt (*methodArg) (sqInt index);
+# sqInt (*objectArg) (sqInt index);
+# sqInt (*integerArg) (sqInt index);
+# double (*floatArg) (sqInt index);
+# sqInt (*methodReturnValue) (sqInt oop);
+# sqInt (*topRemappableOop) (void);
+# #endif
+
+# #if VM_PROXY_MINOR > 10
+# # define DisownVMLockOutFullGC 1
+# sqInt (*disownVM)(sqInt flags);
+# sqInt (*ownVM) (sqInt threadIdAndFlags);
+# void (*addHighPriorityTickee)(void (*ticker)(void), unsigned periodms);
+# void (*addSynchronousTickee)(void (*ticker)(void), unsigned periodms,
unsigned roundms);
+# usqLong (*utcMicroseconds)(void);
+# sqInt (*tenuringIncrementalGC)(void);
+# sqInt (*isYoung) (sqInt anOop);
+# sqInt (*isKindOfClass)(sqInt oop, sqInt aClass);
+# sqInt (*primitiveErrorTable)(void);
+# sqInt (*primitiveFailureCode)(void);
+# sqInt (*instanceSizeOf)(sqInt aClass);
+# #endif
+
+# #if VM_PROXY_MINOR > 11
+# /* VMCallbackContext opaque type avoids all including setjmp.h &
vmCallback.h */
+# sqInt (*sendInvokeCallbackContext)(vmccp);
+# sqInt (*returnAsThroughCallbackContext)(int, vmccp, sqInt);
+# long (*signedMachineIntegerValueOf)(sqInt);
+# long (*stackSignedMachineIntegerValue)(sqInt);
+# unsigned long (*positiveMachineIntegerValueOf)(sqInt);
+# unsigned long (*stackPositiveMachineIntegerValue)(sqInt);
+# sqInt (*getInterruptPending)(void);
+# char *(*cStringOrNullFor)(sqInt);
+# void *(*startOfAlienData)(sqInt);
+# usqInt (*sizeOfAlienData)(sqInt);
+# sqInt (*signalNoResume)(sqInt);
+# #endif
#
##############################################################################
@@ -179,7 +470,7 @@
self.s_frame = None
self.argcount = 0
self.s_method = None
- self.successFlag = True
+ self.success_flag = True
def call(self, signature, interp, s_frame, argcount, s_method):
self.interp = interp
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -139,6 +139,9 @@
from spyvm.fieldtypes import obj
return obj
+ def is_array_object(self):
+ return False
+
class W_SmallInteger(W_Object):
"""Boxed integer value"""
# TODO can we tell pypy that its never larger then 31-bit?
@@ -319,6 +322,9 @@
from spyvm.fieldtypes import LPI
return LPI
+ def is_array_object(self):
+ return True
+
class W_Float(W_AbstractObjectWithIdentityHash):
"""Boxed float value."""
_attrs_ = ['value']
@@ -789,6 +795,9 @@
word += r_uint(ord(self.getchar(i))) << 8*i
return word
+ def is_array_object(self):
+ return True
+
class W_WordsObject(W_AbstractObjectWithClassReference):
_attrs_ = ['words']
@@ -856,6 +865,9 @@
return W_AbstractObjectWithClassReference.as_embellished_string(self,
className='W_WordsObject', additionalInformation=('len=%d' %
self.size()))
+ def is_array_object(self):
+ return True
+
NATIVE_DEPTH = 32
class W_DisplayBitmap(W_AbstractObjectWithClassReference):
@@ -911,6 +923,8 @@
def setword(self, n, word):
raise NotImplementedError("subclass responsibility")
+ def is_array_object(self):
+ return True
class W_DisplayBitmap1Bit(W_DisplayBitmap):
def getword(self, n):
@@ -1162,6 +1176,9 @@
def has_shadow(self):
return self._shadow is not None
+ def is_array_object(self):
+ return True
+
class DetachingShadowError(Exception):
def __init__(self, old_shadow, new_shadow_class):
self.old_shadow = old_shadow
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit