Merge.
This commit is contained in:
268
js/src/jsobj.cpp
268
js/src/jsobj.cpp
@@ -3294,7 +3294,8 @@ JS_FRIEND_API(JSBool)
|
||||
js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
||||
JSProperty **propp)
|
||||
{
|
||||
return js_LookupPropertyWithFlags(cx, obj, id, 0, objp, propp) >= 0;
|
||||
return js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
objp, propp) >= 0;
|
||||
}
|
||||
|
||||
#define SCOPE_DEPTH_ACCUM(bs,val) \
|
||||
@@ -3366,8 +3367,8 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
||||
|
||||
if (clasp->flags & JSCLASS_NEW_RESOLVE) {
|
||||
newresolve = (JSNewResolveOp)resolve;
|
||||
if (!(flags & JSRESOLVE_CLASSNAME) &&
|
||||
cx->fp && cx->fp->regs) {
|
||||
if (flags == JSRESOLVE_INFER && cx->fp && cx->fp->regs) {
|
||||
flags = 0;
|
||||
pc = cx->fp->regs->pc;
|
||||
cs = &js_CodeSpec[*pc];
|
||||
format = cs->format;
|
||||
@@ -3506,7 +3507,8 @@ js_FindPropertyHelper(JSContext *cx, jsid id, JSObject **objp,
|
||||
for (scopeIndex = 0; ; scopeIndex++) {
|
||||
if (obj->map->ops->lookupProperty == js_LookupProperty) {
|
||||
protoIndex =
|
||||
js_LookupPropertyWithFlags(cx, obj, id, 0, &pobj, &prop);
|
||||
js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
&pobj, &prop);
|
||||
} else {
|
||||
if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop))
|
||||
return -1;
|
||||
@@ -3640,7 +3642,6 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp)
|
||||
{
|
||||
JSScope *scope;
|
||||
uint32 slot;
|
||||
jsval pval;
|
||||
int32 sample;
|
||||
JSTempValueRooter tvr;
|
||||
bool ok;
|
||||
@@ -3652,7 +3653,7 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp)
|
||||
|
||||
slot = sprop->slot;
|
||||
if (slot != SPROP_INVALID_SLOT) {
|
||||
pval = LOCKED_OBJ_GET_SLOT(obj, slot);
|
||||
OBJ_CHECK_SLOT(obj, slot);
|
||||
|
||||
/* If sprop has a stub setter, keep scope locked and just store *vp. */
|
||||
if (SPROP_HAS_STUB_SETTER(sprop))
|
||||
@@ -3665,7 +3666,6 @@ js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp)
|
||||
*/
|
||||
if (SPROP_HAS_STUB_SETTER(sprop))
|
||||
return JS_TRUE;
|
||||
pval = JSVAL_VOID;
|
||||
}
|
||||
|
||||
sample = cx->runtime->propertyRemovals;
|
||||
@@ -3703,7 +3703,8 @@ js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JS_COUNT_OPERATION(cx, JSOW_GET_PROPERTY);
|
||||
|
||||
shape = OBJ_SHAPE(obj);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &obj2, &prop);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
&obj2, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
if (!prop) {
|
||||
@@ -3804,7 +3805,8 @@ js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
|
||||
JS_COUNT_OPERATION(cx, JSOW_SET_PROPERTY);
|
||||
|
||||
shape = OBJ_SHAPE(obj);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, 0, &pobj, &prop);
|
||||
protoIndex = js_LookupPropertyWithFlags(cx, obj, id, cx->resolveFlags,
|
||||
&pobj, &prop);
|
||||
if (protoIndex < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
@@ -5306,95 +5308,215 @@ js_GetWrappedObject(JSContext *cx, JSObject *obj)
|
||||
return obj;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#if DEBUG
|
||||
|
||||
/* Routines to print out values during debugging. */
|
||||
/*
|
||||
* Routines to print out values during debugging. These are FRIEND_API to help
|
||||
* the debugger find them and to support temporarily hacking js_Dump* calls
|
||||
* into other code.
|
||||
*/
|
||||
|
||||
void
|
||||
dumpChars(const jschar *s, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (n == (size_t) -1) {
|
||||
while (s[++n]) ;
|
||||
}
|
||||
|
||||
void printChar(jschar *cp) {
|
||||
fprintf(stderr, "jschar* (%p) \"", (void *)cp);
|
||||
while (*cp)
|
||||
fputc(*cp++, stderr);
|
||||
fputc('"', stderr);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (s[i] == '\n')
|
||||
fprintf(stderr, "\\n");
|
||||
else if (s[i] == '\t')
|
||||
fprintf(stderr, "\\t");
|
||||
else if (s[i] >= 32 && s[i] < 127)
|
||||
fputc(s[i], stderr);
|
||||
else if (s[i] <= 255)
|
||||
fprintf(stderr, "\\x%02x", (unsigned int) s[i]);
|
||||
else
|
||||
fprintf(stderr, "\\u%04x", (unsigned int) s[i]);
|
||||
}
|
||||
fputc('"', stderr);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpChars(const jschar *s, size_t n)
|
||||
{
|
||||
fprintf(stderr, "jschar * (%p) = ", (void *) s);
|
||||
dumpChars(s, n);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
void printString(JSString *str) {
|
||||
size_t i, n;
|
||||
jschar *s;
|
||||
fprintf(stderr, "string (%p) \"", (void *)str);
|
||||
JSSTRING_CHARS_AND_LENGTH(str, s, n);
|
||||
for (i=0; i < n; i++)
|
||||
fputc(s[i], stderr);
|
||||
fputc('"', stderr);
|
||||
void
|
||||
dumpString(JSString *str)
|
||||
{
|
||||
dumpChars(JSSTRING_CHARS(str), JSSTRING_LENGTH(str));
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpString(JSString *str)
|
||||
{
|
||||
fprintf(stderr, "JSString* (%p) = jschar * (%p) = ",
|
||||
(void *) str, (void *) JSSTRING_CHARS(str));
|
||||
dumpString(str);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
void printVal(JSContext *cx, jsval val);
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpAtom(JSAtom *atom)
|
||||
{
|
||||
fprintf(stderr, "JSAtom* (%p) = ", (void *) atom);
|
||||
js_DumpValue(ATOM_KEY(atom));
|
||||
}
|
||||
|
||||
void printObj(JSContext *cx, JSObject *obj) {
|
||||
jsuint i, slots;
|
||||
jsval val;
|
||||
void
|
||||
dumpValue(jsval val)
|
||||
{
|
||||
if (JSVAL_IS_NULL(val)) {
|
||||
fprintf(stderr, "null");
|
||||
} else if (JSVAL_IS_VOID(val)) {
|
||||
fprintf(stderr, "undefined");
|
||||
} else if (JSVAL_IS_OBJECT(val)) {
|
||||
JSObject *obj = JSVAL_TO_OBJECT(val);
|
||||
JSClass *cls = STOBJ_GET_CLASS(obj);
|
||||
fprintf(stderr, "<%s%s at %p>",
|
||||
cls->name,
|
||||
cls == &js_ObjectClass ? "" : " object",
|
||||
obj);
|
||||
} else if (JSVAL_IS_INT(val)) {
|
||||
fprintf(stderr, "%d", JSVAL_TO_INT(val));
|
||||
} else if (JSVAL_IS_STRING(val)) {
|
||||
dumpString(JSVAL_TO_STRING(val));
|
||||
} else if (JSVAL_IS_DOUBLE(val)) {
|
||||
fprintf(stderr, "%g", *JSVAL_TO_DOUBLE(val));
|
||||
} else if (val == JSVAL_TRUE) {
|
||||
fprintf(stderr, "true");
|
||||
} else if (val == JSVAL_FALSE) {
|
||||
fprintf(stderr, "false");
|
||||
} else if (val == JSVAL_HOLE) {
|
||||
fprintf(stderr, "hole");
|
||||
} else {
|
||||
/* jsvals are pointer-sized, and %p is portable */
|
||||
fprintf(stderr, "unrecognized jsval %p", (void *) val);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpValue(jsval val)
|
||||
{
|
||||
fprintf(stderr, "jsval %d (%p) = ", (int) val, (void *) val);
|
||||
dumpValue(val);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpId(jsid id)
|
||||
{
|
||||
fprintf(stderr, "id %d (%p) = ", (int) id, (void *) id);
|
||||
dumpValue(ID_TO_VALUE(id));
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
void
|
||||
dumpScopeProp(JSScopeProperty *sprop)
|
||||
{
|
||||
jsid id = sprop->id;
|
||||
uint8 attrs = sprop->attrs;
|
||||
|
||||
fprintf(stderr, " ");
|
||||
if (attrs & JSPROP_ENUMERATE) fprintf(stderr, "enumerate ");
|
||||
if (attrs & JSPROP_READONLY) fprintf(stderr, "readonly ");
|
||||
if (attrs & JSPROP_PERMANENT) fprintf(stderr, "permanent ");
|
||||
if (attrs & JSPROP_GETTER) fprintf(stderr, "getter ");
|
||||
if (attrs & JSPROP_SETTER) fprintf(stderr, "setter ");
|
||||
if (attrs & JSPROP_SHARED) fprintf(stderr, "shared ");
|
||||
if (sprop->flags & SPROP_IS_ALIAS) fprintf(stderr, "alias ");
|
||||
if (JSID_IS_ATOM(id))
|
||||
dumpString(JSVAL_TO_STRING(ID_TO_VALUE(id)));
|
||||
else if (JSID_IS_INT(id))
|
||||
fprintf(stderr, "%d", (int) JSID_TO_INT(id));
|
||||
else
|
||||
fprintf(stderr, "unknown jsid %p", (void *) id);
|
||||
fprintf(stderr, ": slot %d", sprop->slot);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_DumpObject(JSObject *obj)
|
||||
{
|
||||
uint32 i, slots;
|
||||
JSClass *clasp;
|
||||
jsuint reservedEnd;
|
||||
|
||||
fprintf(stderr, "object %p\n", (void *) obj);
|
||||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
clasp = STOBJ_GET_CLASS(obj);
|
||||
fprintf(stderr, "class %p %s\n", (void *)clasp, clasp->name);
|
||||
if (OBJ_IS_DENSE_ARRAY(cx, obj)) {
|
||||
|
||||
/* OBJ_IS_DENSE_ARRAY ignores the cx argument. */
|
||||
if (OBJ_IS_DENSE_ARRAY(BOGUS_CX, obj)) {
|
||||
slots = JS_MIN((jsuint) obj->fslots[JSSLOT_ARRAY_LENGTH],
|
||||
ARRAY_DENSE_LENGTH(obj));
|
||||
fprintf(stderr, "elements\n");
|
||||
for (i = 0; i < slots; i++) {
|
||||
val = obj->dslots[i];
|
||||
if (JSVAL_IS_OBJECT(val))
|
||||
fprintf(stderr, "object %p\n", (void*)JSVAL_TO_OBJECT(val));
|
||||
else
|
||||
printVal(cx, val);
|
||||
fprintf(stderr, " %3d: ", i);
|
||||
dumpValue(obj->dslots[i]);
|
||||
fprintf(stderr, "\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
slots = STOBJ_NSLOTS(obj);
|
||||
for (i=0; i < slots; i++) {
|
||||
fprintf(stderr, "slot %3d ", i);
|
||||
val = STOBJ_GET_SLOT(obj, i);
|
||||
if (JSVAL_IS_OBJECT(val))
|
||||
fprintf(stderr, "object %p\n", (void *)JSVAL_TO_OBJECT(val));
|
||||
else
|
||||
printVal(cx, val);
|
||||
}
|
||||
}
|
||||
if (OBJ_IS_NATIVE(obj)) {
|
||||
JSScope *scope = OBJ_SCOPE(obj);
|
||||
JSObject *proto = STOBJ_GET_PROTO(obj);
|
||||
|
||||
void printVal(JSContext *cx, jsval val) {
|
||||
fprintf(stderr, "val %d (%p) = ", (int)val, (void *)val);
|
||||
if (JSVAL_IS_NULL(val)) {
|
||||
fprintf(stderr, "null\n");
|
||||
} else if (JSVAL_IS_VOID(val)) {
|
||||
fprintf(stderr, "undefined\n");
|
||||
} else if (JSVAL_IS_OBJECT(val)) {
|
||||
printObj(cx, JSVAL_TO_OBJECT(val));
|
||||
} else if (JSVAL_IS_INT(val)) {
|
||||
fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val));
|
||||
} else if (JSVAL_IS_STRING(val)) {
|
||||
printString(JSVAL_TO_STRING(val));
|
||||
} else if (JSVAL_IS_DOUBLE(val)) {
|
||||
fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val));
|
||||
} else if (val == JSVAL_HOLE) {
|
||||
fprintf(stderr, "hole\n");
|
||||
if (SCOPE_IS_SEALED(scope))
|
||||
fprintf(stderr, "sealed\n");
|
||||
|
||||
if (proto && scope == OBJ_SCOPE(proto)) {
|
||||
fprintf(stderr, "shares scope with proto (%s at %p)\n",
|
||||
STOBJ_GET_CLASS(proto)->name, proto);
|
||||
}
|
||||
|
||||
fprintf(stderr, "properties:\n");
|
||||
for (JSScopeProperty *sprop = SCOPE_LAST_PROP(scope); sprop;
|
||||
sprop = sprop->parent) {
|
||||
if (!SCOPE_HAD_MIDDLE_DELETE(scope) ||
|
||||
SCOPE_HAS_PROPERTY(scope, sprop)) {
|
||||
dumpScopeProp(sprop);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(JSVAL_IS_BOOLEAN(val));
|
||||
fprintf(stderr, "(boolean) %s\n",
|
||||
JSVAL_TO_BOOLEAN(val) ? "true" : "false");
|
||||
if (!OBJ_IS_NATIVE(obj))
|
||||
fprintf(stderr, "not native\n");
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
void printId(JSContext *cx, jsid id) {
|
||||
fprintf(stderr, "id %d (%p) is ", (int)id, (void *)id);
|
||||
printVal(cx, ID_TO_VALUE(id));
|
||||
}
|
||||
|
||||
void printAtom(JSAtom *atom) {
|
||||
printString(ATOM_TO_STRING(atom));
|
||||
fprintf(stderr, "slots:\n");
|
||||
slots = obj->map->freeslot;
|
||||
reservedEnd = JSSLOT_PRIVATE;
|
||||
if (clasp->flags & JSCLASS_HAS_PRIVATE)
|
||||
reservedEnd++;
|
||||
reservedEnd += JSCLASS_RESERVED_SLOTS(clasp);
|
||||
for (i = 0; i < slots; i++) {
|
||||
fprintf(stderr, " %3d ", i);
|
||||
if (i == JSSLOT_PRIVATE && (clasp->flags & JSCLASS_HAS_PRIVATE)) {
|
||||
fprintf(stderr, "(private) = %p",
|
||||
JSVAL_TO_PRIVATE(STOBJ_GET_SLOT(obj, i)));
|
||||
continue;
|
||||
}
|
||||
if (i == JSSLOT_PROTO)
|
||||
fprintf(stderr, "(proto) ");
|
||||
else if (i == JSSLOT_PARENT)
|
||||
fprintf(stderr, "(parent) ");
|
||||
else if (i < reservedEnd)
|
||||
fprintf(stderr, "(reserved) ");
|
||||
fprintf(stderr, "= ");
|
||||
dumpValue(STOBJ_GET_SLOT(obj, i));
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user