+ m_expressionTooDeep = true;
+ return newTemporary();
+}
+
+void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
+{
+ m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
+}
+
+bool BytecodeGenerator::isArgumentNumber(const Identifier& ident, int argumentNumber)
+{
+ RegisterID* registerID = local(ident).get();
+ if (!registerID || registerID->index() >= 0)
+ return 0;
+ return registerID->index() == CallFrame::argumentOffset(argumentNumber);
+}
+
+void BytecodeGenerator::emitReadOnlyExceptionIfNeeded()
+{
+ if (!isStrictMode())
+ return;
+ emitOpcode(op_throw_static_error);
+ instructions().append(addConstantValue(addStringConstant(Identifier(m_vm, StrictModeReadonlyPropertyWriteError)))->index());
+ instructions().append(false);
+}
+
+void BytecodeGenerator::emitEnumeration(ThrowableExpressionData* node, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack)
+{
+ if (subjectNode->isResolveNode()
+ && willResolveToArguments(static_cast<ResolveNode*>(subjectNode)->identifier())
+ && !symbolTable().slowArguments()) {
+ RefPtr<RegisterID> index = emitLoad(newTemporary(), jsNumber(0));
+
+ LabelScopePtr scope = newLabelScope(LabelScope::Loop);
+ RefPtr<RegisterID> value = emitLoad(newTemporary(), jsUndefined());
+
+ RefPtr<Label> loopCondition = newLabel();
+ RefPtr<Label> loopStart = newLabel();
+ emitJump(loopCondition.get());
+ emitLabel(loopStart.get());
+ emitLoopHint();
+ emitGetArgumentByVal(value.get(), uncheckedRegisterForArguments(), index.get());
+ callBack(*this, value.get());
+
+ emitLabel(scope->continueTarget());
+ emitInc(index.get());
+ emitLabel(loopCondition.get());
+ RefPtr<RegisterID> length = emitGetArgumentsLength(newTemporary(), uncheckedRegisterForArguments());
+ emitJumpIfTrue(emitEqualityOp(op_less, newTemporary(), index.get(), length.get()), loopStart.get());
+ emitLabel(scope->breakTarget());
+ return;
+ }
+
+ LabelScopePtr scope = newLabelScope(LabelScope::Loop);
+ RefPtr<RegisterID> subject = newTemporary();
+ emitNode(subject.get(), subjectNode);
+ RefPtr<RegisterID> iterator = emitGetById(newTemporary(), subject.get(), propertyNames().iteratorPrivateName);
+ {
+ CallArguments args(*this, 0);
+ emitMove(args.thisRegister(), subject.get());
+ emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, node->divot(), node->divotStart(), node->divotEnd());
+ }
+ RefPtr<RegisterID> iteratorNext = emitGetById(newTemporary(), iterator.get(), propertyNames().iteratorNextPrivateName);
+ RefPtr<RegisterID> value = newTemporary();
+ emitLoad(value.get(), jsUndefined());
+
+ emitJump(scope->continueTarget());
+
+ RefPtr<Label> loopStart = newLabel();
+ emitLabel(loopStart.get());
+ emitLoopHint();
+ callBack(*this, value.get());
+ emitLabel(scope->continueTarget());
+ CallArguments nextArguments(*this, 0, 1);
+ emitMove(nextArguments.thisRegister(), iterator.get());
+ emitMove(nextArguments.argumentRegister(0), value.get());
+ emitCall(value.get(), iteratorNext.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd());
+ RefPtr<RegisterID> result = newTemporary();
+ emitJumpIfFalse(emitEqualityOp(op_stricteq, result.get(), value.get(), emitLoad(0, JSValue(vm()->iterationTerminator.get()))), loopStart.get());
+ emitLabel(scope->breakTarget());