diff --git a/src/jit/nvm_x86_64.c b/src/jit/nvm_x86_64.c index e6beb0c4..712dbdd6 100644 --- a/src/jit/nvm_x86_64.c +++ b/src/jit/nvm_x86_64.c @@ -16,7 +16,7 @@ // separate memory management system for executable code; isn't garbage-collected EmptyValue* mmX_buckets[64]; -u64* mmX_ctrs[64]; +u64 mmX_ctrs[64]; #define BSZ(X) (1ull<<(X)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull))) #define MMI(X) X diff --git a/src/jit/x86_64.h b/src/jit/x86_64.h index aa820e72..eb3a6d06 100644 --- a/src/jit/x86_64.h +++ b/src/jit/x86_64.h @@ -98,13 +98,13 @@ static inline void asm_1(TStack* o, i8 v) { static inline void asm_4(TStack* o, i32 v) { int size = o->size; // o->data[size+0] = (v ) & 0xff; o->data[size+1] = (v>> 8) & 0xff; // o->data[size+2] = (v>>16) & 0xff; o->data[size+3] = (v>>24) & 0xff; - *(u32*)(o->data+size) = v; // clang for whatever reason fails to optimize the above when it's inlined + memcpy(o->data+size, (i32[]){v}, 4); // slightly less UB than an unaligned move o->size = size+4; } -static inline void asm_8(TStack* o, i64 v) { int size = o->size; u8* p = o->data; - // p[size+0] = (u8)(v ); p[size+1] = (u8)(v>> 8); p[size+2] = (u8)(v>>16); p[size+3] = (u8)(v>>24); - // p[size+4] = (u8)(v>>32); p[size+5] = (u8)(v>>40); p[size+6] = (u8)(v>>48); p[size+7] = (u8)(v>>56); - *(u64*)(p+size) = v; +static inline void asm_8(TStack* o, i64 v) { int size = o->size; + // o->data[size+0] = (u8)(v ); o->data[size+1] = (u8)(v>> 8); o->data[size+2] = (u8)(v>>16); o->data[size+3] = (u8)(v>>24); + // o->data[size+4] = (u8)(v>>32); o->data[size+5] = (u8)(v>>40); o->data[size+6] = (u8)(v>>48); o->data[size+7] = (u8)(v>>56); + memcpy(o->data+size, (i64[]){v}, 8); o->size+= 8; } static inline void asm_a(TStack* o, u64 len, u8 v[]) { diff --git a/src/vm.c b/src/vm.c index 0bc8de69..ee6a2502 100644 --- a/src/vm.c +++ b/src/vm.c @@ -18,6 +18,7 @@ F(SETNi)F(SETUi)F(SETMi)F(SETNv)F(SETUv)F(SETMv)F(FAIL) u32* nextBC(u32* p) { + i32 off; switch(*p) { case FN1C: case FN2C: case FN1O: case FN2O: case OP1D: case OP2D: case OP2H: @@ -25,20 +26,21 @@ u32* nextBC(u32* p) { case SETN: case SETU: case SETM: case SETH: case POPS: case CHKV: case VFYM: case RETN: case RETD: case FAIL: - return p+1; + off = 1; break; case PUSH: case DFND: case ARRO: case ARRM: case VARO: case VARM: case FLDO: case FLDM: case SYSV: case NSPM: - return p+2; + off = 2; break; case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case ADDI: case ADDU: case FN1Ci: case FN1Oi: case FN2Ci: case SETNi: case SETUi: case SETMi: case SETNv: case SETUv: case SETMv: - return p+3; + off = 3; break; case FN2Oi: - return p+5; - default: return 0; + off = 5; break; + default: UD; } + return p+off; } i32 stackDiff(u32* p) { if (*p==ARRO|*p==ARRM) return 1-p[1]; @@ -133,7 +135,7 @@ static Body* m_body(i32 vam, i32 pos, u16 maxStack, u16 maxPSC) { // leaves varI #if JIT_START > 0 body->callCount = 0; #endif - body->bc = pos + (u32*)NULL; // hackish way to temporarily store the offset + body->bcTmp = pos; body->maxStack = maxStack; body->maxPSC = maxPSC; body->bl = NULL; @@ -345,7 +347,7 @@ Block* compileBlock(B block, Comp* comp, bool* bDone, u32* bc, usz bcIA, B allBl } for (i32 i = 0; i < bodyCount; i++) { bl->bodies[i] = bodies[i]; - bodies[i]->bc+= nbc-(i32*)NULL; + bodies[i]->bc = (u32*)nbc + bodies[i]->bcTmp; bodies[i]->bl = bl; } bl->dyBody = bodies[index2]; diff --git a/src/vm.h b/src/vm.h index 17890e1e..b29ad064 100644 --- a/src/vm.h +++ b/src/vm.h @@ -96,7 +96,7 @@ struct Body { #if JIT_START > 0 u16 callCount; #endif - u32* bc; // pointer in bl->bc + union { u32* bc; i32 bcTmp; }; // pointer in bl->bc; bcTmp to make ubsan happy (god dammit C) u32 maxStack; u16 maxPSC; #if JIT_START != -1