-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generically allow primitives to return an error code #130
Comments
Basically, when a primitive fails there might be a "storeIntoTemp" bytecode directly after the primitive call, this will store an error code into the temp. We need to find a way to pass this error code into the method activation (or refactor how our primitive fails) |
Let's get this done next week, so we can start providing error codes in primfail errors... |
It is possible to expose an error code via a primitive pragma, e.g. |
Well, |
But |
See Smalltalk specialObjectsArray at: 52 and this from an old VMMaker: ObjectMemory>>initializePrimitiveErrorCodes
"Define the VM's primitive error codes. N.B. these are
replicated in platforms/Cross/vm/sqVirtualMachine.h."
"ObjectMemory initializePrimitiveErrorCodes"
| pet |
PrimErrTableIndex := 51. "Zero-relative"
"See SmalltalkImage>>recreateSpecialObjectsArray for the table definition.
If the table exists and is large enough the corresponding entry is returned as
the primitive error, otherwise the error is answered numerically."
pet := Smalltalk specialObjectsArray at: PrimErrTableIndex + 1 ifAbsent: [#()].
pet isArray ifFalse: [pet := #()].
PrimNoErr := 0. "for helper methods that need to answer success or an error code."
PrimErrGenericFailure := pet indexOf: nil ifAbsent: 1.
PrimErrBadReceiver := pet indexOf: #'bad receiver' ifAbsent: 2.
PrimErrBadArgument := pet indexOf: #'bad argument' ifAbsent: 3.
PrimErrBadIndex := pet indexOf: #'bad index' ifAbsent: 4.
PrimErrBadNumArgs := pet indexOf: #'bad number of arguments' ifAbsent: 5.
PrimErrInappropriate := pet indexOf: #'inappropriate operation' ifAbsent: 6.
PrimErrUnsupported := pet indexOf: #'unsupported operation' ifAbsent: 7.
PrimErrNoModification := pet indexOf: #'no modification' ifAbsent: 8.
PrimErrNoMemory := pet indexOf: #'insufficient object memory' ifAbsent: 9.
PrimErrNoCMemory := pet indexOf: #'insufficient C memory' ifAbsent: 10.
PrimErrNotFound := pet indexOf: #'not found' ifAbsent: 11.
PrimErrBadMethod := pet indexOf: #'bad method' ifAbsent: 12.
PrimErrNamedInternal := pet indexOf: #'internal error in named primitive machinery' ifAbsent: 13.
PrimErrObjectMayMove := pet indexOf: #'object may move' ifAbsent: 14.
PrimErrLimitExceeded := pet indexOf: #'resource limit exceeded' ifAbsent: 15 |
Also all senders of
|
Here's how StackInterpreter/Cog do it: StackInterpreter>>justActivateNewMethod
"..."
"Pass primitive error code to last temp if method receives it (indicated by an
initial long store temp bytecode). We don't need to check that newMethod
actually has a primitive because the initial 129 only occurs if there is one."
primFailCode ~= 0 ifTrue:
[(objectMemory byteAtPointer: instructionPointer + 1) = 129 "long store temp" ifTrue:
[errorCode := self getErrorObjectFromPrimFailCode.
self stackTopPut: errorCode "nil if primFailCode == 1, or primFailCode"].
primFailCode := 0].
StackInterpreter>>getErrorObjectFromPrimFailCode
"Answer the errorCode object to supply to a failing primitive method that accepts one.
If there is a primitive error table and the primFailCode is a valid index there-in answer
the coprresponding entry in the table, otherwise simply answer the code as an integer."
| table |
primFailCode > 0 ifTrue:
[table := objectMemory splObj: PrimErrTableIndex.
primFailCode <= ((objectMemory lastPointerOf: table) // self bytesPerWord) ifTrue:
[^objectMemory fetchPointer: primFailCode - 1 ofObject: table]].
^objectMemory integerObjectOf: primFailCode |
No description provided.
The text was updated successfully, but these errors were encountered: