shithub: libmujs

Download patch

ref: 1aa15582d6f842513a1570b7533effd580bc7789
parent: e8dfb4e624394070b89641a491d03a62eb62682b
author: Tor Andersson <[email protected]>
date: Tue Jan 28 08:39:50 EST 2014

Let hasproperty push the value of the property on the stack if it exists.

This lets us avoid calling getproperty in the most common case of:

    if (hasproperty) { getproperty(); do stuff }

--- a/jsarray.c
+++ b/jsarray.c
@@ -84,10 +84,8 @@
 			len = js_getlength(J, -1);
 
 			while (k < len) {
-				if (js_hasindex(J, -1, k)) {
-					js_getindex(J, -1, k);
+				if (js_hasindex(J, -1, k))
 					js_setindex(J, -3, n);
-				}
 				++k;
 				++n;
 			}
@@ -203,16 +201,12 @@
 		int haslower = js_hasindex(J, 0, lower);
 		int hasupper = js_hasindex(J, 0, upper);
 		if (haslower && hasupper) {
-			js_getindex(J, 0, lower);
-			js_getindex(J, 0, upper);
 			js_setindex(J, 0, lower);
 			js_setindex(J, 0, upper);
 		} else if (hasupper) {
-			js_getindex(J, 0, upper);
 			js_setindex(J, 0, lower);
 			js_delindex(J, 0, upper);
 		} else if (haslower) {
-			js_getindex(J, 0, lower);
 			js_setindex(J, 0, upper);
 			js_delindex(J, 0, lower);
 		}
@@ -238,12 +232,10 @@
 	js_getindex(J, 0, 0);
 
 	for (k = 1; k < len; ++k) {
-		if (js_hasindex(J, 0, k)) {
-			js_getindex(J, 0, k);
+		if (js_hasindex(J, 0, k))
 			js_setindex(J, 0, k - 1);
-		} else {
+		else
 			js_delindex(J, 0, k - 1);
-		}
 	}
 
 	js_delindex(J, 0, len - 1);
@@ -269,12 +261,9 @@
 	s = s < 0 ? 0 : s > len ? len : s;
 	e = e < 0 ? 0 : e > len ? len : e;
 
-	for (n = 0; s < e; ++s, ++n) {
-		if (js_hasindex(J, 0, s)) {
-			js_getindex(J, 0, s);
+	for (n = 0; s < e; ++s, ++n)
+		if (js_hasindex(J, 0, s))
 			js_setindex(J, -2, n);
-		}
-	}
 
 	return 1;
 }
@@ -298,35 +287,27 @@
 	del = del < 0 ? 0 : del > len - start ? len - start : del;
 
 	/* copy deleted items to return array */
-	for (k = 0; k < del; ++k) {
-		if (js_hasindex(J, 0, start + k)) {
-			js_getindex(J, 0, start + k);
+	for (k = 0; k < del; ++k)
+		if (js_hasindex(J, 0, start + k))
 			js_setindex(J, -2, k);
-		}
-	}
 
 	/* shift the tail to resize the hole left by deleted items */
 	add = argc - 2;
 	if (add < del) {
 		for (k = start; k < len - del; ++k) {
-			if (js_hasindex(J, 0, k + del)) {
-				js_getindex(J, 0, k + del);
+			if (js_hasindex(J, 0, k + del))
 				js_setindex(J, 0, k + add);
-			} else {
+			else
 				js_delindex(J, 0, k + del);
-			}
 		}
-		for (k = len; k > len - del + add; --k) {
+		for (k = len; k > len - del + add; --k)
 			js_delindex(J, 0, k - 1);
-		}
 	} else if (add > del) {
 		for (k = len - del; k > start; --k) {
-			if (js_hasindex(J, 0, k + del - 1)) {
-				js_getindex(J, 0, k + del - 1);
+			if (js_hasindex(J, 0, k + del - 1))
 				js_setindex(J, 0, k + add - 1);
-			} else {
+			else
 				js_delindex(J, 0, k + add - 1);
-			}
 		}
 	}
 
@@ -351,12 +332,10 @@
 	for (k = len; k > 0; --k) {
 		int from = k - 1;
 		int to = k + argc - 1;
-		if (js_hasindex(J, 0, from)) {
-			js_getindex(J, 0, from);
+		if (js_hasindex(J, 0, from))
 			js_setindex(J, 0, to);
-		} else {
+		else
 			js_delindex(J, 0, to);
-		}
 	}
 
 	for (i = 1; i <= argc; ++i) {
--- a/jsrun.c
+++ b/jsrun.c
@@ -276,7 +276,7 @@
 
 /* Property access that takes care of attributes and getters/setters */
 
-static void jsR_getproperty(js_State *J, js_Object *obj, const char *name)
+static int jsR_hasproperty(js_State *J, js_Object *obj, const char *name)
 {
 	js_Property *ref;
 
@@ -283,14 +283,22 @@
 	if (obj->type == JS_CARRAY) {
 		if (!strcmp(name, "length")) {
 			js_pushnumber(J, obj->u.a.length);
-			return;
+			return 1;
 		}
 	}
 
 	ref = jsV_getproperty(J, obj, name);
-	if (ref)
+	if (ref) {
 		js_pushvalue(J, ref->value);
-	else
+		return 1;
+	}
+
+	return 0;
+}
+
+static void jsR_getproperty(js_State *J, js_Object *obj, const char *name)
+{
+	if (!jsR_hasproperty(J, obj, name))
 		js_pushundefined(J);
 }
 
@@ -438,7 +446,7 @@
 
 int js_hasproperty(js_State *J, int idx, const char *name)
 {
-	return !!jsV_getproperty(J, js_toobject(J, idx), name);
+	return jsR_hasproperty(J, js_toobject(J, idx), name);
 }
 
 /* Environment records */
@@ -771,7 +779,7 @@
 		case OP_IN:
 			str = js_tostring(J, -2);
 			b = js_hasproperty(J, -1, str);
-			js_pop(J, 2);
+			js_pop(J, 2 + b);
 			js_pushboolean(J, b);
 			break;