ref: 1aa15582d6f842513a1570b7533effd580bc7789
parent: e8dfb4e624394070b89641a491d03a62eb62682b
author: Tor Andersson <tor@ccxvii.net>
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;
--
⑨