Prep patch for iterators and generators (326466, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2006-04-27 00:39:43 +00:00
parent b9a3e06d7d
commit 0667cc1d4c
11 changed files with 70 additions and 48 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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))) {

View File

@ -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,

View File

@ -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);

View File

@ -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)

View File

@ -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);
/*

View File

@ -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

View File

@ -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);