mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Create a JSClass hook to allow object classes to easily support custom iteration without having to override __iterator__ in a resolve hook. bug 393306, r+a=brendan
This commit is contained in:
parent
eaabef106d
commit
6426c64ef1
@ -1214,11 +1214,11 @@ struct JSExtendedClass {
|
|||||||
JSEqualityOp equality;
|
JSEqualityOp equality;
|
||||||
JSObjectOp outerObject;
|
JSObjectOp outerObject;
|
||||||
JSObjectOp innerObject;
|
JSObjectOp innerObject;
|
||||||
|
JSIteratorOp iteratorObject;
|
||||||
void (*reserved0)();
|
void (*reserved0)();
|
||||||
void (*reserved1)();
|
void (*reserved1)();
|
||||||
void (*reserved2)();
|
void (*reserved2)();
|
||||||
void (*reserved3)();
|
void (*reserved3)();
|
||||||
void (*reserved4)();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
|
#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */
|
||||||
@ -1287,7 +1287,7 @@ struct JSExtendedClass {
|
|||||||
|
|
||||||
/* Initializer for unused members of statically initialized JSClass structs. */
|
/* Initializer for unused members of statically initialized JSClass structs. */
|
||||||
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
|
#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0
|
||||||
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0,0
|
#define JSCLASS_NO_RESERVED_MEMBERS 0,0,0,0
|
||||||
|
|
||||||
/* For detailed comments on these function pointer types, see jspubtd.h. */
|
/* For detailed comments on these function pointer types, see jspubtd.h. */
|
||||||
struct JSObjectOps {
|
struct JSObjectOps {
|
||||||
|
@ -334,6 +334,8 @@ js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
|||||||
JSObject *obj;
|
JSObject *obj;
|
||||||
JSTempValueRooter tvr;
|
JSTempValueRooter tvr;
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
|
JSClass *clasp;
|
||||||
|
JSExtendedClass *xclasp;
|
||||||
JSBool ok;
|
JSBool ok;
|
||||||
JSObject *iterobj;
|
JSObject *iterobj;
|
||||||
jsval arg;
|
jsval arg;
|
||||||
@ -370,47 +372,60 @@ js_ValueToIterator(JSContext *cx, uintN flags, jsval *vp)
|
|||||||
JS_ASSERT(obj);
|
JS_ASSERT(obj);
|
||||||
JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
|
JS_PUSH_TEMP_ROOT_OBJECT(cx, obj, &tvr);
|
||||||
|
|
||||||
atom = cx->runtime->atomState.iteratorAtom;
|
clasp = OBJ_GET_CLASS(cx, obj);
|
||||||
#if JS_HAS_XML_SUPPORT
|
if ((clasp->flags & JSCLASS_IS_EXTENDED) &&
|
||||||
if (OBJECT_IS_XML(cx, obj)) {
|
(xclasp = (JSExtendedClass *) clasp)->iteratorObject) {
|
||||||
if (!js_GetXMLFunction(cx, obj, ATOM_TO_JSID(atom), vp))
|
iterobj = xclasp->iteratorObject(cx, obj, !(flags & JSITER_FOREACH));
|
||||||
goto bad;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp))
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSVAL_IS_VOID(*vp)) {
|
|
||||||
default_iter:
|
|
||||||
/*
|
|
||||||
* Fail over to the default enumerating native iterator.
|
|
||||||
*
|
|
||||||
* Create iterobj with a NULL parent to ensure that we use the correct
|
|
||||||
* scope chain to lookup the iterator's constructor. Since we use the
|
|
||||||
* parent slot to keep track of the iterable, we must fix it up after.
|
|
||||||
*/
|
|
||||||
iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL);
|
|
||||||
if (!iterobj)
|
if (!iterobj)
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/* Store iterobj in *vp to protect it from GC (callers must root vp). */
|
|
||||||
*vp = OBJECT_TO_JSVAL(iterobj);
|
*vp = OBJECT_TO_JSVAL(iterobj);
|
||||||
|
|
||||||
if (!InitNativeIterator(cx, iterobj, obj, flags))
|
|
||||||
goto bad;
|
|
||||||
} else {
|
} else {
|
||||||
arg = BOOLEAN_TO_JSVAL((flags & JSITER_FOREACH) == 0);
|
atom = cx->runtime->atomState.iteratorAtom;
|
||||||
if (!js_InternalInvoke(cx, obj, *vp, JSINVOKE_ITERATOR, 1, &arg, vp))
|
#if JS_HAS_XML_SUPPORT
|
||||||
goto bad;
|
if (OBJECT_IS_XML(cx, obj)) {
|
||||||
if (JSVAL_IS_PRIMITIVE(*vp)) {
|
if (!js_GetXMLFunction(cx, obj, ATOM_TO_JSID(atom), vp))
|
||||||
const char *printable = js_AtomToPrintableString(cx, atom);
|
goto bad;
|
||||||
if (printable) {
|
} else
|
||||||
js_ReportValueError2(cx, JSMSG_BAD_ITERATOR_RETURN,
|
#endif
|
||||||
JSDVG_SEARCH_STACK, *vp, NULL, printable);
|
{
|
||||||
|
if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp))
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JSVAL_IS_VOID(*vp)) {
|
||||||
|
default_iter:
|
||||||
|
/*
|
||||||
|
* Fail over to the default enumerating native iterator.
|
||||||
|
*
|
||||||
|
* Create iterobj with a NULL parent to ensure that we use the
|
||||||
|
* correct scope chain to lookup the iterator's constructor. Since
|
||||||
|
* we use the parent slot to keep track of the iterable, we must
|
||||||
|
* fix it up after.
|
||||||
|
*/
|
||||||
|
iterobj = js_NewObject(cx, &js_IteratorClass, NULL, NULL);
|
||||||
|
if (!iterobj)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
/* Store in *vp to protect it from GC (callers must root vp). */
|
||||||
|
*vp = OBJECT_TO_JSVAL(iterobj);
|
||||||
|
|
||||||
|
if (!InitNativeIterator(cx, iterobj, obj, flags))
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
arg = BOOLEAN_TO_JSVAL((flags & JSITER_FOREACH) == 0);
|
||||||
|
if (!js_InternalInvoke(cx, obj, *vp, JSINVOKE_ITERATOR, 1, &arg,
|
||||||
|
vp)) {
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (JSVAL_IS_PRIMITIVE(*vp)) {
|
||||||
|
const char *printable = js_AtomToPrintableString(cx, atom);
|
||||||
|
if (printable) {
|
||||||
|
js_ReportValueError2(cx, JSMSG_BAD_ITERATOR_RETURN,
|
||||||
|
JSDVG_SEARCH_STACK, *vp, NULL,
|
||||||
|
printable);
|
||||||
|
}
|
||||||
|
goto bad;
|
||||||
}
|
}
|
||||||
goto bad;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +524,14 @@ typedef JSBool
|
|||||||
typedef JSObject *
|
typedef JSObject *
|
||||||
(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj);
|
(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hook that creates an iterator object for a given object. Returns the
|
||||||
|
* iterator object or null if an error or exception was thrown on cx.
|
||||||
|
*/
|
||||||
|
typedef JSObject *
|
||||||
|
(* JS_DLL_CALLBACK JSIteratorOp)(JSContext *cx, JSObject *obj,
|
||||||
|
JSBool keysonly);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A generic type for functions taking a context, object, and property, with
|
* A generic type for functions taking a context, object, and property, with
|
||||||
* no return value. Used by JSObjectOps.dropProperty currently (see above,
|
* no return value. Used by JSObjectOps.dropProperty currently (see above,
|
||||||
|
Loading…
Reference in New Issue
Block a user