Author: Lars Wassermann <lars.wasserm...@gmail.com> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit