Skip to content
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

Primitive Failed #14

Open
vitormcruz opened this issue Jun 17, 2022 · 5 comments
Open

Primitive Failed #14

vitormcruz opened this issue Jun 17, 2022 · 5 comments

Comments

@vitormcruz
Copy link

vitormcruz commented Jun 17, 2022

On a Pharo 10 image in a Windows 10, when I execute this code :

| proxy |

proxy := GHObjectMutation behaviour: GHDelegatorBehaviour new.
proxy mutate: #(4 3 3 8 11 34 1).
proxy collect: [ :it | it * 2 ].

I got a "PrimitiveFailed: primitive #setClass:to: in GHMetaMessages class failed":

GHMetaMessages class(ProtoObject)>>primitiveFailed
GHMetaMessages class>>setClass:to:
Array(ProtoObject)>>injectGHMutation:
Array class(GHObjectMutation)>>mutate:
UndefinedObject>>DoIt
[ receiver withArgs: (context ifNil: [ #() ] ifNotNil: [ {context} ]) executeMethod: self compileDoit] in OpalCompiler>>evaluate in Block: [ receiver withArgs: (context ifNil: [ #() ] ifNot...etc...
FullBlockClosure(BlockClosure)>>on:do:
OpalCompiler>>evaluate
[
		oldBindings := self interactionModel bindings copy.
		receiver := self interactionModel doItReceiver.
		result := receiver class compiler
			source: aString readStream;
			context: self interactionModel doItContext;
			receiver: self interactionModel doItReceiver;
			requestor: self interactionModel;
			environment: self environment;
			failBlock:  [ ^ compileErrorBlock value ];
			evaluate.
		oldBindings size = self interactionModel bindings size 
			ifFalse: [ self withAdapterDo: [ :anAdapter | anAdapter refreshStyling ] ].
		result ] in SpCodePresenter>>evaluate:onCompileError:onError: in Block: [...
FullBlockClosure(BlockClosure)>>on:do:
SpCodePresenter>>evaluate:onCompileError:onError:
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluate:andDo:
SpCodeInspectItCommand(SpCodeSelectionCommand)>>evaluateSelectionAndDo:
SpCodeInspectItCommand>>execute
SpCommand(CmCommandDecorator)>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
			psValueAt: index
			put: anObject.
		aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[ self decoratedCommand execute ] in SpToolCurrentApplicationCommand>>execute in Block: [ self decoratedCommand execute ]
[ activeProcess
			psValueAt: index
			put: anObject.
		aBlock value ] in SpToolCurrentApplication(DynamicVariable)>>value:during: in Block: [ activeProcess...
FullBlockClosure(BlockClosure)>>ensure:
SpToolCurrentApplication(DynamicVariable)>>value:during:
SpToolCurrentApplication class(DynamicVariable class)>>value:during:
SpToolCurrentApplicationCommand>>execute
[ 
			aCmCommand canBeExecuted 
				ifTrue: [ aCmCommand execute ] ] in SpKMCategoryBuilder>>visitCommand: in Block: [ ...
FullBlockClosure(BlockClosure)>>cull:
@dionisiydk
Copy link
Collaborator

dionisiydk commented Jun 17, 2022

The mutation over literals is not supported because they are readonly objects since Pharo 10. They can't be modified. The equivalent error would be for an expression:

#(4 3 3 8 11 34 1) at: 2 put: 100.

The error here is more explicit ModificationForbidden. The MirrorPrimitives can be improved to reflect it as well.

But generally your example is not correct. The mutation instance is not a proxy. It modifies given object (an array here) in the way to intercept all messages and process it with the configured behaviour. So it does not replace the object.
The correct example should be:

object := #(4 3 3 8 11 34 1) copy.
mutation := GHObjectMutation behaviour: (GHDelegatorBehaviour target: #(-1 -2 -3)).
mutation mutate: object.
object collect: [ :it | it * 2 ]. "==> #(-1 -4 -6)"

Notice that I added a target array into GHDelegatorBehaviour because the delegator simply resends all intercepted messages into it. Otherwise there will be an error DNU to nil:

object := #(4 3 3 8 11 34 1) copy.
mutation := GHObjectMutation behaviour: GHDelegatorBehaviour new.
mutation mutate: object.
object printString => " ==> 'nil' "

@vitormcruz
Copy link
Author

Humm. This project is related to https://hal.inria.fr/inria-00614720/document? I though so... Well, GHObjectMutation creates an interceptor that I can use to create proxies? It seems so considering your explanation. Anyway thanks, I manage to understand better and make a simple example works.

Besides that, I agree this is not an error. Maybe providing an specific error could be considered an enhancement? Something like 'Trying to mutate a literal which is not supported'?

@dionisiydk
Copy link
Collaborator

Humm. This project is related to https://hal.inria.fr/inria-00614720/document? I though so...

I slightly changed the vocabulary and the implementation. So this version is quite different than one from the paper.

Besides that, I agree this is not an error. Maybe providing an specific error could be considered an enhancement? Something like 'Trying to mutate a literal which is not supported'?

Yes, it will be a good improvement but it is part of Pharo , not this project.

@vitormcruz
Copy link
Author

The problem occurs using this lib, why providing better information of the error is part of Pharo? Instead of a "Primitive Failed' error, if mutation: method informed that primitives cannot be mutated wouldn't it be clearer for Ghost users?

@dionisiydk
Copy link
Collaborator

My comment was about incompleteness of the implementation of MirrorPrimitives method #setClass:to: . It is core part of Pharo. And it have to raise a better exception describing the inability to modify the object: ModificationForbidden in that case.

I don't mind to have a ghost-specific error as well. But I don't see the use case for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants