Skip to content

Compiling method with pragma - #262

Open
luc-raz wants to merge 10 commits into
mainfrom
243-Compiling-primitive-methods
Open

luc-raz wants to merge 10 commits into
mainfrom
243-Compiling-primitive-methods

Conversation

@luc-raz

@luc-raz luc-raz commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fix: #243
Now, can compile successfully pragma with only simple primitive (eg: primitive:1)

For the case of pragma that defines an error variable, we need to define a temp for it. But for now, we are always using temp vector for handling all the temps (in the picture). So it breaks the execution of the method.
We need to rework on it after the optimisation of the use of the temp vector.

pragmas

@luc-raz
luc-raz requested a review from PalumboN September 2, 2026 15:04

@PalumboN PalumboN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @luc-raz ,

I left some comments, answer them if you want to discuss something.

The main issue are the tests (that are not calling the primitive) and some code cleaning.

The thing to think about is the model of the pragmas in our IR. I think that an instruction per pragma is better, but I'm not sure.

Comment on lines +21 to +32
{ #category : 'visiting' }
DRBlockIRGenerator >> interpretCode: aDRMethod receiver: aReceiver [

self setupCFGScope: aDRMethod codeNode.

self pushFrameForCode: aDRMethod receiver: aReceiver.
aDRMethod executeOn: self.

^ self popFrame.

]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is already implemented in the superclass DRMethodIRGenerator

@luc-raz luc-raz Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the super method, the difference is I initialize the pragma

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But you are not doing that in this method 🤔

Comment thread Druid/DRMethodControlFlowGraph.class.st Outdated
Comment on lines +48 to +53
{ #category : 'queries' }
DRMethodControlFlowGraph >> initialize [

super initialize .
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary code

Comment thread Druid-Opal-Tests/DrOpalExamples.class.st
Comment thread Druid/DRInstructionFactory.class.st Outdated
Comment on lines +141 to +152
{ #category : 'initialization' }
DRInstructionFactory >> initializePragma [

^ DRInitializePragma pragmas.
]

{ #category : 'initialization' }
DRInstructionFactory >> initializeScope: aDRScope [

^ DRInitializeScope scope: aDRScope
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These methods must be extension methods of Druid-Opal package, because these classes are in that package. And sometimes we want to load Druid code without the Opal extension ;)

Comment thread Druid-Opal/DRBytecodeGenerator.class.st Outdated
Comment on lines +294 to +298
"if the pragma is a primitive that defines an error variable, we need to store error value"
each isPrimitiveErrorPragma ifTrue: [
builder
storeRemoteTemp: each primitiveErrorVariableName
inVector: aDRInitializePragma scope tempVectorName.]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh the error variable is working then? 🤔

Comment thread Druid-Opal/DRInitializePragma.class.st Outdated
Comment on lines +59 to +69
{ #category : 'accessing' }
DRInitializePragma >> scope [

^ scope
]

{ #category : 'accessing' }
DRInitializePragma >> scope: anObject [

scope := anObject
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scope of the pragma is always the method scope. The instructions already knows their CFG

self controlFlowGraph scope

Comment on lines +418 to +421
DRBytecodeGenerator >> visitPragmaNode: aPragmaNode [

builder addPragma: aPragmaNode pragma.
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh ok, this is for adding it to the metadata in the literals

Comment on lines +93 to +101
{ #category : 'initialization' }
DRMethodIRGenerator >> initializePragma: pragmas [

| instr |
instr := self currentBasicBlock initializePragma.
instr pragmas: pragmas.
instr scope: self scope.
pragmas do: [ :each | each acceptVisitor: self].
]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would not be better to have one instructions per pragma? DRPragmas instead of Init...?

DRMethodIRGenerator >> interpretCode: aDRMethod receiver: aReceiver [

self setupCFGScope: aDRMethod codeNode.
self initializePragma: aDRMethod codeNode pragmas.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the CFG should only have a InitPragma instruction if there are pragmas in the method, and not always.

Also, here we manage any pragma, not only primitives... I don't know if that is good or bad, just saying 😇

Comment on lines +496 to +507
{ #category : 'visiting' }
DRMethodIRGenerator >> visitPragmaNode: aPragmaNode [

| var varNode|
"if the pragma defines an error variable, we need to declare a temp and add it to scope"

aPragmaNode isPrimitiveErrorPragma ifFalse: [ ^ self ].
varNode := OCVariableNode named: aPragmaNode primitiveErrorVariableName.
var := PrimitiveErrorVariable node: varNode.
self ir scope addTempVariables: { var }

]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhh our scopes have AST nodes as variables, I didn't remember that :P

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can open an issue for this

@PalumboN

PalumboN commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Ahhh and I don't understand if the error variable is working or not, because you said not but there are changes related to that.

If necessary, we can move that to another issue, and optimize the temp vectors before.

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

Successfully merging this pull request may close these issues.

Compiling primitive methods

2 participants