Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(1 edit)

I’m less sure if this helps, because on top of the other one, I can’t tell if it does. I’ll have to test without the other optimization.

I know if I do this sort of lookup dispatch in my C forths/lisps, they don’t help. Usually the switch-case is best - probably due to inlining rather than function pointer tables. I’ve never sat down to look, just empirical testing. But, maybe it helps in JS.

turns the switch-case into a lookup table:

diff --git a/js/lil.js b/js/lil.js
index 31b10f4..a88963c 100644
--- a/js/lil.js
+++ b/js/lil.js
@@ -714,50 +714,52 @@ docall=(f,a,tail)=>{
 	issue(f.a.length==1&&f.a[0][0]=='.'?env_bind(f.c,[f.a[0].slice(3)],monad.list(a)): env_bind(f.c,f.a,a),f.b)
 	calldepth=max(calldepth,state.e.length)
 }
+ops={
+	[op.DROP ]:(o,imm,b)=>{arg()},
+	[op.DUP  ]:(o,imm,b)=>{const a=arg();ret(a),ret(a);},
+	[op.SWAP ]:(o,imm,b)=>{const a=arg();b=arg();ret(a),ret(b);},
+	[op.OVER ]:(o,imm,b)=>{const a=arg();b=arg();ret(b),ret(a),ret(b);},
+	[op.JUMP ]:(o,imm,b)=>{setpc(imm)},
+	[op.JUMPF]:(o,imm,b)=>{if(!lb(arg()))setpc(imm)},
+	[op.JUMPT]:(o,imm,b)=>{if( lb(arg()))setpc(imm)},
+	[op.LIT  ]:(o,imm,b)=>{ret(blk_getimm(b,imm))},
+	[op.GET  ]:(o,imm,b)=>{ret(env_get(getev(),blk_getimm(b,imm)));},
+	[op.SET  ]:(o,imm,b)=>{const v=arg();env_set(getev(),blk_getimm(b,imm),v),ret(v);},
+	[op.LOC  ]:(o,imm,b)=>{const v=arg();env_local(getev(),blk_getimm(b,imm),v),ret(v);},
+	[op.LOCS ]:(o,imm,b)=>{env_locals(getev(),blk_getimm(b,imm));},
+	[op.BUND ]:(o,imm,b)=>{const r=[];for(let z=0;z<imm;z++)r.push(arg());r.reverse(),ret(lml(r));},
+	[op.OP1  ]:(o,imm,b)=>{                      ret(monadi[imm](arg()));},
+	[op.OP2  ]:(o,imm,b)=>{const         y=arg();ret(dyadi [imm](arg(),y));},
+	[op.OP3  ]:(o,imm,b)=>{const z=arg(),y=arg();ret(triadi[imm](arg(),y,z));},
+	[op.IPRE ]:(o,imm,b)=>{const s=arg(),i=arg();ret(i),docall(s,i.v[imm]);if(lion(s)||lii(s)||linat(s)){for(let z=0;z<=imm;z++)i.v[z]=null}},
+	[op.IPOST]:(o,imm,b)=>{const s=arg(),i=arg(),r=arg();ret(i.v[imm]?r:s),ret(i),ret(s);},
+	[op.AMEND]:(o,imm,b)=>{
+			let v=arg(),r=arg(),i=ll(arg()),ro=arg(),n=blk_getimm(b,imm),t={v:1}
+			if(i.length&&!i[0]){i=i.filter(x=>x),t.v=0}r=amendv(ro,i,v,0,t);if(t.v&&!lin(n))env_set(getev(),n,r);ret(r);
+		},
+	[op.CALL ]:(o,imm,b)=>{const a=arg(),f=arg();docall(f,a,o==op.TAIL);}, // same as tail
+	[op.TAIL ]:(o,imm,b)=>{const a=arg(),f=arg();docall(f,a,o==op.TAIL);},
+	[op.BIND ]:(o,imm,b)=>{const f=arg(),r=lmon(f.n,f.a,f.b);r.c=getev(),env_local(getev(),lms(f.n),r),ret(r);},
+	[op.ITER ]:(o,imm,b)=>{const x=arg();ret(lil(x)?x:ld(x));ret(lid(x)?lmd():lml([]));},
+	[op.FIDX ]:(o,imm,b)=>{const x=arg(),f=arg();if((lid(f)||lil(f)||lis(f))&&lil(x)){ret(lml(x.v.map(x=>l_at(f,x))));setpc(imm)}else{ret(x)};},
+	[op.FMAP ]:(o,imm,b)=>{const x=arg(),f=monadi[imm];ret(lid(x)?lmd(x.k,x.v.map(f)):lml(ll(x).map(f)));},
+	[op.EACH ]:(o,imm,b)=>{
+			const n=arg(),r=arg(),s=arg();if(count(r)==count(s)){setpc(imm),ret(r);}
+			else{const z=count(r), v=lml([s.v[z],lid(s)?s.k[z]:lmn(z),lmn(z)]);
+			state.e.push(env_bind(getev(),n,v)),ret(s),ret(r);}
+		},
+	[op.NEXT ]:(o,imm,b)=>{const v=arg(),r=arg(),s=arg();state.e.pop();if(lid(r))r.k.push(s.k[r.v.length]);r.v.push(v),ret(s),ret(r),setpc(imm);},
+	[op.COL  ]:(o,imm,b)=>{
+			const ex=arg(),t=arg(),n=tab_cols(t),v=ll(monad.cols(t));ret(t)
+			n.push('column'),v.push(t),issue(env_bind(getev(),n,lml(v)),ex);
+  },
+}
 runop=_=>{
 	op_count+=1
 	const b=getblock();if(!liblk(b))ret(state.t.pop())
 	const pc=getpc(),o=blk_getb(b,pc),imm=(oplens[o]==3?blk_gets(b,1+pc):0); setpc(pc+oplens[o])
-	switch(o){
-		case op.DROP :arg();break
-		case op.DUP  :{const a=arg();ret(a),ret(a);break}
-		case op.SWAP :{const a=arg(),b=arg();ret(a),ret(b);break}
-		case op.OVER :{const a=arg(),b=arg();ret(b),ret(a),ret(b);break}
-		case op.JUMP :setpc(imm);break
-		case op.JUMPF:if(!lb(arg()))setpc(imm);break
-		case op.JUMPT:if( lb(arg()))setpc(imm);break
-		case op.LIT  :ret(blk_getimm(b,imm));break
-		case op.GET  :{ret(env_get(getev(),blk_getimm(b,imm)));break}
-		case op.SET  :{const v=arg();env_set(getev(),blk_getimm(b,imm),v),ret(v);break}
-		case op.LOC  :{const v=arg();env_local(getev(),blk_getimm(b,imm),v),ret(v);break}
-		case op.LOCS :{env_locals(getev(),blk_getimm(b,imm));break}
-		case op.BUND :{const r=[];for(let z=0;z<imm;z++)r.push(arg());r.reverse(),ret(lml(r));break}
-		case op.OP1  :{                      ret(monadi[imm](arg()    ));break}
-		case op.OP2  :{const         y=arg();ret(dyadi [imm](arg(),y  ));break}
-		case op.OP3  :{const z=arg(),y=arg();ret(triadi[imm](arg(),y,z));break}
-		case op.IPRE :{const s=arg(),i=arg();ret(i),docall(s,i.v[imm]);if(lion(s)||lii(s)||linat(s)){for(let z=0;z<=imm;z++)i.v[z]=null}break}
-		case op.IPOST:{const s=arg(),i=arg(),r=arg();ret(i.v[imm]?r:s),ret(i),ret(s);break}
-		case op.AMEND:{
-			let v=arg(),r=arg(),i=ll(arg()),ro=arg(),n=blk_getimm(b,imm),t={v:1}
-			if(i.length&&!i[0]){i=i.filter(x=>x),t.v=0}r=amendv(ro,i,v,0,t);if(t.v&&!lin(n))env_set(getev(),n,r);ret(r);break
-		}
-		case op.CALL : // fall through:
-		case op.TAIL :{const a=arg(),f=arg();docall(f,a,o==op.TAIL);break}
-		case op.BIND :{const f=arg(),r=lmon(f.n,f.a,f.b);r.c=getev(),env_local(getev(),lms(f.n),r),ret(r);break}
-		case op.ITER :{const x=arg();ret(lil(x)?x:ld(x));ret(lid(x)?lmd():lml([]));break}
-		case op.FIDX :{const x=arg(),f=arg();if((lid(f)||lil(f)||lis(f))&&lil(x)){ret(lml(x.v.map(x=>l_at(f,x))));setpc(imm)}else{ret(x)};break}
-		case op.FMAP :{const x=arg(),f=monadi[imm];ret(lid(x)?lmd(x.k,x.v.map(f)):lml(ll(x).map(f)));break}
-		case op.EACH :{
-			const n=arg(),r=arg(),s=arg();if(count(r)==count(s)){setpc(imm),ret(r);break}
-			const z=count(r), v=lml([s.v[z],lid(s)?s.k[z]:lmn(z),lmn(z)]);
-			state.e.push(env_bind(getev(),n,v)),ret(s),ret(r);break
-		}
-		case op.NEXT :{const v=arg(),r=arg(),s=arg();state.e.pop();if(lid(r))r.k.push(s.k[r.v.length]);r.v.push(v),ret(s),ret(r),setpc(imm);break}
-		case op.COL  :{
-			const ex=arg(),t=arg(),n=tab_cols(t),v=ll(monad.cols(t));ret(t)
-			n.push('column'),v.push(t),issue(env_bind(getev(),n,lml(v)),ex);break
-		}
-	}while(running()&&getpc()>=blk_here(getblock()))descope()
+	ops[o](o,imm,b)
+	while(running()&&getpc()>=blk_here(getblock()))descope()
 }
 
 fchar=x=>x=='I'?'i': x=='B'?'b': x=='L'?'s': x=='t'?'J': x=='T'?'J': x
Deleted 20 days ago