SmallInteger>>++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1 error: code > ^ code
11 ++ 'ww' => nil
(i tried different numbered primitives, and it seems like all of them not using error codes, it always returns nil)
Named prims, however working ok:
SmallInteger>>+++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 'qweqw' error: code > ^ code
11 +++ 'ww' => #'not found'
'CoInterpreter VMMaker.oscog-eem.152 uuid: d39d62b0-45ca-4621-8f67-e3981bbe1875 Mar 3 2012, StackToRegisterMappingCogit VMMaker.oscog-eem.148 uuid: bb53aa60-4173-48ed-874b-dc0ff5a48992 Mar 3 2012, r2538 http://www.squeakvm.org/svn/squeak/branches/Cog'
here the bytecode of corresponding methods: <primitive: 3 error: code> 13 <81 41> storeIntoTemp: 1 15 <11> pushTemp: 1 16 <7C> returnTop
<primitive: 'qweqw' error: code> 17 <81 41> storeIntoTemp: 1 19 <11> pushTemp: 1 20 <7C> returnTop
apparently, the ball is on VM side :)
On 16 March 2012 19:11, Igor Stasenko siguctua@gmail.com wrote:
SmallInteger>>++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1 error: code > ^ code
11 ++ 'ww' => nil
(i tried different numbered primitives, and it seems like all of them not using error codes, it always returns nil)
Named prims, however working ok:
SmallInteger>>+++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 'qweqw' error: code > ^ code
11 +++ 'ww' => #'not found'
'CoInterpreter VMMaker.oscog-eem.152 uuid: d39d62b0-45ca-4621-8f67-e3981bbe1875 Mar 3 2012, StackToRegisterMappingCogit VMMaker.oscog-eem.148 uuid: bb53aa60-4173-48ed-874b-dc0ff5a48992 Mar 3 2012, r2538 http://www.squeakvm.org/svn/squeak/branches/Cog'
-- Best regards, Igor Stasenko.
However , some prims reporting errors fine:
veryBasicAt: index <primitive: 60 error: code> ^ code
1 veryBasicAt: 10 => #'inappropriate operation'
(Array new: 10) veryBasicAt: 500 => #'bad index'
i suspect it is about primitives which are directly inlined into interpreter loop.
Igor,
the code in the VM has to be written to answer error codes. Primitive 1 is SmallInteger addition and that primitive's body doesn't fail with an error code, hence the error code is nil. There's nothing wrong here, simply that only some primitives answer error codes. Look at e.g.
primitiveAdd
self pop2AndPushIntegerIfOK: (self stackIntegerValue: 1) + (self stackIntegerValue: 0)
stackIntegerValue: offset "In the StackInterpreter stacks grow down." | integerPointer | integerPointer := stackPages longAt: stackPointer + (offset*BytesPerWord). ^self checkedIntegerValueOf: integerPointer
checkedIntegerValueOf: intOop "Note: May be called by translated primitive code."
(objectMemory isIntegerObject: intOop) ifTrue: [ ^ objectMemory integerValueOf: intOop ] ifFalse: [ self primitiveFail. ^ 0 ]
pop2AndPushIntegerIfOK: integerResult
self successful ifTrue: [(objectMemory isIntegerValue: integerResult) ifTrue: [self pop: 2 thenPush: (objectMemory integerObjectOf: integerResult)] ifFalse: [self success: false]]
as opposed to
primitiveAt
self commonAt: false.
commonAt: stringy "This code is called if the receiver responds primitively to at:. If this is so, it will be installed in the atCache so that subsequent calls of at: or next may be handled immediately in bytecode primitive routines." | index rcvr atIx result | self initPrimCall. rcvr := self stackValue: 1. (objectMemory isNonIntegerObject: rcvr) ifFalse: [^self primitiveFailFor: PrimErrInappropriate]. index := self stackTop. "No need to test for large positive integers here. No object has 1g elements" (objectMemory isIntegerObject: index) ifFalse: [^self primitiveFailFor: PrimErrBadArgument]. index := objectMemory integerValueOf: index.
"NOTE: The at-cache, since it is specific to the non-super response to #at:. Therefore we must determine that the message is #at: (not, eg, #basicAt:), and that the send is not a super-send, before using the at-cache." (messageSelector = (self specialSelector: 16) and: [lkupClass = (objectMemory fetchClassOfNonInt: rcvr)]) ifTrue: ["OK -- look in the at-cache" atIx := rcvr bitAnd: AtCacheMask. "Index into atCache = 4N, for N = 0 ... 7" (atCache at: atIx+AtCacheOop) = rcvr ifFalse: ["Rcvr not in cache. Attempt to install it..." (self install: rcvr inAtCache: atCache at: atIx string: stringy) ifFalse: [self assert: (objectMemory isContextNonInt: rcvr). self initPrimCall. ^self primitiveContextAt]]. self successful ifTrue: [result := self commonVariable: rcvr at: index cacheIndex: atIx]. self successful ifTrue: [^ self pop: argumentCount+1 thenPush: result]].
"The slow but sure way..." self initPrimCall. result := self stObject: rcvr at: index. self successful ifTrue: [stringy ifTrue: [result := self characterForAscii: (objectMemory integerValueOf: result)]. ^ self pop: argumentCount+1 thenPush: result] On Fri, Mar 16, 2012 at 11:11 AM, Igor Stasenko siguctua@gmail.com wrote:
SmallInteger>>++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1 error: code > ^ code
11 ++ 'ww' => nil
(i tried different numbered primitives, and it seems like all of them not using error codes, it always returns nil)
Named prims, however working ok:
SmallInteger>>+++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 'qweqw' error: code > ^ code
11 +++ 'ww' => #'not found'
'CoInterpreter VMMaker.oscog-eem.152 uuid: d39d62b0-45ca-4621-8f67-e3981bbe1875 Mar 3 2012, StackToRegisterMappingCogit VMMaker.oscog-eem.148 uuid: bb53aa60-4173-48ed-874b-dc0ff5a48992 Mar 3 2012, r2538 http://www.squeakvm.org/svn/squeak/branches/Cog'
-- Best regards, Igor Stasenko.
sorry for the noise.
well, i was assumed that if prim does not providing specific error code, while method using <prim: error: > pragma, then error code should be #'generic error', indicating that:
a) the prim doesn't care about telling specific error but b) VM supports error codes for prims.
because if prim answers nil, i cannot distinguish whether VM handling them or not.. well. i don't really care about it.. since i would not recommend using Vms without primitive error codes anyways :) but still.
On 16 March 2012 19:29, Eliot Miranda eliot.miranda@gmail.com wrote:
Igor,
the code in the VM has to be written to answer error codes. Primitive 1 is SmallInteger addition and that primitive's body doesn't fail with an error code, hence the error code is nil. There's nothing wrong here, simply that only some primitives answer error codes. Look at e.g.
primitiveAdd
self pop2AndPushIntegerIfOK: (self stackIntegerValue: 1) + (self stackIntegerValue: 0)
stackIntegerValue: offset "In the StackInterpreter stacks grow down." | integerPointer | integerPointer := stackPages longAt: stackPointer + (offset*BytesPerWord). ^self checkedIntegerValueOf: integerPointer
checkedIntegerValueOf: intOop "Note: May be called by translated primitive code."
(objectMemory isIntegerObject: intOop) ifTrue: [ ^ objectMemory integerValueOf: intOop ] ifFalse: [ self primitiveFail. ^ 0 ]
pop2AndPushIntegerIfOK: integerResult
self successful ifTrue: [(objectMemory isIntegerValue: integerResult) ifTrue: [self pop: 2 thenPush: (objectMemory integerObjectOf: integerResult)] ifFalse: [self success: false]]
as opposed to
primitiveAt
self commonAt: false.
commonAt: stringy "This code is called if the receiver responds primitively to at:. If this is so, it will be installed in the atCache so that subsequent calls of at: or next may be handled immediately in bytecode primitive routines." | index rcvr atIx result | self initPrimCall. rcvr := self stackValue: 1. (objectMemory isNonIntegerObject: rcvr) ifFalse: [^self primitiveFailFor: PrimErrInappropriate]. index := self stackTop. "No need to test for large positive integers here. No object has 1g elements" (objectMemory isIntegerObject: index) ifFalse: [^self primitiveFailFor: PrimErrBadArgument]. index := objectMemory integerValueOf: index.
"NOTE: The at-cache, since it is specific to the non-super response to #at:. Therefore we must determine that the message is #at: (not, eg, #basicAt:), and that the send is not a super-send, before using the at-cache." (messageSelector = (self specialSelector: 16) and: [lkupClass = (objectMemory fetchClassOfNonInt: rcvr)]) ifTrue: ["OK -- look in the at-cache" atIx := rcvr bitAnd: AtCacheMask. "Index into atCache = 4N, for N = 0 ... 7" (atCache at: atIx+AtCacheOop) = rcvr ifFalse: ["Rcvr not in cache. Attempt to install it..." (self install: rcvr inAtCache: atCache at: atIx string: stringy) ifFalse: [self assert: (objectMemory isContextNonInt: rcvr). self initPrimCall. ^self primitiveContextAt]]. self successful ifTrue: [result := self commonVariable: rcvr at: index cacheIndex: atIx]. self successful ifTrue: [^ self pop: argumentCount+1 thenPush: result]].
"The slow but sure way..." self initPrimCall. result := self stObject: rcvr at: index. self successful ifTrue: [stringy ifTrue: [result := self characterForAscii: (objectMemory integerValueOf: result)]. ^ self pop: argumentCount+1 thenPush: result] On Fri, Mar 16, 2012 at 11:11 AM, Igor Stasenko siguctua@gmail.com wrote:
SmallInteger>>++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 1 error: code > ^ code
11 ++ 'ww' => nil
(i tried different numbered primitives, and it seems like all of them not using error codes, it always returns nil)
Named prims, however working ok:
SmallInteger>>+++ aNumber "Primitive. Add the receiver to the argument and answer with the result if it is a SmallInteger. Fail if the argument or the result is not a SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."
<primitive: 'qweqw' error: code > ^ code
11 +++ 'ww' => #'not found'
'CoInterpreter VMMaker.oscog-eem.152 uuid: d39d62b0-45ca-4621-8f67-e3981bbe1875 Mar 3 2012, StackToRegisterMappingCogit VMMaker.oscog-eem.148 uuid: bb53aa60-4173-48ed-874b-dc0ff5a48992 Mar 3 2012, r2538 http://www.squeakvm.org/svn/squeak/branches/Cog'
-- Best regards, Igor Stasenko.
-- best, Eliot
vm-dev@lists.squeakfoundation.org