ref: a442a0418f06b673559c93a69e3167b4460d6d07
parent: 7e27931468a7c0f41b2c8a64c9cb6b069f47a5ac
author: Tor Andersson <tor.andersson@artifex.com>
date: Mon Jan 22 09:17:42 EST 2024
Issue #164: Use correct scope for function declaration bindings. TODO: Make binding for function expression names immutable!
--- a/jscompile.c
+++ b/jscompile.c
@@ -6,7 +6,7 @@
JS_NORETURN void jsC_error(js_State *J, js_Ast *node, const char *fmt, ...) JS_PRINTFLIKE(3,4);
-static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body);
+static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body, int is_fun_exp);
static void cexp(JF, js_Ast *exp);
static void cstmlist(JF, js_Ast *list);
static void cstm(JF, js_Ast *stm);
@@ -47,7 +47,7 @@
}
}
-static js_Function *newfun(js_State *J, int line, js_Ast *name, js_Ast *params, js_Ast *body, int script, int default_strict)
+static js_Function *newfun(js_State *J, int line, js_Ast *name, js_Ast *params, js_Ast *body, int script, int default_strict, int is_fun_exp)
{
js_Function *F = js_malloc(J, sizeof *F);
memset(F, 0, sizeof *F);
@@ -62,7 +62,7 @@
F->strict = default_strict;
F->name = name ? name->string : "";
- cfunbody(J, F, name, params, body);
+ cfunbody(J, F, name, params, body, is_fun_exp);
return F;
}
@@ -347,12 +347,12 @@
emit(J, F, OP_INITPROP);
break;
case EXP_PROP_GET:
- emitfunction(J, F, newfun(J, prop->line, NULL, NULL, kv->c, 0, F->strict));
+ emitfunction(J, F, newfun(J, prop->line, NULL, NULL, kv->c, 0, F->strict, 1));
emitline(J, F, kv);
emit(J, F, OP_INITGETTER);
break;
case EXP_PROP_SET:
- emitfunction(J, F, newfun(J, prop->line, NULL, kv->b, kv->c, 0, F->strict));
+ emitfunction(J, F, newfun(J, prop->line, NULL, kv->b, kv->c, 0, F->strict, 1));
emitline(J, F, kv);
emit(J, F, OP_INITSETTER);
break;
@@ -623,7 +623,7 @@
case EXP_FUN:
emitline(J, F, exp);
- emitfunction(J, F, newfun(J, exp->line, exp->a, exp->b, exp->c, 0, F->strict));
+ emitfunction(J, F, newfun(J, exp->line, exp->a, exp->b, exp->c, 0, F->strict, 1));
break;
case EXP_IDENTIFIER:
@@ -1361,7 +1361,7 @@
js_Ast *stm = list->a;
if (stm->type == AST_FUNDEC) {
emitline(J, F, stm);
- emitfunction(J, F, newfun(J, stm->line, stm->a, stm->b, stm->c, 0, F->strict));
+ emitfunction(J, F, newfun(J, stm->line, stm->a, stm->b, stm->c, 0, F->strict, 0));
emitline(J, F, stm);
emit(J, F, OP_SETLOCAL);
emitarg(J, F, addlocal(J, F, stm->a, 1));
@@ -1371,7 +1371,7 @@
}
}
-static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body)
+static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body, int is_fun_exp)
{
F->lightweight = 1;
F->arguments = 0;
@@ -1395,11 +1395,14 @@
if (name) {
checkfutureword(J, F, name);
- if (findlocal(J, F, name->string) < 0) {
- emit(J, F, OP_CURRENT);
- emit(J, F, OP_SETLOCAL);
- emitarg(J, F, addlocal(J, F, name, 1));
- emit(J, F, OP_POP);
+ if (is_fun_exp) {
+ if (findlocal(J, F, name->string) < 0) {
+ /* TODO: make this binding immutable! */
+ emit(J, F, OP_CURRENT);
+ emit(J, F, OP_SETLOCAL);
+ emitarg(J, F, addlocal(J, F, name, 1));
+ emit(J, F, OP_POP);
+ }
}
}
@@ -1416,10 +1419,10 @@
js_Function *jsC_compilefunction(js_State *J, js_Ast *prog)
{
- return newfun(J, prog->line, prog->a, prog->b, prog->c, 0, J->default_strict);
+ return newfun(J, prog->line, prog->a, prog->b, prog->c, 0, J->default_strict, 1);
}
js_Function *jsC_compilescript(js_State *J, js_Ast *prog, int default_strict)
{
- return newfun(J, prog ? prog->line : 0, NULL, NULL, prog, 1, default_strict);
+ return newfun(J, prog ? prog->line : 0, NULL, NULL, prog, 1, default_strict, 0);
}