зеркало из https://github.com/mozilla/pjs.git
Don't wrap StopIteration singleton, just translate it to the current global's StopIteration object and freeze StopIteration at birth (606573, r=mrbkap).
This commit is contained in:
Родитель
19087d1172
Коммит
8f3f417a80
|
@ -1718,6 +1718,10 @@ struct JSClass {
|
|||
#define JSCLASS_MARK_IS_TRACE (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
|
||||
#define JSCLASS_INTERNAL_FLAG2 (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
|
||||
|
||||
/* Indicate whether the proto or ctor should be frozen. */
|
||||
#define JSCLASS_FREEZE_PROTO (1<<(JSCLASS_HIGH_FLAGS_SHIFT+5))
|
||||
#define JSCLASS_FREEZE_CTOR (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6))
|
||||
|
||||
/* Additional global reserved slots, beyond those for standard prototypes. */
|
||||
#define JSRESERVED_GLOBAL_SLOTS_COUNT 3
|
||||
#define JSRESERVED_GLOBAL_THIS (JSProto_LIMIT * 3)
|
||||
|
|
|
@ -38,9 +38,10 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsgc.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsiter.h"
|
||||
#include "jsproxy.h"
|
||||
#include "jsscope.h"
|
||||
#include "methodjit/PolyIC.h"
|
||||
|
@ -143,6 +144,10 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
|||
if (obj->compartment() == this)
|
||||
return true;
|
||||
|
||||
/* Translate StopIteration singleton. */
|
||||
if (obj->getClass() == &js_StopIterationClass)
|
||||
return js_FindClassObject(cx, NULL, JSProto_StopIteration, vp);
|
||||
|
||||
/* Don't unwrap an outer window proxy. */
|
||||
if (!obj->getClass()->ext.innerObject) {
|
||||
obj = vp->toObject().unwrap(&flags);
|
||||
|
|
|
@ -624,6 +624,16 @@ GetIterator(JSContext *cx, JSObject *obj, uintN flags, Value *vp)
|
|||
bool keysOnly = (flags == JSITER_ENUMERATE);
|
||||
|
||||
if (obj) {
|
||||
/* Enumerate Iterator.prototype directly. */
|
||||
JSIteratorOp op = obj->getClass()->ext.iteratorObject;
|
||||
if (op && (obj->getClass() != &js_IteratorClass || obj->getNativeIterator())) {
|
||||
JSObject *iterobj = op(cx, obj, !(flags & JSITER_FOREACH));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
vp->setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keysOnly) {
|
||||
/*
|
||||
* Check to see if this is the same as the most recent object which
|
||||
|
@ -813,8 +823,7 @@ js_ValueToIterator(JSContext *cx, uintN flags, Value *vp)
|
|||
if ((flags & JSITER_ENUMERATE)) {
|
||||
if (!js_ValueToObjectOrNull(cx, *vp, &obj))
|
||||
return false;
|
||||
if (!obj)
|
||||
return GetIterator(cx, NULL, flags, vp);
|
||||
/* fall through */
|
||||
} else {
|
||||
obj = js_ValueToNonNullObject(cx, *vp);
|
||||
if (!obj)
|
||||
|
@ -822,18 +831,6 @@ js_ValueToIterator(JSContext *cx, uintN flags, Value *vp)
|
|||
}
|
||||
}
|
||||
|
||||
AutoObjectRooter tvr(cx, obj);
|
||||
|
||||
/* Enumerate Iterator.prototype directly. */
|
||||
JSIteratorOp op = obj->getClass()->ext.iteratorObject;
|
||||
if (op && (obj->getClass() != &js_IteratorClass || obj->getNativeIterator())) {
|
||||
JSObject *iterobj = op(cx, obj, !(flags & JSITER_FOREACH));
|
||||
if (!iterobj)
|
||||
return false;
|
||||
vp->setObject(*iterobj);
|
||||
return true;
|
||||
}
|
||||
|
||||
return GetIterator(cx, obj, flags, vp);
|
||||
}
|
||||
|
||||
|
@ -1084,7 +1081,9 @@ stopiter_hasInstance(JSContext *cx, JSObject *obj, const Value *v, JSBool *bp)
|
|||
|
||||
Class js_StopIterationClass = {
|
||||
js_StopIteration_str,
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration),
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration) |
|
||||
JSCLASS_FREEZE_PROTO |
|
||||
JSCLASS_FREEZE_CTOR,
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
|
|
@ -3680,6 +3680,13 @@ js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
if (!proto->getEmptyShape(cx, proto->clasp, FINALIZE_OBJECT0))
|
||||
goto bad;
|
||||
|
||||
if (clasp->flags & (JSCLASS_FREEZE_PROTO|JSCLASS_FREEZE_CTOR)) {
|
||||
if (proto && (clasp->flags & JSCLASS_FREEZE_PROTO) && !proto->freeze(cx))
|
||||
goto bad;
|
||||
if (ctor && (clasp->flags & JSCLASS_FREEZE_CTOR) && !ctor->freeze(cx))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* If this is a standard class, cache its prototype. */
|
||||
if (key != JSProto_Null && !js_SetClassObject(cx, obj, key, ctor, proto))
|
||||
goto bad;
|
||||
|
|
Загрузка…
Ссылка в новой задаче