@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
22
33import { compile } from "#compiler" ;
44import type * as Format from "@ethdebug/format" ;
5- import { Program } from "@ethdebug/format" ;
5+ import { Pointer , Program } from "@ethdebug/format" ;
66
77const { Context } = Program ;
88const { Invocation } = Context . Invoke ;
@@ -68,52 +68,42 @@ code {
6868 result = add(10, 20);
6969}` ;
7070
71- it ( "should emit invoke context on caller JUMP" , async ( ) => {
72- const program = await compileProgram ( source ) ;
71+ it (
72+ "should emit invoke context on caller JUMP " +
73+ "(identity + code target, no args)" ,
74+ async ( ) => {
75+ const program = await compileProgram ( source ) ;
7376
74- const invokeJumps = findInstructionsWithContext (
75- program ,
76- "JUMP" ,
77- Context . isInvoke ,
78- ) ;
79-
80- expect ( invokeJumps . length ) . toBeGreaterThanOrEqual ( 1 ) ;
77+ const invokeJumps = findInstructionsWithContext (
78+ program ,
79+ "JUMP" ,
80+ Context . isInvoke ,
81+ ) ;
8182
82- const { invoke } = invokeJumps [ 0 ] . context ;
83- expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
83+ expect ( invokeJumps . length ) . toBeGreaterThanOrEqual ( 1 ) ;
8484
85- const call = invoke as InternalCall ;
86- expect ( call . jump ) . toBe ( true ) ;
87- expect ( call . identifier ) . toBe ( "add" ) ;
85+ const { invoke } = invokeJumps [ 0 ] . context ;
86+ expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
8887
89- // Should have declaration source range
90- expect ( invoke . declaration ) . toBeDefined ( ) ;
91- expect ( invoke . declaration ! . source ) . toEqual ( { id : "0" } ) ;
92- expect ( invoke . declaration ! . range ) . toBeDefined ( ) ;
93- expect ( typeof invoke . declaration ! . range ! . offset ) . toBe ( "number" ) ;
94- expect ( typeof invoke . declaration ! . range ! . length ) . toBe ( "number" ) ;
95-
96- // Should have target pointer
97- expect ( call . target . pointer ) . toBeDefined ( ) ;
98-
99- // Should have argument pointers
100- expect ( call . arguments ) . toBeDefined ( ) ;
101- const group = ( call . arguments ! . pointer as { group : unknown [ ] } ) . group ;
102-
103- expect ( group ) . toHaveLength ( 2 ) ;
104- // First arg (a) is deepest on stack
105- expect ( group [ 0 ] ) . toEqual ( {
106- name : "a" ,
107- location : "stack" ,
108- slot : 1 ,
109- } ) ;
110- // Second arg (b) is on top
111- expect ( group [ 1 ] ) . toEqual ( {
112- name : "b" ,
113- location : "stack" ,
114- slot : 0 ,
115- } ) ;
116- } ) ;
88+ const call = invoke as InternalCall ;
89+ expect ( call . jump ) . toBe ( true ) ;
90+ expect ( call . identifier ) . toBe ( "add" ) ;
91+
92+ // Should have declaration source range
93+ expect ( invoke . declaration ) . toBeDefined ( ) ;
94+ expect ( invoke . declaration ! . source ) . toEqual ( { id : "0" } ) ;
95+ expect ( invoke . declaration ! . range ) . toBeDefined ( ) ;
96+ expect ( typeof invoke . declaration ! . range ! . offset ) . toBe ( "number" ) ;
97+ expect ( typeof invoke . declaration ! . range ! . length ) . toBe ( "number" ) ;
98+
99+ // Target should be a code pointer (not stack)
100+ expect ( Pointer . Region . isCode ( call . target . pointer ) ) . toBe ( true ) ;
101+
102+ // Caller JUMP should NOT have argument pointers
103+ // (args live on the callee JUMPDEST invoke context)
104+ expect ( call . arguments ) . toBeUndefined ( ) ;
105+ } ,
106+ ) ;
117107
118108 it ( "should emit return context on continuation JUMPDEST" , async ( ) => {
119109 const program = await compileProgram ( source ) ;
@@ -142,32 +132,51 @@ code {
142132 } ) ;
143133 } ) ;
144134
145- it ( "should emit invoke context on callee entry JUMPDEST" , async ( ) => {
146- const program = await compileProgram ( source ) ;
135+ it (
136+ "should emit invoke context on callee entry " +
137+ "JUMPDEST with args and code target" ,
138+ async ( ) => {
139+ const program = await compileProgram ( source ) ;
147140
148- // The callee entry point, not the continuation
149- const invokeJumpdests = findInstructionsWithContext (
150- program ,
151- "JUMPDEST" ,
152- Context . isInvoke ,
153- ) ;
141+ // The callee entry point, not the continuation
142+ const invokeJumpdests = findInstructionsWithContext (
143+ program ,
144+ "JUMPDEST" ,
145+ Context . isInvoke ,
146+ ) ;
154147
155- expect ( invokeJumpdests . length ) . toBeGreaterThanOrEqual ( 1 ) ;
148+ expect ( invokeJumpdests . length ) . toBeGreaterThanOrEqual ( 1 ) ;
149+
150+ const { invoke } = invokeJumpdests [ 0 ] . context ;
151+ expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
156152
157- const { invoke } = invokeJumpdests [ 0 ] . context ;
158- expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
153+ const call = invoke as InternalCall ;
154+ expect ( call . jump ) . toBe ( true ) ;
155+ expect ( call . identifier ) . toBe ( "add" ) ;
159156
160- const call = invoke as InternalCall ;
161- expect ( call . jump ) . toBe ( true ) ;
162- expect ( call . identifier ) . toBe ( "add" ) ;
157+ // Target should be a code pointer
158+ expect ( Pointer . Region . isCode ( call . target . pointer ) ) . toBe ( true ) ;
163159
164- // Should have argument pointers matching
165- // function parameters
166- expect ( call . arguments ) . toBeDefined ( ) ;
167- const group = ( call . arguments ! . pointer as { group : unknown [ ] } ) . group ;
160+ // Should have argument pointers matching
161+ // function parameters
162+ expect ( call . arguments ) . toBeDefined ( ) ;
163+ const group = ( call . arguments ! . pointer as { group : unknown [ ] } ) . group ;
168164
169- expect ( group ) . toHaveLength ( 2 ) ;
170- } ) ;
165+ expect ( group ) . toHaveLength ( 2 ) ;
166+ // First arg (a) is deepest on stack
167+ expect ( group [ 0 ] ) . toEqual ( {
168+ name : "a" ,
169+ location : "stack" ,
170+ slot : 1 ,
171+ } ) ;
172+ // Second arg (b) is on top
173+ expect ( group [ 1 ] ) . toEqual ( {
174+ name : "b" ,
175+ location : "stack" ,
176+ slot : 0 ,
177+ } ) ;
178+ } ,
179+ ) ;
171180
172181 it ( "should emit contexts in correct instruction order" , async ( ) => {
173182 const program = await compileProgram ( source ) ;
@@ -331,32 +340,37 @@ code {
331340 result = double(7);
332341}` ;
333342
334- it ( "should emit single-element argument group" , async ( ) => {
335- const program = await compileProgram ( singleArgSource ) ;
343+ it (
344+ "should emit single-element argument group " + "on callee JUMPDEST" ,
345+ async ( ) => {
346+ const program = await compileProgram ( singleArgSource ) ;
336347
337- const invokeJumps = findInstructionsWithContext (
338- program ,
339- "JUMP" ,
340- Context . isInvoke ,
341- ) ;
348+ // Args are on the callee JUMPDEST, not the
349+ // caller JUMP
350+ const invokeJumpdests = findInstructionsWithContext (
351+ program ,
352+ "JUMPDEST" ,
353+ Context . isInvoke ,
354+ ) ;
342355
343- expect ( invokeJumps . length ) . toBeGreaterThanOrEqual ( 1 ) ;
356+ expect ( invokeJumpdests . length ) . toBeGreaterThanOrEqual ( 1 ) ;
344357
345- const { invoke } = invokeJumps [ 0 ] . context ;
346- expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
358+ const { invoke } = invokeJumpdests [ 0 ] . context ;
359+ expect ( Invocation . isInternalCall ( invoke ) ) . toBe ( true ) ;
347360
348- const call = invoke as InternalCall ;
349- expect ( call . arguments ) . toBeDefined ( ) ;
350- const group = ( call . arguments ! . pointer as { group : unknown [ ] } ) . group ;
361+ const call = invoke as InternalCall ;
362+ expect ( call . arguments ) . toBeDefined ( ) ;
363+ const group = ( call . arguments ! . pointer as { group : unknown [ ] } ) . group ;
351364
352- // Single arg at stack slot 0
353- expect ( group ) . toHaveLength ( 1 ) ;
354- expect ( group [ 0 ] ) . toEqual ( {
355- name : "x" ,
356- location : "stack" ,
357- slot : 0 ,
358- } ) ;
359- } ) ;
365+ // Single arg at stack slot 0
366+ expect ( group ) . toHaveLength ( 1 ) ;
367+ expect ( group [ 0 ] ) . toEqual ( {
368+ name : "x" ,
369+ location : "stack" ,
370+ slot : 0 ,
371+ } ) ;
372+ } ,
373+ ) ;
360374 } ) ;
361375
362376 describe ( "return epilogue source maps" , ( ) => {
0 commit comments