From a99a80a7a04efd0a3f6af24edb5b849e5cf0d80b Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 19 Aug 2021 00:37:54 +0300 Subject: [PATCH] VFYM --- src/h.h | 6 +++--- src/jit/nvm_x86_64.c | 21 +++++++++++++-------- src/vm.c | 21 ++++++++++++++++----- src/vm.h | 4 ++++ 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/h.h b/src/h.h index d4f78cc7..819353d7 100644 --- a/src/h.h +++ b/src/h.h @@ -172,10 +172,10 @@ enum Type { /*19*/ t_hslice, t_i8slice, t_i32slice, t_fillslice, t_c32slice, t_f64slice, /*25*/ t_comp, t_block, t_body, t_scope, t_scopeExt, t_blBlocks, - /*31*/ t_ns, t_nsDesc, t_fldAlias, t_hashmap, t_temp, t_nfn, t_nfnDesc, - /*38*/ t_freed, t_harrPartial, + /*31*/ t_ns, t_nsDesc, t_fldAlias, t_vfyObj, t_hashmap, t_temp, t_nfn, t_nfnDesc, + /*39*/ t_freed, t_harrPartial, #ifdef RT_WRAP - /*40*/ t_funWrap, t_md1Wrap, t_md2Wrap, + /*41*/ t_funWrap, t_md1Wrap, t_md2Wrap, #endif t_COUNT }; diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index 5f44560b..a27060ae 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -140,6 +140,11 @@ INS B i_FLDO(B ns, u32 p, Scope* sc) { dec(ns); return r; } +INS B i_VFYM(B o) { // TODO this and NSPM allocate and thus can error on OOM + VfyObj* a = mm_alloc(sizeof(VfyObj), t_vfyObj); + a->obj = o; + return tag(a,OBJ_TAG); +} INS B i_NSPM(B o, u32 l) { FldAlias* a = mm_alloc(sizeof(FldAlias), t_fldAlias); a->obj = o; @@ -530,8 +535,7 @@ Nvm_res m_nvm(Body* body) { NORES(1); break; case ADDI: TOPs; { u64 x = L64; IMM(R_RES, x); IMM(R_A3, v(b(x))); INCV(R_A3); break; } // (u64 v, S) - case ADDU: TOPs; IMM(R_RES, L64); - break; + case ADDU: TOPs; IMM(R_RES, L64); break; case FN1C: TOPp; GET(R_A1,1,1); IMM(R_A2,off); CCALL(i_FN1C); break; // ( B f, B x, u32* bc) case FN1O: TOPp; GET(R_A1,1,1); IMM(R_A2,off); CCALL(i_FN1O); break; // ( B f, B x, u32* bc) case FN2C: TOPp; GET(R_A1,1,0); GET(R_A2,2,1); IMM(R_A3,off); CCALL(i_FN2C); break; // (B w, B f, B x, u32* bc) @@ -569,13 +573,13 @@ Nvm_res m_nvm(Body* body) { LSC(R_A1,d); MOV8rmo(R_RES,R_A1,p*8+offsetof(Scope,vars)); // read variable IMM(R_A2, bi_optOut.u); MOV8mro(R_A1, R_A2,p*8+offsetof(Scope,vars)); // set to bi_optOut } break; - case EXTO: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); IMM(R_A2,off); INV(3,1,i_EXTO); } break; // (u32 p, Scope* sc, u32* bc, S) // case LOCU: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); CCALL(i_LOCU); } break; // (u32 p, Scope* sc) + case EXTO: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); IMM(R_A2,off); INV(3,1,i_EXTO); } break; // (u32 p, Scope* sc, u32* bc, S) case EXTU: TOPs; { u64 d=*bc++; IMM(R_A0,*bc++); LSC(R_A1,d); CCALL(i_EXTU); } break; // (u32 p, Scope* sc) - case SETN: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETN); break; // (B s, B x, Scope** pscs, u32* bc) - case SETU: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETU); break; // (B s, B x, Scope** pscs, u32* bc) + case SETN: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETN); break; // (B s, B x, Scope** pscs, u32* bc) + case SETU: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETU); break; // (B s, B x, Scope** pscs, u32* bc) case SETM: TOPp; GET(R_A1,1,1) GET(R_A2,2,1); LEAi(R_A3,R_SP,VAR(pscs,0)); IMM(R_A4,off); CCALL(i_SETM); break; // (B s, B f, B x, Scope** pscs, u32* bc) - case SETH: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETH); break; // (B s, B x, Scope** pscs, u32* bc) + case SETH: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETH); break; // (B s, B x, Scope** pscs, u32* bc) // TODO SETNi doesn't really need to update gStack case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNi); break; } // ( B x, Scope* sc, u32 p, u32* bc) case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUi); break; } // ( B x, Scope* sc, u32 p, u32* bc) @@ -585,10 +589,11 @@ Nvm_res m_nvm(Body* body) { case SETMv:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,1,1); LSC(R_A2,d); IMM(R_A3,p); IMM(R_A4,off); CCALL(i_SETMv); NORES(2); break; } // (B f, B x, Scope* sc, u32 p, u32* bc) case FLDO: TOPp; GET(R_A1,0,2); IMM(R_A1,*bc++); MOV(R_A2,r_SC); CCALL(i_FLDO); break; // (B, u32 p, Scope* sc) case NSPM: TOPp; IMM(R_A1,*bc++); CCALL(i_NSPM); break; // (B, u32 l) + case VFYM: TOPp; CCALL(i_VFYM); break; // (B) case CHKV: TOPp; IMM(R_A1,off); INV(2,0,i_CHKV); break; // (B, u32* bc, S) case RETD: if (lGPos) GS_SET(r_CS); MOV(R_A0,r_SC); CCALL(i_RETD); ret=true; break; // (Scope* sc) - case RETN: if (lGPos) GS_SET(r_CS); ret=true; break; - case FAIL: TOPs; IMM(R_A0,off); INV(1,0,i_FAIL); ret=true; break; + case RETN: if (lGPos) GS_SET(r_CS); ret=true; break; + case FAIL: TOPs; IMM(R_A0,off); INV(1,0,i_FAIL); ret=true; break; default: thrF("JIT: Unsupported bytecode %i/%S", *s, nameBC(s)); } #undef GET diff --git a/src/vm.c b/src/vm.c index 2dd01950..439eb524 100644 --- a/src/vm.c +++ b/src/vm.c @@ -60,8 +60,8 @@ i32 stackConsumed(u32* p) { if (*p==ARRO|*p==ARRM) return p[1]; switch(*p) { default: UD; // case ARRO: case ARRM: return -p[1]; case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 0; - case CHKV: case VFYM: case RETD: return 0; - case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: return 1; + case CHKV: case RETD: return 0; + case FN1Ci:case FN1Oi:case FLDO: case FLDM: case NSPM: case RETN: case POPS: case VFYM: return 1; case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case OP2H: case SETH: return 2; case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: return 3; @@ -444,7 +444,8 @@ NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) { } } NOINLINE bool v_sethR(Scope* pscs[], B s, B x) { - assert(!isExt(s)); + assert(isVal(s)); + if (v(s)->type==t_vfyObj) return equal(c(VfyObj,s)->obj,x); VTY(s, t_harr); B* sp = harr_ptr(s); usz ia = a(s)->ia; @@ -456,7 +457,7 @@ NOINLINE bool v_sethR(Scope* pscs[], B s, B x) { Scope* sc = pscs[(u16)(c.u>>32)]; i32 nameID = sc->body->varIDs[(u32)c.u]; if (!v_seth(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID))) return false; - } else if (isObj(c)) { + } else if (isObj(c) && v(c)->type==t_fldAlias) { assert(v(c)->type == t_fldAlias); Scope* sc = pscs[0]; FldAlias* cf = c(FldAlias,c); @@ -690,8 +691,14 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume if (q_N(PEEK(1))) { GS_UPD; POS_UPD; thrM("Unexpected Nothing (ยท)"); } break; } + case VFYM: { P(o) + VfyObj* a = mm_alloc(sizeof(VfyObj), t_vfyObj); + a->obj = o; + ADD(tag(a,OBJ_TAG)); + break; + } case FAIL: thrM("No body matched"); - // not implemented: VARO VARM VFYM SETH FLDM SYSV + // not implemented: VARO VARM FLDM SYSV default: #ifdef DEBUG printf("todo %d\n", bc[-1]); bc++; break; @@ -823,6 +830,7 @@ DEF_FREE(funBl) { FunBlock* c = (FunBlock*)x; ptr_dec(c->sc); ptr_decR(c->bl); } DEF_FREE(md1Bl) { Md1Block* c = (Md1Block*)x; ptr_dec(c->sc); ptr_decR(c->bl); } DEF_FREE(md2Bl) { Md2Block* c = (Md2Block*)x; ptr_dec(c->sc); ptr_decR(c->bl); } DEF_FREE(alias) { dec(((FldAlias*)x)->obj); } +DEF_FREE(vfymO) { dec(((VfyObj* )x)->obj); } DEF_FREE(bBlks) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (i32 i = 0; i < am; i++) ptr_dec(c->a[i]); } DEF_FREE(scExt) { ScopeExt* c = (ScopeExt*)x; u16 am = c->varAm*2; for (i32 i = 0; i < am; i++) dec(c->vars[i]); } @@ -855,6 +863,7 @@ void funBl_visit(Value* x) { FunBlock* c = (FunBlock*)x; mm_visitP(c->sc); mm_vi void md1Bl_visit(Value* x) { Md1Block* c = (Md1Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); } void md2Bl_visit(Value* x) { Md2Block* c = (Md2Block*)x; mm_visitP(c->sc); mm_visitP(c->bl); } void alias_visit(Value* x) { mm_visit(((FldAlias*)x)->obj); } +void vfymO_visit(Value* x) { mm_visit(((VfyObj* )x)->obj); } void bBlks_visit(Value* x) { BlBlocks* c = (BlBlocks*)x; u16 am = c->am; for (i32 i = 0; i < am; i++) mm_visitP(c->a[i]); } void scExt_visit(Value* x) { ScopeExt* c = (ScopeExt*)x; u16 am = c->varAm*2; for (i32 i = 0; i < am; i++) mm_visit(c->vars[i]); } @@ -863,6 +872,7 @@ void body_print (B x) { printf("(%p: body varam=%d)",v(x),c(Body,x)->varAm); } void block_print(B x) { printf("(%p: block)",v(x)); } void scope_print(B x) { printf("(%p: scope; vars:",v(x));Scope*sc=c(Scope,x);for(u64 i=0;ivarAm;i++){printf(" ");print(sc->vars[i]);}printf(")"); } void alias_print(B x) { printf("(alias %d of ", c(FldAlias,x)->p); print(c(FldAlias,x)->obj); printf(")"); } +void vfymO_print(B x) { print(c(FldAlias,x)->obj); } void bBlks_print(B x) { printf("(block list)"); } void scExt_print(B x) { printf("(scope extension with %d vars)", c(ScopeExt,x)->varAm); } @@ -907,6 +917,7 @@ void comp_init() { TIi(t_scopeExt ,freeO) = scExt_freeO; TIi(t_scopeExt ,freeF) = scExt_freeF; TIi(t_scopeExt ,visit) = scExt_visit; TIi(t_scopeExt ,print) = scExt_print; TIi(t_blBlocks ,freeO) = bBlks_freeO; TIi(t_blBlocks ,freeF) = bBlks_freeF; TIi(t_blBlocks ,visit) = bBlks_visit; TIi(t_blBlocks ,print) = bBlks_print; TIi(t_fldAlias ,freeO) = alias_freeO; TIi(t_fldAlias ,freeF) = alias_freeF; TIi(t_fldAlias ,visit) = alias_visit; TIi(t_fldAlias ,print) = alias_print; + TIi(t_vfyObj ,freeO) = vfymO_freeO; TIi(t_vfyObj ,freeF) = vfymO_freeF; TIi(t_vfyObj ,visit) = vfymO_visit; TIi(t_vfyObj ,print) = vfymO_print; TIi(t_fun_block,freeO) = funBl_freeO; TIi(t_fun_block,freeF) = funBl_freeF; TIi(t_fun_block,visit) = funBl_visit; TIi(t_fun_block,print) = funBl_print; TIi(t_fun_block,decompose) = block_decompose; TIi(t_md1_block,freeO) = md1Bl_freeO; TIi(t_md1_block,freeF) = md1Bl_freeF; TIi(t_md1_block,visit) = md1Bl_visit; TIi(t_md1_block,print) = md1Bl_print; TIi(t_md1_block,decompose) = block_decompose; TIi(t_md1_block,m1_d)=bl_m1d; TIi(t_md2_block,freeO) = md2Bl_freeO; TIi(t_md2_block,freeF) = md2Bl_freeF; TIi(t_md2_block,visit) = md2Bl_visit; TIi(t_md2_block,print) = md2Bl_print; TIi(t_md2_block,decompose) = block_decompose; TIi(t_md2_block,m2_d)=bl_m2d; diff --git a/src/vm.h b/src/vm.h index a4348506..58b094a9 100644 --- a/src/vm.h +++ b/src/vm.h @@ -202,6 +202,10 @@ typedef struct FldAlias { B obj; i32 p; } FldAlias; +typedef struct VfyObj { + struct Value; + B obj; +} VfyObj; NOINLINE B v_getR(Scope* pscs[], B s); // doesn't consume