diff --git a/jscompile.c b/jscompile.c index 3d0110a..de99313 100644 --- a/jscompile.c +++ b/jscompile.c @@ -199,6 +199,15 @@ static void labelto(JF, int inst, int addr) /* Expressions */ +static void ctypeof(JF, js_Ast *exp) +{ + if (exp->type == EXP_IDENTIFIER) + emitlocal(J, F, OP_GETLOCAL, OP_HASVAR, exp->string); + else + cexp(J, F, exp); + emit(J, F, OP_TYPEOF); +} + static void cunary(JF, js_Ast *exp, int opcode) { cexp(J, F, exp->a); @@ -525,7 +534,7 @@ static void cexp(JF, js_Ast *exp) emit(J, F, OP_UNDEF); break; - case EXP_TYPEOF: cunary(J, F, exp, OP_TYPEOF); break; + case EXP_TYPEOF: ctypeof(J, F, exp->a); break; case EXP_POS: cunary(J, F, exp, OP_POS); break; case EXP_NEG: cunary(J, F, exp, OP_NEG); break; case EXP_BITNOT: cunary(J, F, exp, OP_BITNOT); break; diff --git a/jscompile.h b/jscompile.h index 449e4ba..e1f41d8 100644 --- a/jscompile.h +++ b/jscompile.h @@ -42,6 +42,7 @@ enum js_OpCode OP_INITVAR, /* -S- */ OP_DEFVAR, /* -S- */ + OP_HASVAR, /* -S- ( | undefined ) */ OP_GETVAR, /* -S- */ OP_SETVAR, /* -S- */ OP_DELVAR, /* -S- */ diff --git a/jsrun.c b/jsrun.c index ad3bd89..cdb6673 100644 --- a/jsrun.c +++ b/jsrun.c @@ -702,7 +702,7 @@ static void js_defvar(js_State *J, const char *name) jsR_defproperty(J, J->E->variables, name, JS_DONTENUM | JS_DONTCONF, NULL, NULL, NULL); } -static void js_getvar(js_State *J, const char *name) +static int js_hasvar(js_State *J, const char *name) { js_Environment *E = J->E; do { @@ -715,11 +715,11 @@ static void js_getvar(js_State *J, const char *name) } else { js_pushvalue(J, ref->value); } - return; + return 1; } E = E->outer; } while (E); - js_referenceerror(J, "%s is not defined", name); + return 0; } static void js_setvar(js_State *J, const char *name) @@ -1075,7 +1075,14 @@ static void jsR_run(js_State *J, js_Function *F) break; case OP_GETVAR: - js_getvar(J, ST[*pc++]); + str = ST[*pc++]; + if (!js_hasvar(J, str)) + js_referenceerror(J, "%s is not defined", str); + break; + + case OP_HASVAR: + if (!js_hasvar(J, ST[*pc++])) + js_pushundefined(J); break; case OP_SETVAR: diff --git a/opnames.h b/opnames.h index cce47e9..b45f5bb 100644 --- a/opnames.h +++ b/opnames.h @@ -30,6 +30,7 @@ "dellocal", "initvar", "defvar", +"hasvar", "getvar", "setvar", "delvar",