11import { mapValues , range , zip } from './lib/object.ts' ;
2- import { hexlify } from './bytes.ts' ;
2+ import { bigintify } from './bytes.ts' ;
33import { Dispatch , type Opcode } from './decode.ts' ;
44import { Inst , Local , Lit , SExpr , Def } from './sexpr.ts' ;
55import type { State , StepFn , Step } from './sevm.ts' ;
66
7- function addLocal ( { insts, stack } : State , expr : SExpr , pc : number ) {
8- const local = new Local ( insts . length , expr ) ;
9- insts . push ( new Def ( local , pc ) ) ;
10- stack . push ( local ) ;
7+ const sexpr = ( inputs : number ) => function ( this : IAddLocal , state : State , op : Opcode ) {
8+ return this . addLocal ( state , new SExpr ( op . mnemonic . toLowerCase ( ) , state . stack . popn ( inputs ) ) , op . pc ) ;
119}
1210
13- const sexpr = ( inputs : number ) => function ( state : State , op : Opcode ) {
14- addLocal ( state , new SExpr ( op . mnemonic . toLowerCase ( ) , state . stack . popn ( inputs ) ) , op . pc ) ;
11+ const sinst = ( inputs : number ) => function ( state : State , op : Opcode ) {
12+ return new Inst ( op . mnemonic . toLowerCase ( ) , state . stack . popn ( inputs ) , op . pc ) ;
1513}
1614
17- const sinst = ( inputs : number ) => function ( { insts , stack } : State , op : Opcode ) {
18- insts . push ( new Inst ( op . mnemonic . toLowerCase ( ) , stack . popn ( inputs ) , op . pc ) ) ;
15+ interface IAddLocal {
16+ addLocal ( state : State , expr : SExpr , pc : number ) : Inst ;
1917}
2018
2119function ForkFactory < M extends string > (
2220 def : { [ m in M ] : { op : number , size ?: number , step : StepFn } } ,
2321 invalid : NoInfer < M > ,
2422) : new ( ) => Dispatch < M > & Step < M > {
25- class Fork extends Dispatch < M > {
23+ class Fork extends Dispatch < M > implements IAddLocal {
24+ readonly #locals = new WeakMap < State , number > ( ) ;
25+
2626 constructor ( ) {
2727 super ( def , invalid ) ;
2828 }
2929
30- decode1 ( ) {
31- return this . decode ( null as unknown as Uint8Array , 0 ) ;
32- }
33- * decode2 ( ) {
34- yield this . decode ( null as unknown as Uint8Array , 0 ) ;
30+ addLocal ( state : State , expr : SExpr , pc : number ) {
31+ const id = this . #locals. get ( state ) ?? 0 ;
32+ this . #locals. set ( state , id + 1 ) ;
33+
34+ const local = new Local ( state . pcbegin , id , expr ) ;
35+ state . stack . push ( local ) ;
36+ // state.insts.push(new Def(local, pc));
37+ return new Def ( local , pc ) ;
3538 }
36- // *decode3(pc0: number): Generator<Opcode & {mnemonic: number}, void, unknown> {
37- // yield* this.decode(null as unknown as Uint8Array, pc0);
38- // }
3939 }
4040 Object . assign ( Fork . prototype , mapValues ( def , op => op . step ) ) ;
4141 return Fork as ( new ( ) => Dispatch < M > & Step < M > ) ;
@@ -48,15 +48,20 @@ const FlowDef = {
4848 JUMPDEST : { op : 0x5B , step : sinst ( 0 ) } ,
4949 ...zip ( range ( 32 ) . map ( i => [
5050 `PUSH${ i + 1 as Size < 32 > } ` ,
51- { op : 0x60 + i , size : i + 1 , step : ( state , op ) => addLocal ( state , new Lit ( BigInt ( '0x' + hexlify ( op . data ! ) ) ) , op . pc ) }
51+ {
52+ op : 0x60 + i , size : i + 1 , step : function ( this : IAddLocal , state , op ) {
53+ // return this.addLocal(state, new Lit(BigInt('0x' + hexlify(op.data!))), op.pc);
54+ return this . addLocal ( state , new Lit ( bigintify ( op . data ! ) ) , op . pc ) ;
55+ }
56+ }
5257 ] as const ) ) ,
5358 ...zip ( range ( 16 ) . map ( i => [
5459 `DUP${ i + 1 as Size < 16 > } ` ,
55- { op : 0x80 + i , step : ( { stack } ) => stack . dup ( i ) }
60+ { op : 0x80 + i , step : ( { stack } ) => ( stack . dup ( i ) , undefined ) }
5661 ] as const ) ) ,
5762 ...zip ( range ( 16 ) . map ( i => [
5863 `SWAP${ i + 1 as Size < 16 > } ` ,
59- { op : 0x90 + i , step : ( { stack } ) => stack . swap ( i + 1 ) }
64+ { op : 0x90 + i , step : ( { stack } ) => ( stack . swap ( i + 1 ) , undefined ) }
6065 ] as const ) ) ,
6166 INVALID : { op : 0xfe , step : sinst ( 0 ) } ,
6267} satisfies Parameters < typeof ForkFactory > [ 0 ] ;
@@ -157,7 +162,11 @@ const ParisDef = {
157162
158163const ShanghaiDef = {
159164 ...ParisDef ,
160- PUSH0 : { op : 0x5F , step : ( state , op ) => addLocal ( state , new Lit ( 0n ) , op . pc ) } ,
165+ PUSH0 : {
166+ op : 0x5F , step : function ( this : IAddLocal , state , op ) {
167+ this . addLocal ( state , new Lit ( 0n ) , op . pc )
168+ }
169+ } ,
161170} satisfies Parameters < typeof ForkFactory > [ 0 ] ;
162171
163172export const Flow = ForkFactory ( FlowDef , 'INVALID' ) ;
0 commit comments