shithub: libmujs

Download patch

ref: 2d28162c2fd40588cde6b2fd62517fe25e7baffb
parent: 3585abad419a5eb53ebb58d6c37bbeeff44ce65e
author: Tor Andersson <[email protected]>
date: Mon Feb 24 07:03:59 EST 2014

typeof X when X in not declared should return undefined rather than throw.

--- a/jscompile.c
+++ b/jscompile.c
@@ -199,6 +199,15 @@
 
 /* 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 @@
 		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;
--- a/jscompile.h
+++ b/jscompile.h
@@ -42,6 +42,7 @@
 
 	OP_INITVAR,	/* <value> -S- */
 	OP_DEFVAR,	/* -S- */
+	OP_HASVAR,	/* -S- ( <value> | undefined ) */
 	OP_GETVAR,	/* -S- <value> */
 	OP_SETVAR,	/* <value> -S- <value> */
 	OP_DELVAR,	/* -S- <success> */
--- a/jsrun.c
+++ b/jsrun.c
@@ -702,7 +702,7 @@
 	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 @@
 			} 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 @@
 			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:
--- a/opnames.h
+++ b/opnames.h
@@ -30,6 +30,7 @@
 "dellocal",
 "initvar",
 "defvar",
+"hasvar",
 "getvar",
 "setvar",
 "delvar",