From dc577b652208c5f35935b967786a4829984a978d Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Thu, 27 Apr 2006 00:39:43 +0000 Subject: [PATCH] Prep patch for iterators and generators (326466, r=mrbkap). git-svn-id: svn://10.0.0.236/trunk@195494 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/js.c | 2 +- mozilla/js/src/jsapi.c | 4 ++-- mozilla/js/src/jsarray.c | 28 +++++++++++++++++++++------- mozilla/js/src/jsarray.h | 10 ++++++++++ mozilla/js/src/jsexn.c | 2 +- mozilla/js/src/jsfile.c | 2 +- mozilla/js/src/jsfun.c | 32 +++++++++++++++----------------- mozilla/js/src/jsfun.h | 4 ++-- mozilla/js/src/jsinterp.c | 18 +++++++++--------- mozilla/js/src/jsobj.c | 8 ++++---- mozilla/js/src/jsxml.c | 8 ++++---- 11 files changed, 70 insertions(+), 48 deletions(-) diff --git a/mozilla/js/src/js.c b/mozilla/js/src/js.c index 5512ed5b498..adae026a130 100644 --- a/mozilla/js/src/js.c +++ b/mozilla/js/src/js.c @@ -1014,7 +1014,7 @@ Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if (!script) continue; - if (JSVAL_IS_FUNCTION(cx, argv[i])) { + if (VALUE_IS_FUNCTION(cx, argv[i])) { JSFunction *fun = JS_ValueToFunction(cx, argv[i]); if (fun && (fun->flags & JSFUN_FLAGS_MASK)) { uint8 flags = fun->flags; diff --git a/mozilla/js/src/jsapi.c b/mozilla/js/src/jsapi.c index fe692fd0ce1..e3605b21ab8 100644 --- a/mozilla/js/src/jsapi.c +++ b/mozilla/js/src/jsapi.c @@ -613,7 +613,7 @@ JS_TypeOfValue(JSContext *cx, jsval v) .callAtom), &v)) { JS_ClearPendingException(cx); - } else if (JSVAL_IS_FUNCTION(cx, v)) { + } else if (VALUE_IS_FUNCTION(cx, v)) { type = JSTYPE_FUNCTION; } #endif @@ -2326,7 +2326,7 @@ JS_GetConstructor(JSContext *cx, JSObject *proto) &cval)) { return NULL; } - if (!JSVAL_IS_FUNCTION(cx, cval)) { + if (!VALUE_IS_FUNCTION(cx, cval)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, OBJ_GET_CLASS(cx, proto)->name); return NULL; diff --git a/mozilla/js/src/jsarray.c b/mozilla/js/src/jsarray.c index 84f03ee1fc2..429a953ec4e 100644 --- a/mozilla/js/src/jsarray.c +++ b/mozilla/js/src/jsarray.c @@ -279,6 +279,20 @@ js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp) return ValueIsLength(cx, v, lengthp); } +JSBool +js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp) +{ + JSClass *clasp; + + clasp = OBJ_GET_CLASS(cx, obj); + *answerp = (clasp == &js_ArgumentsClass || clasp == &js_ArrayClass); + if (!*answerp) { + *lengthp = 0; + return JS_TRUE; + } + return js_GetLengthProperty(cx, obj, lengthp); +} + /* * This get function is specific to Array.prototype.length and other array * instance length properties. It calls back through the class get function @@ -1570,7 +1584,7 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, JSObject *callable, *thisp, *newarr; void *mark; JSStackFrame *fp; - JSBool ok, b; + JSBool ok, cond; /* Hoist the explicit local root address computation. */ vp = argv + argc; @@ -1668,11 +1682,11 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, if (mode > MAP) { if (rval2 == JSVAL_NULL) { - b = JS_FALSE; + cond = JS_FALSE; } else if (JSVAL_IS_BOOLEAN(rval2)) { - b = JSVAL_TO_BOOLEAN(rval2); + cond = JSVAL_TO_BOOLEAN(rval2); } else { - ok = js_ValueToBoolean(cx, rval2, &b); + ok = js_ValueToBoolean(cx, rval2, &cond); if (!ok) goto out; } @@ -1687,7 +1701,7 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, goto out; break; case FILTER: - if (!b) + if (!cond) break; /* Filter passed *vp, push as result. */ ok = IndexToId(cx, newlen++, &id); @@ -1698,13 +1712,13 @@ array_extra(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, goto out; break; case SOME: - if (b) { + if (cond) { *rval = JSVAL_TRUE; goto out; } break; case EVERY: - if (!b) { + if (!cond) { *rval = JSVAL_FALSE; goto out; } diff --git a/mozilla/js/src/jsarray.h b/mozilla/js/src/jsarray.h index fb4527f0357..ce230e126d9 100644 --- a/mozilla/js/src/jsarray.h +++ b/mozilla/js/src/jsarray.h @@ -67,6 +67,16 @@ js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length); extern JSBool js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); +/* + * Test whether an object is "array-like". Currently this means whether obj + * is an Array or an arguments object. We would like an API, and probably a + * way in the language, to bless other objects as array-like: having indexed + * properties, and a 'length' property of uint32 value equal to one more than + * the greatest index. + */ +extern JSBool +js_IsArrayLike(JSContext *cx, JSObject *obj, JSBool *answerp, jsuint *lengthp); + /* * JS-specific heap sort function. */ diff --git a/mozilla/js/src/jsexn.c b/mozilla/js/src/jsexn.c index 466ed72d761..4aaff8762f0 100644 --- a/mozilla/js/src/jsexn.c +++ b/mozilla/js/src/jsexn.c @@ -417,7 +417,7 @@ InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message, v = fp->argv[i]; if (JSVAL_IS_PRIMITIVE(v)) { argsrc = js_ValueToSource(cx, v); - } else if (JSVAL_IS_FUNCTION(cx, v)) { + } else if (VALUE_IS_FUNCTION(cx, v)) { /* XXX Avoid function decompilation bloat for now. */ argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v)); if (!argsrc && !(argsrc = js_ValueToSource(cx, v))) { diff --git a/mozilla/js/src/jsfile.c b/mozilla/js/src/jsfile.c index 64dfb9b214c..a3956f96a3a 100644 --- a/mozilla/js/src/jsfile.c +++ b/mozilla/js/src/jsfile.c @@ -1907,7 +1907,7 @@ file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) if (JSVAL_IS_REGEXP(cx, argv[0])) { re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); }else - if (JSVAL_IS_FUNCTION(cx, argv[0])) { + if (VALUE_IS_FUNCTION(cx, argv[0])) { func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); }else{ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, diff --git a/mozilla/js/src/jsfun.c b/mozilla/js/src/jsfun.c index 397c80cf710..be2203005da 100644 --- a/mozilla/js/src/jsfun.c +++ b/mozilla/js/src/jsfun.c @@ -1443,7 +1443,7 @@ js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, JS_ASSERT(JS_ObjectIsFunction(cx, obj)); } else { fval = argv[-1]; - if (!JSVAL_IS_FUNCTION(cx, fval)) { + if (!VALUE_IS_FUNCTION(cx, fval)) { /* * If we don't have a function to start off with, try converting * the object to a function. If that doesn't work, complain. @@ -1456,7 +1456,7 @@ js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, } argv[-1] = fval; } - if (!JSVAL_IS_FUNCTION(cx, fval)) { + if (!VALUE_IS_FUNCTION(cx, fval)) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO, js_Function_str, js_toString_str, @@ -1512,7 +1512,7 @@ fun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return JS_FALSE; fval = argv[-1]; - if (!JSVAL_IS_FUNCTION(cx, fval)) { + if (!VALUE_IS_FUNCTION(cx, fval)) { str = JS_ValueToString(cx, fval); if (str) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, @@ -1566,9 +1566,9 @@ fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) JSString *str; JSObject *aobj; jsuint length; + JSBool arraylike, ok; void *mark; uintN i; - JSBool ok; JSStackFrame *fp; if (argc == 0) { @@ -1580,7 +1580,7 @@ fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) return JS_FALSE; fval = argv[-1]; - if (!JSVAL_IS_FUNCTION(cx, fval)) { + if (!VALUE_IS_FUNCTION(cx, fval)) { str = JS_ValueToString(cx, fval); if (str) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, @@ -1601,17 +1601,17 @@ fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) argc = 0; } else { /* The second arg must be an array (or arguments object). */ - if (JSVAL_IS_PRIMITIVE(argv[1]) || - (aobj = JSVAL_TO_OBJECT(argv[1]), - OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass && - OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass)) - { + arraylike = JS_FALSE; + if (!JSVAL_IS_PRIMITIVE(argv[1])) { + aobj = JSVAL_TO_OBJECT(argv[1]); + if (!js_IsArrayLike(cx, aobj, &arraylike, &length)) + return JS_FALSE; + } + if (!arraylike) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_APPLY_ARGS, "apply"); return JS_FALSE; } - if (!js_GetLengthProperty(cx, aobj, &length)) - return JS_FALSE; } } @@ -2112,9 +2112,7 @@ js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj) { if (!fun->object) fun->object = funobj; - if (!JS_SetPrivate(cx, funobj, fun)) - return JS_FALSE; - return JS_TRUE; + return JS_SetPrivate(cx, funobj, fun); } JSFunction * @@ -2152,7 +2150,7 @@ js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags) if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) { if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v)) return NULL; - obj = JSVAL_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL; + obj = VALUE_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL; } } if (!obj) { @@ -2170,7 +2168,7 @@ js_ValueToFunctionObject(JSContext *cx, jsval *vp, uintN flags) JSStackFrame *caller; JSPrincipals *principals; - if (JSVAL_IS_FUNCTION(cx, *vp)) + if (VALUE_IS_FUNCTION(cx, *vp)) return JSVAL_TO_OBJECT(*vp); fun = js_ValueToFunction(cx, vp, flags); diff --git a/mozilla/js/src/jsfun.h b/mozilla/js/src/jsfun.h index cf54b6f6491..c85ad5bf752 100644 --- a/mozilla/js/src/jsfun.h +++ b/mozilla/js/src/jsfun.h @@ -74,13 +74,13 @@ struct JSFunction { extern JSClass js_ArgumentsClass; extern JSClass js_CallClass; -/* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */ +/* JS_FRIEND_DATA so that VALUE_IS_FUNCTION is callable from the shell. */ extern JS_FRIEND_DATA(JSClass) js_FunctionClass; /* * NB: jsapi.h and jsobj.h must be included before any call to this macro. */ -#define JSVAL_IS_FUNCTION(cx, v) \ +#define VALUE_IS_FUNCTION(cx, v) \ (!JSVAL_IS_PRIMITIVE(v) && \ OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) diff --git a/mozilla/js/src/jsinterp.c b/mozilla/js/src/jsinterp.c index 99553fa030a..091cbe4e956 100644 --- a/mozilla/js/src/jsinterp.c +++ b/mozilla/js/src/jsinterp.c @@ -842,7 +842,7 @@ LogCall(JSContext *cx, jsval callee, uintN argc, jsval *argv) key.filename = NULL; key.lineno = 0; name = ""; - if (JSVAL_IS_FUNCTION(cx, callee)) { + if (VALUE_IS_FUNCTION(cx, callee)) { fun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(callee)); if (fun->atom) name = js_AtomToPrintableString(cx, fun->atom); @@ -932,7 +932,7 @@ LogCall(JSContext *cx, jsval callee, uintN argc, jsval *argv) str = js_QuoteString(cx, JSVAL_TO_STRING(argval), (jschar)'"'); break; case JSTYPE_FUNCTION: - if (JSVAL_IS_FUNCTION(cx, argval)) { + if (VALUE_IS_FUNCTION(cx, argval)) { fun = (JSFunction *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(argval)); if (fun && fun->atom) { str = ATOM_TO_STRING(fun->atom); @@ -1057,7 +1057,7 @@ js_Invoke(JSContext *cx, uintN argc, uintN flags) if (!ok) goto out2; - if (JSVAL_IS_FUNCTION(cx, v)) { + if (VALUE_IS_FUNCTION(cx, v)) { /* Make vp refer to funobj to keep it available as argv[-2]. */ *vp = v; funobj = JSVAL_TO_OBJECT(v); @@ -1369,7 +1369,7 @@ js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, */ JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE); if (cx->runtime->checkObjectAccess && - JSVAL_IS_FUNCTION(cx, fval) && + VALUE_IS_FUNCTION(cx, fval) && ((JSFunction *)JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)))->interpreted && !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode, &fval)) { @@ -1551,7 +1551,7 @@ ImportProperty(JSContext *cx, JSObject *obj, jsid id) ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs); if (!ok) goto out; - if (JSVAL_IS_FUNCTION(cx, value)) { + if (VALUE_IS_FUNCTION(cx, value)) { funobj = JSVAL_TO_OBJECT(value); closure = js_CloneFunctionObject(cx, funobj, obj); if (!closure) { @@ -1646,7 +1646,7 @@ js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, if (!isFunction) { if (!OBJ_GET_PROPERTY(cx, obj, id, &value)) goto bad; - isFunction = JSVAL_IS_FUNCTION(cx, value); + isFunction = VALUE_IS_FUNCTION(cx, value); } type = (oldAttrs & attrs & JSPROP_GETTER) ? js_getter_str @@ -3683,7 +3683,7 @@ interrupt: } #endif - if (JSVAL_IS_FUNCTION(cx, lval) && + if (VALUE_IS_FUNCTION(cx, lval) && (obj = JSVAL_TO_OBJECT(lval), fun = (JSFunction *) JS_GetPrivate(cx, obj), fun->interpreted)) @@ -4805,7 +4805,7 @@ interrupt: BEGIN_LITOPX_CASE(JSOP_NAMEDFUNOBJ, 0) /* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */ rval = ATOM_KEY(atom); - JS_ASSERT(JSVAL_IS_FUNCTION(cx, rval)); + JS_ASSERT(VALUE_IS_FUNCTION(cx, rval)); /* * 1. Create a new object as if by the expression new Object(). @@ -4900,7 +4900,7 @@ interrupt: * Get immediate operand atom, which is a function object literal. * From it, get the function to close. */ - JS_ASSERT(JSVAL_IS_FUNCTION(cx, ATOM_KEY(atom))); + JS_ASSERT(VALUE_IS_FUNCTION(cx, ATOM_KEY(atom))); obj = ATOM_TO_OBJECT(atom); /* diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index b4231c526d5..341bfe87d38 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -3708,7 +3708,7 @@ js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) &fval)) { return JS_FALSE; } - if (JSVAL_IS_FUNCTION(cx, fval)) { + if (VALUE_IS_FUNCTION(cx, fval)) { if (!GetCurrentExecutionContext(cx, obj, &nargv[2])) return JS_FALSE; args = js_GetArgsObject(cx, cx->fp); @@ -3751,7 +3751,7 @@ js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, &cval)) { return JS_FALSE; } - if (JSVAL_IS_FUNCTION(cx, cval)) { + if (VALUE_IS_FUNCTION(cx, cval)) { if (!GetCurrentExecutionContext(cx, obj, &nargv[1])) return JS_FALSE; args = js_GetArgsObject(cx, cx->fp); @@ -3792,7 +3792,7 @@ js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) &fval)) { return JS_FALSE; } - if (JSVAL_IS_FUNCTION(cx, fval)) { + if (VALUE_IS_FUNCTION(cx, fval)) { return js_InternalCall(cx, obj, fval, 1, &v, &rval) && js_ValueToBoolean(cx, rval, bp); } @@ -3835,7 +3835,7 @@ js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id, if (!js_FindClassObject(cx, scope, id, &v)) return JS_FALSE; - if (JSVAL_IS_FUNCTION(cx, v)) { + if (VALUE_IS_FUNCTION(cx, v)) { ctor = JSVAL_TO_OBJECT(v); if (!OBJ_GET_PROPERTY(cx, ctor, ATOM_TO_JSID(cx->runtime->atomState diff --git a/mozilla/js/src/jsxml.c b/mozilla/js/src/jsxml.c index 5623c6bcd71..32f99954f09 100644 --- a/mozilla/js/src/jsxml.c +++ b/mozilla/js/src/jsxml.c @@ -1830,7 +1830,7 @@ GetXMLSetting(JSContext *cx, const char *name, jsval *vp) if (!js_FindClassObject(cx, NULL, INT_TO_JSID(JSProto_XML), &v)) return JS_FALSE; - if (!JSVAL_IS_FUNCTION(cx, v)) { + if (!VALUE_IS_FUNCTION(cx, v)) { *vp = JSVAL_VOID; return JS_TRUE; } @@ -3914,7 +3914,7 @@ GetFunction(JSContext *cx, JSObject *obj, JSXML *xml, jsid id, jsval *vp) /* XXXbe really want a separate scope for function::*. */ if (!js_GetProperty(cx, obj, id, &fval)) return JS_FALSE; - if (JSVAL_IS_FUNCTION(cx, fval)) { + if (VALUE_IS_FUNCTION(cx, fval)) { if (xml && OBJECT_IS_XML(cx, obj)) { fun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)); if (!fun->interpreted && fun->u.n.spare && @@ -4997,7 +4997,7 @@ xml_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, JSPropertyOp getter, JSPropertyOp setter, uintN attrs, JSProperty **propp) { - if (JSVAL_IS_FUNCTION(cx, value) || getter || setter || + if (VALUE_IS_FUNCTION(cx, value) || getter || setter || (attrs & JSPROP_ENUMERATE) == 0 || (attrs & (JSPROP_READONLY | JSPROP_PERMANENT | JSPROP_SHARED))) { return js_DefineProperty(cx, obj, id, value, getter, setter, attrs, @@ -7485,7 +7485,7 @@ js_InitXMLClass(JSContext *cx, JSObject *obj) JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))); cval = OBJ_GET_SLOT(cx, pobj, sprop->slot); OBJ_DROP_PROPERTY(cx, pobj, prop); - JS_ASSERT(JSVAL_IS_FUNCTION(cx, cval)); + JS_ASSERT(VALUE_IS_FUNCTION(cx, cval)); /* Set default settings. */ ctor = JSVAL_TO_OBJECT(cval);