fix parser

This commit is contained in:
2026-02-03 18:24:06 -06:00
parent dc3c474b3a
commit 04c569eab1

View File

@@ -5112,21 +5112,23 @@ static int JS_CheckDefineGlobalVar (JSContext *ctx, JSValue prop, int flags) {
Currently safe because rec_resize always fails.
def_flags is (0, DEFINE_GLOBAL_LEX_VAR) */
static int JS_DefineGlobalVar (JSContext *ctx, JSValue prop, int def_flags) {
JSRecord *rec;
JSValue *pobj;
JSValue val;
JSRecord *rec;
int slot;
if (def_flags & DEFINE_GLOBAL_LEX_VAR) {
rec = (JSRecord *)JS_VALUE_GET_OBJ (ctx->global_var_obj);
pobj = &ctx->global_var_obj;
val = JS_UNINITIALIZED;
} else {
rec = (JSRecord *)JS_VALUE_GET_OBJ (ctx->global_obj);
pobj = &ctx->global_obj;
val = JS_NULL;
}
rec = (JSRecord *)JS_VALUE_GET_OBJ (*pobj);
slot = rec_find_slot (rec, prop);
if (slot > 0) return 0; /* already defined */
if (obj_is_stone (rec)) return 0;
return rec_set_own (ctx, rec, prop, val);
return rec_set_own (ctx, pobj, prop, val);
}
/* Simplified global function definition */
@@ -7512,91 +7514,59 @@ restart:
BREAK;
CASE (OP_check_var) : {
int ret;
JSValue key;
key = b->cpool[get_u32 (pc)];
/* Global object is immutable - linker should have resolved or removed this */
pc += 4;
sf->cur_pc = pc;
ret = JS_CheckGlobalVar (ctx, key);
if (ret < 0) goto exception;
*sp++ = JS_NewBool (ctx, ret);
JS_ThrowInternalError (ctx, "OP_check_var: linker should have resolved this");
goto exception;
}
BREAK;
CASE (OP_get_var_undef) : CASE (OP_get_var) : {
JSValue val;
JSValue key;
key = b->cpool[get_u32 (pc)];
/* Global object is immutable - linker should have resolved this */
pc += 4;
sf->cur_pc = pc;
val = JS_GetGlobalVar (ctx, key, opcode - OP_get_var_undef);
if (unlikely (JS_IsException (val))) goto exception;
*sp++ = val;
JS_ThrowInternalError (ctx, "OP_get_var: linker should have resolved to get_global_slot");
goto exception;
}
BREAK;
CASE (OP_put_var) : CASE (OP_put_var_init) : {
int ret;
JSValue key;
key = b->cpool[get_u32 (pc)];
/* Global object is immutable - linker should have resolved this */
pc += 4;
sf->cur_pc = pc;
ret = JS_SetGlobalVar (ctx, key, sp[-1], opcode - OP_put_var);
sp--;
if (unlikely (ret < 0)) goto exception;
JS_ThrowInternalError (ctx, "OP_put_var: global object is immutable, linker should resolve");
goto exception;
}
BREAK;
CASE (OP_put_var_strict) : {
int ret;
JSValue key;
key = b->cpool[get_u32 (pc)];
/* Global object is immutable - linker should have resolved this */
pc += 4;
sf->cur_pc = pc;
/* sp[-2] is JS_TRUE or JS_FALSE */
if (unlikely (!JS_VALUE_GET_INT (sp[-2]))) {
JS_ThrowReferenceErrorNotDefined (ctx, key);
goto exception;
}
ret = JS_SetGlobalVar (ctx, key, sp[-1], 2);
sp -= 2;
if (unlikely (ret < 0)) goto exception;
JS_ThrowInternalError (ctx, "OP_put_var_strict: global object is immutable, linker should resolve");
goto exception;
}
BREAK;
CASE (OP_check_define_var) : {
JSValue key;
int flags;
key = b->cpool[get_u32 (pc)];
flags = pc[4];
/* Global object is immutable - this opcode should not be emitted */
pc += 5;
sf->cur_pc = pc;
if (JS_CheckDefineGlobalVar (ctx, key, flags)) goto exception;
JS_ThrowInternalError (ctx, "OP_check_define_var: global object is immutable");
goto exception;
}
BREAK;
CASE (OP_define_var) : {
JSValue key;
int flags;
key = b->cpool[get_u32 (pc)];
flags = pc[4];
/* Global object is immutable - this opcode should not be emitted */
pc += 5;
sf->cur_pc = pc;
if (JS_DefineGlobalVar (ctx, key, flags)) goto exception;
JS_ThrowInternalError (ctx, "OP_define_var: global object is immutable");
goto exception;
}
BREAK;
CASE (OP_define_func) : {
JSValue key;
int flags;
key = b->cpool[get_u32 (pc)];
flags = pc[4];
/* Global object is immutable - this opcode should not be emitted */
pc += 5;
sf->cur_pc = pc;
if (JS_DefineGlobalFunction (ctx, key, sp[-1], flags)) goto exception;
sp--;
JS_ThrowInternalError (ctx, "OP_define_func: global object is immutable");
goto exception;
}
BREAK;
@@ -8127,8 +8097,7 @@ restart:
}
/* Record property set - use JSValue key directly */
JSRecord *rec = JS_VALUE_GET_RECORD (sp[-2]);
ret = rec_set_own (ctx, rec, key, sp[-1]);
ret = rec_set_own (ctx, &sp[-2], key, sp[-1]);
sp -= 2;
if (unlikely (ret < 0)) goto exception;
}
@@ -8153,8 +8122,7 @@ restart:
}
/* Record property set - use JSValue key directly */
JSRecord *rec = JS_VALUE_GET_RECORD (sp[-2]);
ret = rec_set_own (ctx, rec, key, sp[-1]);
ret = rec_set_own (ctx, &sp[-2], key, sp[-1]);
sp--;
if (unlikely (ret < 0)) goto exception;
}
@@ -8906,16 +8874,10 @@ restart:
sp--;
BREAK;
CASE (OP_delete_var) : {
JSValue key;
int ret;
key = b->cpool[get_u32 (pc)];
/* Global object is immutable - cannot delete globals */
pc += 4;
sf->cur_pc = pc;
ret = JS_DeleteGlobalVar (ctx, key);
if (unlikely (ret < 0)) goto exception;
*sp++ = JS_NewBool (ctx, ret);
JS_ThrowInternalError (ctx, "OP_delete_var: global object is immutable");
goto exception;
}
BREAK;
@@ -10219,18 +10181,51 @@ static int js_keyword_lookup (JSValue str, BOOL *is_strict_reserved) {
}
buf[len] = '\0';
cstr = buf;
} else if (JS_IsPtr (str)) {
/* Handle heap strings (JSText) - keywords like "function" are 8 chars */
JSText *text = (JSText *)JS_VALUE_GET_PTR (str);
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: JS_IsPtr branch, ptr=%p, hdr_type=%d\n", (void*)text, objhdr_type(text->hdr));
#endif
if (objhdr_type (text->hdr) != OBJ_TEXT) return -1;
len = JSText_len (text);
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: text len=%zu\n", len);
#endif
if (len >= sizeof (buf)) return -1;
for (size_t i = 0; i < len; i++) {
uint32_t c = string_get (text, i);
if (c >= 128) return -1; /* Keywords are ASCII only */
buf[i] = (char)c;
}
buf[len] = '\0';
cstr = buf;
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: extracted string='%s' len=%zu\n", cstr, len);
#endif
} else {
/* heap strings longer than immediate can't be keywords */
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: unknown str type, tag=%llx\n", (unsigned long long)(str & 0xFF));
#endif
return -1;
}
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: looking up '%s' in %zu keywords\n", cstr, (size_t)JS_KEYWORD_COUNT);
#endif
for (size_t i = 0; i < JS_KEYWORD_COUNT; i++) {
if (strcmp (cstr, js_keywords[i].name) == 0) {
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: matched keyword '%s' -> token %d\n", js_keywords[i].name, js_keywords[i].token);
#endif
if (is_strict_reserved)
*is_strict_reserved = js_keywords[i].is_strict_reserved;
return js_keywords[i].token;
}
}
#ifdef PRINT_LEXER
fprintf(stderr, "DEBUG: no keyword match for '%s'\n", cstr);
#endif
return -1;
}
@@ -10239,7 +10234,7 @@ static void update_token_ident (JSParseState *s) {
BOOL is_strict_reserved = FALSE;
int token = js_keyword_lookup (s->token.u.ident.str, &is_strict_reserved);
if (token >= 0) {
if (token != -1) {
if (s->token.u.ident.has_escape) {
/* identifiers with escape sequences stay identifiers */
s->token.u.ident.is_reserved = TRUE;
@@ -11672,15 +11667,8 @@ static int define_var (JSParseState *s, JSFunctionDef *fd, JSValue name, JSVarDe
}
}
if (fd->is_eval && fd->eval_type == JS_EVAL_TYPE_GLOBAL
&& fd->scope_level == fd->body_scope) {
JSGlobalVar *hf;
hf = add_global_var (s->ctx, fd, name);
if (!hf) return -1;
hf->is_lexical = TRUE;
hf->is_const = (var_def_type == JS_VAR_DEF_CONST);
idx = GLOBAL_VAR_OFFSET;
} else {
/* Global object is immutable - always use local variables */
{
JSVarKindEnum var_kind;
if (var_def_type == JS_VAR_DEF_FUNCTION_DECL)
var_kind = JS_VAR_FUNCTION_DECL;
@@ -18132,7 +18120,8 @@ static __exception int js_parse_program (JSParseState *s) {
if (js_parse_directives (s)) return -1;
fd->is_global_var = fd->eval_type == JS_EVAL_TYPE_GLOBAL;
/* Global object is immutable - all variables are locals of the eval function */
fd->is_global_var = FALSE;
/* hidden variable for the return value */
fd->eval_ret_idx = idx = add_var (s->ctx, fd, JS_KEY__ret_);