]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSArrayIterator.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / JSArrayIterator.cpp
index c6220f5f9916cd1767c5f72496b1c1d7abe59e44..0abc9d120fb01bac220232761aeabb09e70a3320 100644 (file)
 
 namespace JSC {
 
-const ClassInfo JSArrayIterator::s_info = { "ArrayIterator", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSArrayIterator) };
+const ClassInfo JSArrayIterator::s_info = { "Array Iterator", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayIterator) };
 
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(ExecState*);
-static EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(ExecState*);
-
-void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject* globalObject, ArrayIterationKind kind, JSObject* iteratedObject)
+void JSArrayIterator::finishCreation(VM& vm, JSGlobalObject*, ArrayIterationKind kind, JSObject* iteratedObject)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(info()));
-    m_iterationKind = kind;
-    m_iteratedObject.set(vm, this, iteratedObject);
-    switch (kind) {
-    case ArrayIterateKey:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextKey, DontEnum, 0, ArrayIteratorNextKeyIntrinsic);
-        break;
-    case ArrayIterateValue:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextValue, DontEnum, 0, ArrayIteratorNextValueIntrinsic);
-        break;
-    default:
-        JSC_NATIVE_INTRINSIC_FUNCTION(vm.propertyNames->iteratorNextPrivateName, arrayIteratorNextGeneric, DontEnum, 0, ArrayIteratorNextGenericIntrinsic);
-        break;
-    }
 
+    putDirect(vm, vm.propertyNames->iteratedObjectPrivateName, iteratedObject);
+    putDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName, jsNumber(0));
+    putDirect(vm, vm.propertyNames->arrayIterationKindPrivateName, jsNumber(kind));
 }
-    
-    
-void JSArrayIterator::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    JSArrayIterator* thisObject = jsCast<JSArrayIterator*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
-    ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
-        
-    Base::visitChildren(thisObject, visitor);
-    visitor.append(&thisObject->m_iteratedObject);
 
-}
-
-static EncodedJSValue createIteratorResult(CallFrame* callFrame, ArrayIterationKind kind, size_t index, JSValue result, bool done)
+ArrayIterationKind JSArrayIterator::kind(ExecState* exec) const
 {
-    if (done)
-        return JSValue::encode(callFrame->vm().iterationTerminator.get());
-    
-    switch (kind & ~ArrayIterateSparseTag) {
-    case ArrayIterateKey:
-        return JSValue::encode(jsNumber(index));
-        
-    case ArrayIterateValue:
-        return JSValue::encode(result);
-        
-    case ArrayIterateKeyValue: {
-        MarkedArgumentBuffer args;
-        args.append(jsNumber(index));
-        args.append(result);
-        JSGlobalObject* globalObject = callFrame->callee()->globalObject();
-        return JSValue::encode(constructArray(callFrame, 0, globalObject, args));
-        
-    }
-    default:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-    return JSValue::encode(JSValue());
+    JSValue kindValue = getDirect(exec->vm(), exec->vm().propertyNames->arrayIterationKindPrivateName);
+    return static_cast<ArrayIterationKind>(kindValue.asInt32());
 }
 
-static inline EncodedJSValue JSC_HOST_CALL arrayIteratorNext(CallFrame* callFrame)
-{
-    JSArrayIterator* iterator = jsDynamicCast<JSArrayIterator*>(callFrame->thisValue());
-    if (!iterator) {
-        ASSERT_NOT_REACHED();
-        return JSValue::encode(throwTypeError(callFrame, ASCIILiteral("Cannot call ArrayIterator.next() on a non-ArrayIterator object")));
-    }
-    JSObject* iteratedObject = iterator->iteratedObject();
-    size_t index = iterator->nextIndex();
-    ArrayIterationKind kind = iterator->iterationKind();
-    JSValue jsLength = JSValue(iteratedObject).get(callFrame, callFrame->propertyNames().length);
-    if (callFrame->hadException())
-        return JSValue::encode(jsNull());
-    
-    size_t length = jsLength.toUInt32(callFrame);
-    if (callFrame->hadException())
-        return JSValue::encode(jsNull());
-    
-    if (index >= length) {
-        iterator->finish();
-        return createIteratorResult(callFrame, kind, index, jsUndefined(), true);
-    }
-    if (JSValue result = iteratedObject->tryGetIndexQuickly(index)) {
-        iterator->setNextIndex(index + 1);
-        return createIteratorResult(callFrame, kind, index, result, false);
-    }
-    
-    JSValue result = jsUndefined();
-    PropertySlot slot(iteratedObject);
-    if (kind > ArrayIterateSparseTag) {
-        // We assume that the indexed property will be an own property so cache the getOwnProperty
-        // method locally
-        auto getOwnPropertySlotByIndex = iteratedObject->methodTable()->getOwnPropertySlotByIndex;
-        while (index < length) {
-            if (getOwnPropertySlotByIndex(iteratedObject, callFrame, index, slot)) {
-                result = slot.getValue(callFrame, index);
-                break;
-            }
-            if (iteratedObject->getPropertySlot(callFrame, index, slot)) {
-                result = slot.getValue(callFrame, index);
-                break;
-            }
-            index++;
-        }
-    } else if (iteratedObject->getPropertySlot(callFrame, index, slot))
-        result = slot.getValue(callFrame, index);
-    
-    if (index == length)
-        iterator->finish();
-    else
-        iterator->setNextIndex(index + 1);
-    return createIteratorResult(callFrame, kind, index, jsUndefined(), index == length);
-}
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextKey(CallFrame* callFrame)
-{
-    return arrayIteratorNext(callFrame);
-}
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextValue(CallFrame* callFrame)
+JSValue JSArrayIterator::iteratedValue(ExecState* exec) const
 {
-    return arrayIteratorNext(callFrame);
+    return getDirect(exec->vm(), exec->vm().propertyNames->iteratedObjectPrivateName);
 }
-    
-EncodedJSValue JSC_HOST_CALL arrayIteratorNextGeneric(CallFrame* callFrame)
+
+JSArrayIterator* JSArrayIterator::clone(ExecState* exec)
 {
-    return arrayIteratorNext(callFrame);
+    VM& vm = exec->vm();
+    JSValue iteratedObject = getDirect(vm, vm.propertyNames->iteratedObjectPrivateName);
+    JSValue nextIndex = getDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName);
+
+    auto clone = JSArrayIterator::create(exec, exec->callee()->globalObject()->arrayIteratorStructure(), kind(exec), asObject(iteratedObject));
+    clone->putDirect(vm, vm.propertyNames->arrayIteratorNextIndexPrivateName, nextIndex);
+    return clone;
 }
 
 }