--- trunk/js/jsiter.cpp 2009/09/22 20:24:54 459 +++ trunk/js/jsiter.cpp 2009/09/26 23:15:22 460 @@ -64,6 +64,8 @@ #include "jsscan.h" #include "jsscope.h" #include "jsscript.h" +#include "jsstaticcheck.h" +#include "jstracer.h" #if JS_HAS_XML_SUPPORT #include "jsxml.h" @@ -75,7 +77,7 @@ #if JS_HAS_GENERATORS -static JSBool +static JS_REQUIRES_STACK JSBool CloseGenerator(JSContext *cx, JSObject *genobj); #endif @@ -103,9 +105,8 @@ #if JS_HAS_XML_SUPPORT uintN flags = JSVAL_TO_INT(STOBJ_GET_SLOT(iterobj, JSSLOT_ITER_FLAGS)); if ((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, iterable)) { - ((JSXMLObjectOps *) iterable->map->ops)-> - enumerateValues(cx, iterable, JSENUMERATE_DESTROY, &state, - NULL, NULL); + js_EnumerateXMLValues(cx, iterable, JSENUMERATE_DESTROY, &state, + NULL, NULL); } else #endif OBJ_ENUMERATE(cx, iterable, JSENUMERATE_DESTROY, &state, NULL); @@ -142,8 +143,7 @@ ok = #if JS_HAS_XML_SUPPORT ((flags & JSITER_FOREACH) && OBJECT_IS_XML(cx, obj)) - ? ((JSXMLObjectOps *) obj->map->ops)-> - enumerateValues(cx, obj, JSENUMERATE_INIT, &state, NULL, NULL) + ? js_EnumerateXMLValues(cx, obj, JSENUMERATE_INIT, &state, NULL, NULL) : #endif OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &state, NULL); @@ -174,7 +174,7 @@ keyonly = js_ValueToBoolean(argv[1]); flags = keyonly ? 0 : JSITER_FOREACH; - if (cx->fp->flags & JSFRAME_CONSTRUCTING) { + if (JS_IsConstructing(cx)) { /* XXX work around old valueOf call hidden beneath js_ValueToObject */ if (!JSVAL_IS_PRIMITIVE(argv[0])) { obj = JSVAL_TO_OBJECT(argv[0]); @@ -232,9 +232,8 @@ ok = #if JS_HAS_XML_SUPPORT (foreach && OBJECT_IS_XML(cx, iterable)) - ? ((JSXMLObjectOps *) iterable->map->ops)-> - enumerateValues(cx, iterable, JSENUMERATE_NEXT, &state, - &id, rval) + ? js_EnumerateXMLValues(cx, iterable, JSENUMERATE_NEXT, &state, + &id, rval) : #endif OBJ_ENUMERATE(cx, iterable, JSENUMERATE_NEXT, &state, &id); @@ -376,17 +375,8 @@ *vp = OBJECT_TO_JSVAL(iterobj); } else { atom = cx->runtime->atomState.iteratorAtom; -#if JS_HAS_XML_SUPPORT - if (OBJECT_IS_XML(cx, obj)) { - if (!js_GetXMLFunction(cx, obj, ATOM_TO_JSID(atom), vp)) - goto bad; - } else -#endif - { - if (!OBJ_GET_PROPERTY(cx, obj, ATOM_TO_JSID(atom), vp)) - goto bad; - } - + if (!js_GetMethod(cx, obj, ATOM_TO_JSID(atom), false, vp)) + goto bad; if (JSVAL_IS_VOID(*vp)) { default_iter: /* @@ -407,18 +397,15 @@ if (!InitNativeIterator(cx, iterobj, obj, flags)) goto bad; } else { + js_LeaveTrace(cx); 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); - } + js_ReportValueError(cx, JSMSG_BAD_ITERATOR_RETURN, + JSDVG_SEARCH_STACK, *vp, NULL); goto bad; } } @@ -449,6 +436,7 @@ } #if JS_HAS_GENERATORS else if (clasp == &js_GeneratorClass) { + JS_ASSERT_NOT_ON_TRACE(cx); if (!CloseGenerator(cx, obj)) return JS_FALSE; } @@ -487,10 +475,8 @@ */ if (obj == origobj && OBJECT_IS_XML(cx, obj)) { if (foreach) { - JSXMLObjectOps *xmlops = (JSXMLObjectOps *) obj->map->ops; - - if (!xmlops->enumerateValues(cx, obj, JSENUMERATE_NEXT, &state, - &id, rval)) { + if (!js_EnumerateXMLValues(cx, obj, JSENUMERATE_NEXT, &state, + &id, rval)) { return JS_FALSE; } } else { @@ -690,7 +676,7 @@ js_TraceStackFrame(trc, &gen->frame); } -JSClass js_GeneratorClass = { +JS_FRIEND_DATA(JSClass) js_GeneratorClass = { js_Generator_str, JSCLASS_HAS_PRIVATE | JSCLASS_IS_ANONYMOUS | JSCLASS_MARK_IS_TRACE | JSCLASS_HAS_CACHED_PROTO(JSProto_Generator), @@ -787,6 +773,8 @@ gen->frame.flags = (fp->flags & ~JSFRAME_ROOTED_ARGV) | JSFRAME_GENERATOR; gen->frame.dormantNext = NULL; gen->frame.xmlNamespace = NULL; + /* JSOP_GENERATOR appears in the prologue, outside all blocks. */ + JS_ASSERT(!fp->blockChain); gen->frame.blockChain = NULL; /* Note that gen is newborn. */ @@ -814,7 +802,7 @@ * Start newborn or restart yielding generator and perform the requested * operation inside its frame. */ -static JSBool +static JS_REQUIRES_STACK JSBool SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj, JSGenerator *gen, jsval arg) { @@ -863,7 +851,7 @@ cx->stackPool.current = arena->next = &gen->arena; /* Push gen->frame around the interpreter activation. */ - fp = cx->fp; + fp = js_GetTopStackFrame(cx); cx->fp = &gen->frame; gen->frame.down = fp; ok = js_Interpret(cx); @@ -904,7 +892,7 @@ return JS_FALSE; } -static JSBool +static JS_REQUIRES_STACK JSBool CloseGenerator(JSContext *cx, JSObject *obj) { JSGenerator *gen; @@ -932,6 +920,8 @@ JSGenerator *gen; jsval arg; + js_LeaveTrace(cx); + obj = JS_THIS_OBJECT(cx, vp); if (!JS_InstanceOf(cx, obj, &js_GeneratorClass, vp + 2)) return JS_FALSE;