shithub: libmujs

Download patch

ref: 75cab70afd12dfe404f863448b5726c62c15f3f3
parent: 9e9f168cbb71002806e760f270a1e783210aa9b1
author: Tor Andersson <tor.andersson@gmail.com>
date: Mon Apr 17 09:03:06 EDT 2017

Handle undefined this at the OP_THIS level.

Don't distinguish lax mode code by pushing the global object.
Always push undefined and let the calling code promote an undefined
this to the global object instead.

--- a/jsarray.c
+++ b/jsarray.c
@@ -265,7 +265,7 @@
 
 		if (hasfn) {
 			js_copy(J, 1); /* copy function */
-			js_pushundefinedthis(J); /* set this object */
+			js_pushundefined(J); /* set this object */
 			js_copy(J, -4); /* copy x */
 			js_copy(J, -4); /* copy y */
 			js_call(J, 2);
--- a/jscompile.c
+++ b/jscompile.c
@@ -517,7 +517,7 @@
 		/* fall through */
 	default:
 		cexp(J, F, fun);
-		emit(J, F, J->strict ? OP_UNDEF : OP_GLOBAL);
+		emit(J, F, OP_UNDEF);
 		break;
 	}
 	n = cargs(J, F, args);
--- a/jscompile.h
+++ b/jscompile.h
@@ -29,7 +29,6 @@
 	OP_FALSE,
 
 	OP_THIS,
-	OP_GLOBAL,
 	OP_CURRENT,	/* currently executing function object */
 
 	OP_INITLOCAL,	/* <value> -K- */
--- a/jsi.h
+++ b/jsi.h
@@ -111,8 +111,6 @@
 void js_dup1rot3(js_State *J);
 void js_dup1rot4(js_State *J);
 
-void js_pushundefinedthis(js_State *J); /* push 'global' if non-strict, undefined if strict */
-
 void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text);
 
 void js_trap(js_State *J, int pc); /* dump stack and environment to stdout */
--- a/jsrun.c
+++ b/jsrun.c
@@ -161,14 +161,6 @@
 	js_pushobject(J, J->G);
 }
 
-void js_pushundefinedthis(js_State *J)
-{
-	if (J->strict)
-		js_pushundefined(J);
-	else
-		js_pushobject(J, J->G);
-}
-
 void js_currentfunction(js_State *J)
 {
 	CHECKSTACK(1);
@@ -1319,9 +1311,20 @@
 		case OP_TRUE: js_pushboolean(J, 1); break;
 		case OP_FALSE: js_pushboolean(J, 0); break;
 
-		case OP_THIS: js_copy(J, 0); break;
-		case OP_GLOBAL: js_pushobject(J, J->G); break;
-		case OP_CURRENT: js_currentfunction(J); break;
+		case OP_THIS:
+			if (J->strict) {
+				js_copy(J, 0);
+			} else {
+				if (js_iscoercible(J, 0))
+					js_copy(J, 0);
+				else
+					js_pushglobal(J);
+			}
+			break;
+
+		case OP_CURRENT:
+			js_currentfunction(J);
+			break;
 
 		case OP_INITLOCAL:
 			STACK[BOT + *pc++] = STACK[--TOP];
--- a/jsstring.c
+++ b/jsstring.c
@@ -405,7 +405,7 @@
 
 	if (js_iscallable(J, 2)) {
 		js_copy(J, 2);
-		js_pushundefinedthis(J);
+		js_pushundefined(J);
 		for (x = 0; m.sub[x].sp; ++x) /* arg 0..x: substring and subexps that matched */
 			js_pushlstring(J, m.sub[x].sp, m.sub[x].ep - m.sub[x].sp);
 		js_pushnumber(J, s - source); /* arg x+2: offset within search string */
@@ -500,7 +500,7 @@
 
 	if (js_iscallable(J, 2)) {
 		js_copy(J, 2);
-		js_pushundefinedthis(J);
+		js_pushundefined(J);
 		js_pushlstring(J, s, n); /* arg 1: substring that matched */
 		js_pushnumber(J, s - source); /* arg 2: offset within search string */
 		js_copy(J, 0); /* arg 3: search string */
--- a/opnames.h
+++ b/opnames.h
@@ -19,7 +19,6 @@
 "true",
 "false",
 "this",
-"global",
 "current",
 "initlocal",
 "getlocal",