| Index: src/x64/lithium-x64.cc
|
| ===================================================================
|
| --- src/x64/lithium-x64.cc (revision 7031)
|
| +++ src/x64/lithium-x64.cc (working copy)
|
| @@ -74,15 +74,13 @@
|
| // Call instructions can use only fixed registers as
|
| // temporaries and outputs because all registers
|
| // are blocked by the calling convention.
|
| - // Inputs can use either fixed register or have a short lifetime (be
|
| - // used at start of the instruction).
|
| + // Inputs must use a fixed register.
|
| ASSERT(Output() == NULL ||
|
| LUnallocated::cast(Output())->HasFixedPolicy() ||
|
| !LUnallocated::cast(Output())->HasRegisterPolicy());
|
| for (UseIterator it(this); it.HasNext(); it.Advance()) {
|
| LOperand* operand = it.Next();
|
| ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
|
| - LUnallocated::cast(operand)->IsUsedAtStart() ||
|
| !LUnallocated::cast(operand)->HasRegisterPolicy());
|
| }
|
| for (TempIterator it(this); it.HasNext(); it.Advance()) {
|
| @@ -298,8 +296,15 @@
|
| }
|
|
|
|
|
| +void LStoreContextSlot::PrintDataTo(StringStream* stream) {
|
| + InputAt(0)->PrintTo(stream);
|
| + stream->Add("[%d] <- ", slot_index());
|
| + InputAt(1)->PrintTo(stream);
|
| +}
|
| +
|
| +
|
| void LCallKeyed::PrintDataTo(StringStream* stream) {
|
| - stream->Add("[ecx] #%d / ", arity());
|
| + stream->Add("[rcx] #%d / ", arity());
|
| }
|
|
|
|
|
| @@ -400,7 +405,7 @@
|
| }
|
|
|
|
|
| -void LStoreNamed::PrintDataTo(StringStream* stream) {
|
| +void LStoreNamedField::PrintDataTo(StringStream* stream) {
|
| object()->PrintTo(stream);
|
| stream->Add(".");
|
| stream->Add(*String::cast(*name())->ToCString());
|
| @@ -409,8 +414,17 @@
|
| }
|
|
|
|
|
| -void LStoreKeyed::PrintDataTo(StringStream* stream) {
|
| +void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
|
| object()->PrintTo(stream);
|
| + stream->Add(".");
|
| + stream->Add(*String::cast(*name())->ToCString());
|
| + stream->Add(" <- ");
|
| + value()->PrintTo(stream);
|
| +}
|
| +
|
| +
|
| +void LStoreKeyedFastElement::PrintDataTo(StringStream* stream) {
|
| + object()->PrintTo(stream);
|
| stream->Add("[");
|
| key()->PrintTo(stream);
|
| stream->Add("] <- ");
|
| @@ -418,6 +432,15 @@
|
| }
|
|
|
|
|
| +void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
|
| + object()->PrintTo(stream);
|
| + stream->Add("[");
|
| + key()->PrintTo(stream);
|
| + stream->Add("] <- ");
|
| + value()->PrintTo(stream);
|
| +}
|
| +
|
| +
|
| void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
|
| LGap* gap = new LGap(block);
|
| int index = -1;
|
| @@ -845,8 +868,14 @@
|
|
|
| LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
|
| HArithmeticBinaryOperation* instr) {
|
| - Abort("Unimplemented: %s", "DoArithmeticD");
|
| - return NULL;
|
| + ASSERT(instr->representation().IsDouble());
|
| + ASSERT(instr->left()->representation().IsDouble());
|
| + ASSERT(instr->right()->representation().IsDouble());
|
| + ASSERT(op != Token::MOD);
|
| + LOperand* left = UseRegisterAtStart(instr->left());
|
| + LOperand* right = UseRegisterAtStart(instr->right());
|
| + LArithmeticD* result = new LArithmeticD(op, left, right);
|
| + return DefineSameAsFirst(result);
|
| }
|
|
|
|
|
| @@ -1075,9 +1104,8 @@
|
| } else if (v->IsInstanceOf()) {
|
| HInstanceOf* instance_of = HInstanceOf::cast(v);
|
| LInstanceOfAndBranch* result =
|
| - new LInstanceOfAndBranch(
|
| - UseFixed(instance_of->left(), InstanceofStub::left()),
|
| - UseFixed(instance_of->right(), InstanceofStub::right()));
|
| + new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax),
|
| + UseFixed(instance_of->right(), rdx));
|
| return MarkAsCall(result, instr);
|
| } else if (v->IsTypeofIs()) {
|
| HTypeofIs* typeof_is = HTypeofIs::cast(v);
|
| @@ -1108,33 +1136,41 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
|
| - Abort("Unimplemented: %s", "DoArgumentsLength");
|
| - return NULL;
|
| + return DefineAsRegister(new LArgumentsLength(Use(length->value())));
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
|
| - Abort("Unimplemented: %s", "DoArgumentsElements");
|
| - return NULL;
|
| + return DefineAsRegister(new LArgumentsElements);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
|
| - Abort("Unimplemented: %s", "DoInstanceOf");
|
| - return NULL;
|
| + LOperand* left = UseFixed(instr->left(), rax);
|
| + LOperand* right = UseFixed(instr->right(), rdx);
|
| + LInstanceOf* result = new LInstanceOf(left, right);
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
|
| HInstanceOfKnownGlobal* instr) {
|
| - Abort("Unimplemented: %s", "DoInstanceOfKnownGlobal");
|
| - return NULL;
|
| + LInstanceOfKnownGlobal* result =
|
| + new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax));
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
|
| - Abort("Unimplemented: %s", "DoApplyArguments");
|
| - return NULL;
|
| + LOperand* function = UseFixed(instr->function(), rdi);
|
| + LOperand* receiver = UseFixed(instr->receiver(), rax);
|
| + LOperand* length = UseFixed(instr->length(), rbx);
|
| + LOperand* elements = UseFixed(instr->elements(), rcx);
|
| + LApplyArguments* result = new LApplyArguments(function,
|
| + receiver,
|
| + length,
|
| + elements);
|
| + return MarkAsCall(DefineFixed(result, rax), instr, CAN_DEOPTIMIZE_EAGERLY);
|
| }
|
|
|
|
|
| @@ -1146,14 +1182,13 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoContext(HContext* instr) {
|
| - Abort("Unimplemented: DoContext");
|
| - return NULL;
|
| + return DefineAsRegister(new LContext);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
|
| - Abort("Unimplemented: DoOuterContext");
|
| - return NULL;
|
| + LOperand* context = UseRegisterAtStart(instr->value());
|
| + return DefineAsRegister(new LOuterContext(context));
|
| }
|
|
|
|
|
| @@ -1175,14 +1210,39 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
|
| - Abort("Unimplemented: %s", "DoUnaryMathOperation");
|
| - return NULL;
|
| + BuiltinFunctionId op = instr->op();
|
| + if (op == kMathLog || op == kMathSin || op == kMathCos) {
|
| + LOperand* input = UseFixedDouble(instr->value(), xmm1);
|
| + LUnaryMathOperation* result = new LUnaryMathOperation(input);
|
| + return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
|
| + } else {
|
| + LOperand* input = UseRegisterAtStart(instr->value());
|
| + LUnaryMathOperation* result = new LUnaryMathOperation(input);
|
| + switch (op) {
|
| + case kMathAbs:
|
| + return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
|
| + case kMathFloor:
|
| + return AssignEnvironment(DefineAsRegister(result));
|
| + case kMathRound:
|
| + return AssignEnvironment(DefineAsRegister(result));
|
| + case kMathSqrt:
|
| + return DefineSameAsFirst(result);
|
| + case kMathPowHalf:
|
| + return DefineSameAsFirst(result);
|
| + default:
|
| + UNREACHABLE();
|
| + return NULL;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
|
| - Abort("Unimplemented: %s", "DoCallKeyed");
|
| - return NULL;
|
| + ASSERT(instr->key()->representation().IsTagged());
|
| + LOperand* key = UseFixed(instr->key(), rcx);
|
| + argument_count_ -= instr->argument_count();
|
| + LCallKeyed* result = new LCallKeyed(key);
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| @@ -1193,8 +1253,8 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
|
| - Abort("Unimplemented: %s", "DoCallGlobal");
|
| - return NULL;
|
| + argument_count_ -= instr->argument_count();
|
| + return MarkAsCall(DefineFixed(new LCallGlobal, rax), instr);
|
| }
|
|
|
|
|
| @@ -1213,8 +1273,9 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
|
| - Abort("Unimplemented: %s", "DoCallFunction");
|
| - return NULL;
|
| + argument_count_ -= instr->argument_count();
|
| + LCallFunction* result = new LCallFunction();
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| @@ -1282,8 +1343,32 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
| - Abort("Unimplemented: %s", "DoMod");
|
| - return NULL;
|
| + if (instr->representation().IsInteger32()) {
|
| + ASSERT(instr->left()->representation().IsInteger32());
|
| + ASSERT(instr->right()->representation().IsInteger32());
|
| + // The temporary operand is necessary to ensure that right is not allocated
|
| + // into edx.
|
| + LOperand* temp = FixedTemp(rdx);
|
| + LOperand* value = UseFixed(instr->left(), rax);
|
| + LOperand* divisor = UseRegister(instr->right());
|
| + LModI* mod = new LModI(value, divisor, temp);
|
| + LInstruction* result = DefineFixed(mod, rdx);
|
| + return (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
|
| + instr->CheckFlag(HValue::kCanBeDivByZero))
|
| + ? AssignEnvironment(result)
|
| + : result;
|
| + } else if (instr->representation().IsTagged()) {
|
| + return DoArithmeticT(Token::MOD, instr);
|
| + } else {
|
| + ASSERT(instr->representation().IsDouble());
|
| + // We call a C function for double modulo. It can't trigger a GC.
|
| + // We need to use fixed result register for the call.
|
| + // TODO(fschneider): Allow any register as input registers.
|
| + LOperand* left = UseFixedDouble(instr->left(), xmm2);
|
| + LOperand* right = UseFixedDouble(instr->right(), xmm1);
|
| + LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
|
| + return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
|
| + }
|
| }
|
|
|
|
|
| @@ -1338,7 +1423,7 @@
|
| }
|
| return result;
|
| } else if (instr->representation().IsDouble()) {
|
| - Abort("Unimplemented: %s", "DoAdd on Doubles");
|
| + return DoArithmeticD(Token::ADD, instr);
|
| } else {
|
| ASSERT(instr->representation().IsTagged());
|
| return DoArithmeticT(Token::ADD, instr);
|
| @@ -1348,8 +1433,22 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoPower(HPower* instr) {
|
| - Abort("Unimplemented: %s", "DoPower");
|
| - return NULL;
|
| + ASSERT(instr->representation().IsDouble());
|
| + // We call a C function for double power. It can't trigger a GC.
|
| + // We need to use fixed result register for the call.
|
| + Representation exponent_type = instr->right()->representation();
|
| + ASSERT(instr->left()->representation().IsDouble());
|
| + LOperand* left = UseFixedDouble(instr->left(), xmm2);
|
| + LOperand* right = exponent_type.IsDouble() ?
|
| + UseFixedDouble(instr->right(), xmm1) :
|
| +#ifdef _WIN64
|
| + UseFixed(instr->right(), rdx);
|
| +#else
|
| + UseFixed(instr->right(), rdi);
|
| +#endif
|
| + LPower* result = new LPower(left, right);
|
| + return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
|
| + CAN_DEOPTIMIZE_EAGERLY);
|
| }
|
|
|
|
|
| @@ -1414,15 +1513,25 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoHasInstanceType(HHasInstanceType* instr) {
|
| - Abort("Unimplemented: %s", "DoHasInstanceType");
|
| + ASSERT(instr->value()->representation().IsTagged());
|
| + LOperand* value = UseRegisterAtStart(instr->value());
|
| +
|
| + return DefineAsRegister(new LHasInstanceType(value));
|
| +}
|
| +
|
| +
|
| +LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
|
| + HGetCachedArrayIndex* instr) {
|
| + Abort("Unimplemented: %s", "DoGetCachedArrayIndex");
|
| return NULL;
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoHasCachedArrayIndex(
|
| HHasCachedArrayIndex* instr) {
|
| - Abort("Unimplemented: %s", "DoHasCachedArrayIndex");
|
| - return NULL;
|
| + ASSERT(instr->value()->representation().IsTagged());
|
| + LOperand* value = UseRegister(instr->value());
|
| + return DefineAsRegister(new LHasCachedArrayIndex(value));
|
| }
|
|
|
|
|
| @@ -1444,9 +1553,16 @@
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) {
|
| + LOperand* array = UseRegisterAtStart(instr->value());
|
| + return DefineAsRegister(new LPixelArrayLength(array));
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
|
| - Abort("Unimplemented: %s", "DoValueOf");
|
| - return NULL;
|
| + LOperand* object = UseRegister(instr->value());
|
| + LValueOf* result = new LValueOf(object);
|
| + return AssignEnvironment(DefineSameAsFirst(result));
|
| }
|
|
|
|
|
| @@ -1504,12 +1620,8 @@
|
| return AssignPointerMap(Define(result, result_temp));
|
| } else {
|
| ASSERT(to.IsInteger32());
|
| - bool needs_temp = instr->CanTruncateToInt32() &&
|
| - !Isolate::Current()->cpu_features()->IsSupported(SSE3);
|
| - LOperand* value = needs_temp ?
|
| - UseTempRegister(instr->value()) : UseRegister(instr->value());
|
| - LOperand* temp = needs_temp ? TempRegister() : NULL;
|
| - return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
|
| + LOperand* value = UseRegister(instr->value());
|
| + return AssignEnvironment(DefineAsRegister(new LDoubleToI(value)));
|
| }
|
| } else if (from.IsInteger32()) {
|
| if (to.IsTagged()) {
|
| @@ -1607,14 +1719,23 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
|
| - Abort("Unimplemented: %s", "DoLoadContextSlot");
|
| - return NULL;
|
| + LOperand* context = UseRegisterAtStart(instr->value());
|
| + return DefineAsRegister(new LLoadContextSlot(context));
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
|
| - Abort("Unimplemented: DoStoreContextSlot");
|
| - return NULL;
|
| + Abort("Unimplemented: DoStoreContextSlot"); // Temporarily disabled (whesse).
|
| + LOperand* context;
|
| + LOperand* value;
|
| + if (instr->NeedsWriteBarrier()) {
|
| + context = UseTempRegister(instr->context());
|
| + value = UseTempRegister(instr->value());
|
| + } else {
|
| + context = UseRegister(instr->context());
|
| + value = UseRegister(instr->value());
|
| + }
|
| + return new LStoreContextSlot(context, value);
|
| }
|
|
|
|
|
| @@ -1634,17 +1755,24 @@
|
|
|
| LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
|
| HLoadFunctionPrototype* instr) {
|
| - Abort("Unimplemented: %s", "DoLoadFunctionPrototype");
|
| - return NULL;
|
| + return AssignEnvironment(DefineAsRegister(
|
| + new LLoadFunctionPrototype(UseRegister(instr->function()))));
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
|
| LOperand* input = UseRegisterAtStart(instr->value());
|
| - return DefineSameAsFirst(new LLoadElements(input));
|
| + return DefineAsRegister(new LLoadElements(input));
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer(
|
| + HLoadPixelArrayExternalPointer* instr) {
|
| + LOperand* input = UseRegisterAtStart(instr->value());
|
| + return DefineAsRegister(new LLoadPixelArrayExternalPointer(input));
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
|
| HLoadKeyedFastElement* instr) {
|
| ASSERT(instr->representation().IsTagged());
|
| @@ -1656,9 +1784,25 @@
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
|
| + HLoadPixelArrayElement* instr) {
|
| + ASSERT(instr->representation().IsInteger32());
|
| + ASSERT(instr->key()->representation().IsInteger32());
|
| + LOperand* external_pointer =
|
| + UseRegisterAtStart(instr->external_pointer());
|
| + LOperand* key = UseRegisterAtStart(instr->key());
|
| + LLoadPixelArrayElement* result =
|
| + new LLoadPixelArrayElement(external_pointer, key);
|
| + return DefineSameAsFirst(result);
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
|
| - Abort("Unimplemented: %s", "DoLoadKeyedGeneric");
|
| - return NULL;
|
| + LOperand* object = UseFixed(instr->object(), rdx);
|
| + LOperand* key = UseFixed(instr->key(), rax);
|
| +
|
| + LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key);
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| @@ -1681,9 +1825,31 @@
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoStorePixelArrayElement(
|
| + HStorePixelArrayElement* instr) {
|
| + ASSERT(instr->value()->representation().IsInteger32());
|
| + ASSERT(instr->external_pointer()->representation().IsExternal());
|
| + ASSERT(instr->key()->representation().IsInteger32());
|
| +
|
| + LOperand* external_pointer = UseRegister(instr->external_pointer());
|
| + LOperand* val = UseTempRegister(instr->value());
|
| + LOperand* key = UseRegister(instr->key());
|
| +
|
| + return new LStorePixelArrayElement(external_pointer, key, val);
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
|
| - Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
|
| - return NULL;
|
| + LOperand* object = UseFixed(instr->object(), rdx);
|
| + LOperand* key = UseFixed(instr->key(), rcx);
|
| + LOperand* value = UseFixed(instr->value(), rax);
|
| +
|
| + ASSERT(instr->object()->representation().IsTagged());
|
| + ASSERT(instr->key()->representation().IsTagged());
|
| + ASSERT(instr->value()->representation().IsTagged());
|
| +
|
| + LStoreKeyedGeneric* result = new LStoreKeyedGeneric(object, key, value);
|
| + return MarkAsCall(result, instr);
|
| }
|
|
|
|
|
| @@ -1708,20 +1874,25 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
|
| - Abort("Unimplemented: %s", "DoStoreNamedGeneric");
|
| - return NULL;
|
| + LOperand* object = UseFixed(instr->object(), rdx);
|
| + LOperand* value = UseFixed(instr->value(), rax);
|
| +
|
| + LStoreNamedGeneric* result = new LStoreNamedGeneric(object, value);
|
| + return MarkAsCall(result, instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
|
| - Abort("Unimplemented: %s", "DoStringCharCodeAt");
|
| - return NULL;
|
| + LOperand* string = UseRegister(instr->string());
|
| + LOperand* index = UseRegisterOrConstant(instr->index());
|
| + LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
|
| + return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
|
| - Abort("Unimplemented: %s", "DoStringLength");
|
| - return NULL;
|
| + LOperand* string = UseRegisterAtStart(instr->value());
|
| + return DefineAsRegister(new LStringLength(string));
|
| }
|
|
|
|
|
| @@ -1736,8 +1907,7 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
|
| - Abort("Unimplemented: %s", "DoRegExpLiteral");
|
| - return NULL;
|
| + return MarkAsCall(DefineFixed(new LRegExpLiteral, rax), instr);
|
| }
|
|
|
|
|
| @@ -1747,14 +1917,16 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
|
| - Abort("Unimplemented: %s", "DoDeleteProperty");
|
| - return NULL;
|
| + LDeleteProperty* result =
|
| + new LDeleteProperty(Use(instr->object()), UseOrConstant(instr->key()));
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
|
| - Abort("Unimplemented: %s", "DoOsrEntry");
|
| - return NULL;
|
| + allocator_->MarkAsOsrEntry();
|
| + current_block_->last_environment()->set_ast_id(instr->ast_id());
|
| + return AssignEnvironment(new LOsrEntry);
|
| }
|
|
|
|
|
| @@ -1765,8 +1937,8 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
|
| - Abort("Unimplemented: %s", "DoUnknownOSRValue");
|
| - return NULL;
|
| + int spill_index = chunk()->GetNextSpillIndex(false); // Not double-width.
|
| + return DefineAsSpilled(new LUnknownOSRValue, spill_index);
|
| }
|
|
|
|
|
| @@ -1777,26 +1949,31 @@
|
|
|
|
|
| LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
|
| - Abort("Unimplemented: %s", "DoArgumentsObject");
|
| + // There are no real uses of the arguments object.
|
| + // arguments.length and element access are supported directly on
|
| + // stack arguments, and any real arguments object use causes a bailout.
|
| + // So this value is never used.
|
| return NULL;
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
|
| - Abort("Unimplemented: %s", "DoAccessArgumentsAt");
|
| - return NULL;
|
| + LOperand* arguments = UseRegister(instr->arguments());
|
| + LOperand* length = UseTempRegister(instr->length());
|
| + LOperand* index = Use(instr->index());
|
| + LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
|
| + return AssignEnvironment(DefineAsRegister(result));
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
|
| - Abort("Unimplemented: %s", "DoTypeof");
|
| - return NULL;
|
| + LTypeof* result = new LTypeof(UseAtStart(instr->value()));
|
| + return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
|
| - Abort("Unimplemented: %s", "DoTypeofIs");
|
| - return NULL;
|
| + return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
|
| }
|
|
|
|
|
|
|