On 26 January 2012 15:08, Mariano Martinez Peck marianopeck@gmail.com wrote:
There's another problem with using "tryXYZ" when primitive doing something weird with contexts (like block's #value) because then debugger cannot intercept switching contexts so easily, when primitive doing manipulation with contexts, because debugger have no idea where to put his next "break point" to do step-by-step evaluation.
I thinking that there should be special primitive which: - takes a context, a receiver, a method and arguments (or just a context, if debugger ensures to pass it in prepared state i.e. receiver and args already on stack) - invokes method's primitive - answers a nil if primitive failed or a new context object, which holds an updated context state after primitive possibly manipulated with context(s)
Isn't that what the new (only in Cog) primtiive 218 does ? #primitiveDoNamedPrimitiveWithArgs
i just checked the code. it invokes a prim. but no, if prim manipulate the context state, or just changes an active context, like in (sema wait) a debugger won't be able to intercept return from prim, and an arbitrary code will go running for indefinite period, without any guarantees that it will ever return back to debugger somehow.
And this is not acceptable.
if you look at #doPrimitive: primitiveIndex method: meth receiver: receiver args: arguments there a huge case statement, which actually dealing with all those prims which manipulating the contexts, now if primitiveDoNamedPrimitiveWithArgs would care to answer an updated debuggable context state , that method will turn into 1-liner. And what i don't like about that code, that image kind of having an intimate knowledge about what certain primitive(s) doing. It ties closely VM implementation details with image, which is not good.
So, IMO, a right way to implement a "tryPrimitive" primitive is to pass a single argument to it: debuggable context. and it should return an updated debuggable context or nil if primitive failed.
Igor notice that all I have mentioned only happens when we are running in a non-cog VM because otherwise #primitiveDoNamedPrimitiveWithArgs will be used. See #tryNamedPrimitiveIn: aCompiledMethod for: aReceiver withArgs: arguments
My code is just the fallback for none-code vms.
so, then debugger will use it like:
contextOrNil := self invokeMethodPrimitive: method context: currentContext receiver: recvr arguments: args contextOrNil ifNil: [ primitive failed .. ] ifNotNil: [ currentContext := contextOrNil ].
-- Best regards, Igor Stasenko.
-- Mariano http://marianopeck.wordpress.com