mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-19 05:23:27 +00:00
Compare commits
9 Commits
f14556234c
...
84cb21ffaf
Author | SHA1 | Date | |
---|---|---|---|
![]() |
84cb21ffaf | ||
![]() |
4f2bb199fe | ||
![]() |
e3c70a7d81 | ||
![]() |
7db2d1b12a | ||
![]() |
e0551670c9 | ||
![]() |
85c3f2fb6f | ||
![]() |
eee16efa77 | ||
![]() |
4219efae43 | ||
![]() |
0254770582 |
@ -179,7 +179,7 @@ static const void *bcread_varinfo(GCproto *pt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read a single constant key/value of a template table. */
|
/* Read a single constant key/value of a template table. */
|
||||||
static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t)
|
static void bcread_ktabk(LexState *ls, TValue *o)
|
||||||
{
|
{
|
||||||
MSize tp = bcread_uleb128(ls);
|
MSize tp = bcread_uleb128(ls);
|
||||||
if (tp >= BCDUMP_KTAB_STR) {
|
if (tp >= BCDUMP_KTAB_STR) {
|
||||||
@ -191,8 +191,6 @@ static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t)
|
|||||||
} else if (tp == BCDUMP_KTAB_NUM) {
|
} else if (tp == BCDUMP_KTAB_NUM) {
|
||||||
o->u32.lo = bcread_uleb128(ls);
|
o->u32.lo = bcread_uleb128(ls);
|
||||||
o->u32.hi = bcread_uleb128(ls);
|
o->u32.hi = bcread_uleb128(ls);
|
||||||
} else if (tp == BCDUMP_KTAB_NIL) { /* Restore nil value marker. */
|
|
||||||
settabV(ls->L, o, t);
|
|
||||||
} else {
|
} else {
|
||||||
lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
|
lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
|
||||||
setpriV(o, ~tp);
|
setpriV(o, ~tp);
|
||||||
@ -209,15 +207,15 @@ static GCtab *bcread_ktab(LexState *ls)
|
|||||||
MSize i;
|
MSize i;
|
||||||
TValue *o = tvref(t->array);
|
TValue *o = tvref(t->array);
|
||||||
for (i = 0; i < narray; i++, o++)
|
for (i = 0; i < narray; i++, o++)
|
||||||
bcread_ktabk(ls, o, t);
|
bcread_ktabk(ls, o);
|
||||||
}
|
}
|
||||||
if (nhash) { /* Read hash entries. */
|
if (nhash) { /* Read hash entries. */
|
||||||
MSize i;
|
MSize i;
|
||||||
for (i = 0; i < nhash; i++) {
|
for (i = 0; i < nhash; i++) {
|
||||||
TValue key;
|
TValue key;
|
||||||
bcread_ktabk(ls, &key, t);
|
bcread_ktabk(ls, &key);
|
||||||
lj_assertLS(!tvisnil(&key), "nil key");
|
lj_assertLS(!tvisnil(&key), "nil key");
|
||||||
bcread_ktabk(ls, lj_tab_set(ls->L, t, &key), t);
|
bcread_ktabk(ls, lj_tab_set(ls->L, t, &key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
|
@ -71,8 +71,6 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
|
|||||||
*p++ = BCDUMP_KTAB_NUM;
|
*p++ = BCDUMP_KTAB_NUM;
|
||||||
p = lj_strfmt_wuleb128(p, o->u32.lo);
|
p = lj_strfmt_wuleb128(p, o->u32.lo);
|
||||||
p = lj_strfmt_wuleb128(p, o->u32.hi);
|
p = lj_strfmt_wuleb128(p, o->u32.hi);
|
||||||
} else if (tvistab(o)) { /* Write the nil value marker as a nil. */
|
|
||||||
*p++ = BCDUMP_KTAB_NIL;
|
|
||||||
} else {
|
} else {
|
||||||
lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
|
lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
|
||||||
*p++ = BCDUMP_KTAB_NIL+~itype(o);
|
*p++ = BCDUMP_KTAB_NIL+~itype(o);
|
||||||
@ -135,7 +133,7 @@ static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
|
|||||||
TValue **heap = ctx->heap;
|
TValue **heap = ctx->heap;
|
||||||
MSize i = nhash;
|
MSize i = nhash;
|
||||||
for (;; node--) { /* Build heap. */
|
for (;; node--) { /* Build heap. */
|
||||||
if (!tvisnil(&node->val)) {
|
if (!tvisnil(&node->key)) {
|
||||||
bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
|
bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
|
||||||
if (i == 0) break;
|
if (i == 0) break;
|
||||||
}
|
}
|
||||||
@ -165,7 +163,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
|
|||||||
MSize i, hmask = t->hmask;
|
MSize i, hmask = t->hmask;
|
||||||
Node *node = noderef(t->node);
|
Node *node = noderef(t->node);
|
||||||
for (i = 0; i <= hmask; i++)
|
for (i = 0; i <= hmask; i++)
|
||||||
nhash += !tvisnil(&node[i].val);
|
nhash += !tvisnil(&node[i].key);
|
||||||
}
|
}
|
||||||
/* Write number of array slots and hash slots. */
|
/* Write number of array slots and hash slots. */
|
||||||
p = lj_strfmt_wuleb128(p, narray);
|
p = lj_strfmt_wuleb128(p, narray);
|
||||||
|
@ -262,6 +262,14 @@ static void *callback_mcode_init(global_State *g, uint32_t *page)
|
|||||||
#define CCPROT_CREATE 0
|
#define CCPROT_CREATE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Check for macOS hardened runtime. */
|
||||||
|
#if defined(LUAJIT_ENABLE_OSX_HRT) && LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000
|
||||||
|
#include <pthread.h>
|
||||||
|
#define CCMAP_CREATE MAP_JIT
|
||||||
|
#else
|
||||||
|
#define CCMAP_CREATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate and initialize area for callback function pointers. */
|
/* Allocate and initialize area for callback function pointers. */
|
||||||
@ -276,10 +284,13 @@ static void callback_mcode_new(CTState *cts)
|
|||||||
if (!p)
|
if (!p)
|
||||||
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
|
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
|
||||||
#elif LJ_TARGET_POSIX
|
#elif LJ_TARGET_POSIX
|
||||||
p = mmap(NULL, sz, (PROT_READ|PROT_WRITE|CCPROT_CREATE), MAP_PRIVATE|MAP_ANONYMOUS,
|
p = mmap(NULL, sz, PROT_READ|PROT_WRITE|CCPROT_CREATE,
|
||||||
-1, 0);
|
MAP_PRIVATE|MAP_ANONYMOUS|CCMAP_CREATE, -1, 0);
|
||||||
if (p == MAP_FAILED)
|
if (p == MAP_FAILED)
|
||||||
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
|
lj_err_caller(cts->L, LJ_ERR_FFI_CBACKOV);
|
||||||
|
#if CCMAP_CREATE
|
||||||
|
pthread_jit_write_protect_np(0);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
/* Fallback allocator. Fails if memory is not executable by default. */
|
/* Fallback allocator. Fails if memory is not executable by default. */
|
||||||
p = lj_mem_new(cts->L, sz);
|
p = lj_mem_new(cts->L, sz);
|
||||||
@ -296,8 +307,12 @@ static void callback_mcode_new(CTState *cts)
|
|||||||
LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot);
|
LJ_WIN_VPROTECT(p, sz, PAGE_EXECUTE_READ, &oprot);
|
||||||
}
|
}
|
||||||
#elif LJ_TARGET_POSIX
|
#elif LJ_TARGET_POSIX
|
||||||
|
#if CCMAP_CREATE
|
||||||
|
pthread_jit_write_protect_np(1);
|
||||||
|
#else
|
||||||
mprotect(p, sz, (PROT_READ|PROT_EXEC));
|
mprotect(p, sz, (PROT_READ|PROT_EXEC));
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free area for callback function pointers. */
|
/* Free area for callback function pointers. */
|
||||||
|
@ -98,21 +98,35 @@ static int mcode_setprot(void *p, size_t sz, DWORD prot)
|
|||||||
#define MAP_ANONYMOUS MAP_ANON
|
#define MAP_ANONYMOUS MAP_ANON
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Check for macOS hardened runtime. */
|
||||||
|
#if defined(LUAJIT_ENABLE_OSX_HRT) && LUAJIT_SECURITY_MCODE != 0 && defined(MAP_JIT) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000
|
||||||
|
#include <pthread.h>
|
||||||
|
#define MCMAP_CREATE MAP_JIT
|
||||||
|
#else
|
||||||
|
#define MCMAP_CREATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MCPROT_RW (PROT_READ|PROT_WRITE)
|
#define MCPROT_RW (PROT_READ|PROT_WRITE)
|
||||||
#define MCPROT_RX (PROT_READ|PROT_EXEC)
|
#define MCPROT_RX (PROT_READ|PROT_EXEC)
|
||||||
#define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
|
#define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
|
||||||
#ifdef PROT_MPROTECT
|
#ifdef PROT_MPROTECT
|
||||||
#define MCPROT_CREATE (PROT_MPROTECT(MCPROT_RWX))
|
#define MCPROT_CREATE (PROT_MPROTECT(MCPROT_RWX))
|
||||||
|
#elif MCMAP_CREATE
|
||||||
|
#define MCPROT_CREATE PROT_EXEC
|
||||||
#else
|
#else
|
||||||
#define MCPROT_CREATE 0
|
#define MCPROT_CREATE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot)
|
static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot)
|
||||||
{
|
{
|
||||||
void *p = mmap((void *)hint, sz, prot|MCPROT_CREATE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
void *p = mmap((void *)hint, sz, prot|MCPROT_CREATE, MAP_PRIVATE|MAP_ANONYMOUS|MCMAP_CREATE, -1, 0);
|
||||||
if (p == MAP_FAILED) {
|
if (p == MAP_FAILED) {
|
||||||
if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL);
|
if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL);
|
||||||
p = NULL;
|
p = NULL;
|
||||||
|
#if MCMAP_CREATE
|
||||||
|
} else {
|
||||||
|
pthread_jit_write_protect_np(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -125,7 +139,12 @@ static void mcode_free(jit_State *J, void *p, size_t sz)
|
|||||||
|
|
||||||
static int mcode_setprot(void *p, size_t sz, int prot)
|
static int mcode_setprot(void *p, size_t sz, int prot)
|
||||||
{
|
{
|
||||||
|
#if MCMAP_CREATE
|
||||||
|
pthread_jit_write_protect_np((prot & PROT_EXEC));
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return mprotect(p, sz, prot);
|
return mprotect(p, sz, prot);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -2217,11 +2217,9 @@ LJFOLD(HREF TDUP KNUM)
|
|||||||
LJFOLDF(fwd_href_tdup)
|
LJFOLDF(fwd_href_tdup)
|
||||||
{
|
{
|
||||||
TValue keyv;
|
TValue keyv;
|
||||||
cTValue *val;
|
|
||||||
lj_ir_kvalue(J->L, &keyv, fright);
|
lj_ir_kvalue(J->L, &keyv, fright);
|
||||||
val = lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv);
|
if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
|
||||||
/* Check for either nil or the nil value marker in the template table. */
|
lj_opt_fwd_href_nokey(J))
|
||||||
if ((tvisnil(val) || tvistab(val)) && lj_opt_fwd_href_nokey(J))
|
|
||||||
return lj_ir_kkptr(J, niltvg(J2G(J)));
|
return lj_ir_kkptr(J, niltvg(J2G(J)));
|
||||||
return NEXTFOLD;
|
return NEXTFOLD;
|
||||||
}
|
}
|
||||||
|
@ -233,9 +233,7 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
|
|||||||
return lj_ir_knum_u64(J, tv->u64);
|
return lj_ir_knum_u64(J, tv->u64);
|
||||||
else if (tvisint(tv))
|
else if (tvisint(tv))
|
||||||
return lj_ir_kint(J, intV(tv));
|
return lj_ir_kint(J, intV(tv));
|
||||||
else if (tvistab(tv)) /* Template table nil value marker. */
|
else if (tvisgcv(tv))
|
||||||
return TREF_NIL;
|
|
||||||
else if (tvisstr(tv))
|
|
||||||
return lj_ir_kstr(J, strV(tv));
|
return lj_ir_kstr(J, strV(tv));
|
||||||
}
|
}
|
||||||
/* Othwerwise: don't intern as a constant. */
|
/* Othwerwise: don't intern as a constant. */
|
||||||
|
@ -1725,7 +1725,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
|||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
BCLine line = ls->linenumber;
|
BCLine line = ls->linenumber;
|
||||||
GCtab *t = NULL;
|
GCtab *t = NULL;
|
||||||
int vcall = 0, needarr = 0;
|
int vcall = 0, needarr = 0, fixt = 0;
|
||||||
uint32_t narr = 1; /* First array index. */
|
uint32_t narr = 1; /* First array index. */
|
||||||
uint32_t nhash = 0; /* Number of hash entries. */
|
uint32_t nhash = 0; /* Number of hash entries. */
|
||||||
BCReg freg = fs->freereg;
|
BCReg freg = fs->freereg;
|
||||||
@ -1769,10 +1769,9 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
|||||||
lj_gc_anybarriert(fs->L, t);
|
lj_gc_anybarriert(fs->L, t);
|
||||||
if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
|
if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
|
||||||
expr_kvalue(fs, v, &val);
|
expr_kvalue(fs, v, &val);
|
||||||
/* Mark nil value with table value itself to preserve the key. */
|
} else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */
|
||||||
if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t);
|
settabV(fs->L, v, t); /* Preserve key with table itself as value. */
|
||||||
} else { /* Preserve the key for the following non-const store. */
|
fixt = 1; /* Fix this later, after all resizes. */
|
||||||
settabV(fs->L, v, t);
|
|
||||||
goto nonconst;
|
goto nonconst;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1814,6 +1813,17 @@ static void expr_table(LexState *ls, ExpDesc *e)
|
|||||||
} else {
|
} else {
|
||||||
if (needarr && t->asize < narr)
|
if (needarr && t->asize < narr)
|
||||||
lj_tab_reasize(fs->L, t, narr-1);
|
lj_tab_reasize(fs->L, t, narr-1);
|
||||||
|
if (fixt) { /* Fix value for dummy keys in template table. */
|
||||||
|
Node *node = noderef(t->node);
|
||||||
|
uint32_t i, hmask = t->hmask;
|
||||||
|
for (i = 0; i <= hmask; i++) {
|
||||||
|
Node *n = &node[i];
|
||||||
|
if (tvistab(&n->val)) {
|
||||||
|
lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table");
|
||||||
|
setnilV(&n->val); /* Turn value into nil. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lj_gc_check(fs->L);
|
lj_gc_check(fs->L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2079,6 +2079,7 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
|||||||
/* -- Concatenation ------------------------------------------------------- */
|
/* -- Concatenation ------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct RecCatDataCP {
|
typedef struct RecCatDataCP {
|
||||||
|
TValue savetv[5+LJ_FR2];
|
||||||
jit_State *J;
|
jit_State *J;
|
||||||
BCReg baseslot, topslot;
|
BCReg baseslot, topslot;
|
||||||
TRef tr;
|
TRef tr;
|
||||||
@ -2119,7 +2120,9 @@ static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Pass partial result. */
|
/* Pass partial result. */
|
||||||
topslot = J->maxslot--;
|
rcd->topslot = topslot = J->maxslot--;
|
||||||
|
/* Save updated range of slots. */
|
||||||
|
memcpy(rcd->savetv, &L->base[topslot-1], sizeof(rcd->savetv));
|
||||||
*xbase = tr;
|
*xbase = tr;
|
||||||
top = xbase;
|
top = xbase;
|
||||||
setstrV(J->L, &ix.keyv, &J2G(J)->strempty); /* Simulate string result. */
|
setstrV(J->L, &ix.keyv, &J2G(J)->strempty); /* Simulate string result. */
|
||||||
@ -2139,16 +2142,18 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|||||||
{
|
{
|
||||||
lua_State *L = J->L;
|
lua_State *L = J->L;
|
||||||
ptrdiff_t delta = L->top - L->base;
|
ptrdiff_t delta = L->top - L->base;
|
||||||
TValue savetv[5+LJ_FR2], errobj;
|
TValue errobj;
|
||||||
RecCatDataCP rcd;
|
RecCatDataCP rcd;
|
||||||
int errcode;
|
int errcode;
|
||||||
rcd.J = J;
|
rcd.J = J;
|
||||||
rcd.baseslot = baseslot;
|
rcd.baseslot = baseslot;
|
||||||
rcd.topslot = topslot;
|
rcd.topslot = topslot;
|
||||||
memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
/* Save slots. */
|
||||||
|
memcpy(rcd.savetv, &L->base[topslot-1], sizeof(rcd.savetv));
|
||||||
errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
||||||
if (errcode) copyTV(L, &errobj, L->top-1);
|
if (errcode) copyTV(L, &errobj, L->top-1);
|
||||||
memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
/* Restore slots. */
|
||||||
|
memcpy(&L->base[rcd.topslot-1], rcd.savetv, sizeof(rcd.savetv));
|
||||||
if (errcode) {
|
if (errcode) {
|
||||||
L->top = L->base + delta;
|
L->top = L->base + delta;
|
||||||
copyTV(L, L->top++, &errobj);
|
copyTV(L, L->top++, &errobj);
|
||||||
|
@ -194,7 +194,6 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
|
|||||||
Node *next = nextnode(kn);
|
Node *next = nextnode(kn);
|
||||||
/* Don't use copyTV here, since it asserts on a copy of a dead key. */
|
/* Don't use copyTV here, since it asserts on a copy of a dead key. */
|
||||||
n->val = kn->val; n->key = kn->key;
|
n->val = kn->val; n->key = kn->key;
|
||||||
if (tvistab(&n->val)) setnilV(&n->val); /* Replace nil value marker. */
|
|
||||||
setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
|
setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,14 +222,6 @@ static void trace_unpatch(jit_State *J, GCtrace *T)
|
|||||||
bc_isret(op), "bad original bytecode %d", op);
|
bc_isret(op), "bad original bytecode %d", op);
|
||||||
*pc = T->startins;
|
*pc = T->startins;
|
||||||
break;
|
break;
|
||||||
case BC_JMP:
|
|
||||||
lj_assertJ(op == BC_ITERL, "bad original bytecode %d", op);
|
|
||||||
pc += bc_j(*pc)+2;
|
|
||||||
if (bc_op(*pc) == BC_JITERL) {
|
|
||||||
lj_assertJ(traceref(J, bc_d(*pc)) == T, "JITERL references other trace");
|
|
||||||
*pc = T->startins;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case BC_JFUNCF:
|
case BC_JFUNCF:
|
||||||
lj_assertJ(op == BC_FUNCF, "bad original bytecode %d", op);
|
lj_assertJ(op == BC_FUNCF, "bad original bytecode %d", op);
|
||||||
*pc = T->startins;
|
*pc = T->startins;
|
||||||
@ -245,18 +237,19 @@ static void trace_flushroot(jit_State *J, GCtrace *T)
|
|||||||
GCproto *pt = &gcref(T->startpt)->pt;
|
GCproto *pt = &gcref(T->startpt)->pt;
|
||||||
lj_assertJ(T->root == 0, "not a root trace");
|
lj_assertJ(T->root == 0, "not a root trace");
|
||||||
lj_assertJ(pt != NULL, "trace has no prototype");
|
lj_assertJ(pt != NULL, "trace has no prototype");
|
||||||
/* First unpatch any modified bytecode. */
|
|
||||||
trace_unpatch(J, T);
|
|
||||||
/* Unlink root trace from chain anchored in prototype. */
|
/* Unlink root trace from chain anchored in prototype. */
|
||||||
if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
|
if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */
|
||||||
pt->trace = T->nextroot;
|
pt->trace = T->nextroot;
|
||||||
|
unpatch:
|
||||||
|
/* Unpatch modified bytecode only if the trace has not been flushed. */
|
||||||
|
trace_unpatch(J, T);
|
||||||
} else if (pt->trace) { /* Otherwise search in chain of root traces. */
|
} else if (pt->trace) { /* Otherwise search in chain of root traces. */
|
||||||
GCtrace *T2 = traceref(J, pt->trace);
|
GCtrace *T2 = traceref(J, pt->trace);
|
||||||
if (T2) {
|
if (T2) {
|
||||||
for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
|
for (; T2->nextroot; T2 = traceref(J, T2->nextroot))
|
||||||
if (T2->nextroot == T->traceno) {
|
if (T2->nextroot == T->traceno) {
|
||||||
T2->nextroot = T->nextroot; /* Unlink from chain. */
|
T2->nextroot = T->nextroot; /* Unlink from chain. */
|
||||||
break;
|
goto unpatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
@rem nogc64 disable LJ_GC64 mode for x64
|
@rem nogc64 disable LJ_GC64 mode for x64
|
||||||
@rem debug emit debug symbols
|
@rem debug emit debug symbols
|
||||||
@rem amalg amalgamated build
|
@rem amalg amalgamated build
|
||||||
@rem static static linkage
|
@rem static create static lib to statically link into your project
|
||||||
|
@rem mixed create static lib to build a DLL in your project
|
||||||
|
|
||||||
@if not defined INCLUDE goto :FAIL
|
@if not defined INCLUDE goto :FAIL
|
||||||
|
|
||||||
@ -106,12 +107,14 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
|||||||
@if "%1"=="static" goto :STATIC
|
@if "%1"=="static" goto :STATIC
|
||||||
%LJCOMPILE% %LJDYNBUILD% lj_*.c lib_*.c
|
%LJCOMPILE% %LJDYNBUILD% lj_*.c lib_*.c
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
|
@if "%1"=="mixed" goto :STATICLIB
|
||||||
%LJLINK% /DLL /OUT:%LJDLLNAME% lj_*.obj lib_*.obj
|
%LJLINK% /DLL /OUT:%LJDLLNAME% lj_*.obj lib_*.obj
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
@goto :MTDLL
|
@goto :MTDLL
|
||||||
:STATIC
|
:STATIC
|
||||||
%LJCOMPILE% lj_*.c lib_*.c
|
%LJCOMPILE% lj_*.c lib_*.c
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
|
:STATICLIB
|
||||||
%LJLIB% /OUT:%LJLIBNAME% lj_*.obj lib_*.obj
|
%LJLIB% /OUT:%LJLIBNAME% lj_*.obj lib_*.obj
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
@goto :MTDLL
|
@goto :MTDLL
|
||||||
@ -119,13 +122,15 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
|
|||||||
@if "%2"=="static" goto :AMALGSTATIC
|
@if "%2"=="static" goto :AMALGSTATIC
|
||||||
%LJCOMPILE% %LJDYNBUILD% ljamalg.c
|
%LJCOMPILE% %LJDYNBUILD% ljamalg.c
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
|
@if "%2"=="mixed" goto :AMALGSTATICLIB
|
||||||
%LJLINK% /DLL /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
%LJLINK% /DLL /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
@goto :MTDLL
|
@goto :MTDLL
|
||||||
:AMALGSTATIC
|
:AMALGSTATIC
|
||||||
%LJCOMPILE% ljamalg.c
|
%LJCOMPILE% ljamalg.c
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
%LJLINK% /OUT:%LJDLLNAME% ljamalg.obj lj_vm.obj
|
:AMALGSTATICLIB
|
||||||
|
%LJLIB% /OUT:%LJLIBNAME% ljamalg.obj lj_vm.obj
|
||||||
@if errorlevel 1 goto :BAD
|
@if errorlevel 1 goto :BAD
|
||||||
:MTDLL
|
:MTDLL
|
||||||
if exist %LJDLLNAME%.manifest^
|
if exist %LJDLLNAME%.manifest^
|
||||||
|
Loading…
Reference in New Issue
Block a user