| Index: src/x64/lithium-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/lithium-codegen-x64.cc (revision 6713)
|
| +++ src/x64/lithium-codegen-x64.cc (working copy)
|
| @@ -1721,7 +1721,44 @@
|
|
|
|
|
| void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
|
| - Abort("Unimplemented: %s", "DoLoadFunctionPrototype");
|
| + Register function = ToRegister(instr->function());
|
| + Register result = ToRegister(instr->result());
|
| +
|
| + // Check that the function really is a function.
|
| + __ CmpObjectType(function, JS_FUNCTION_TYPE, result);
|
| + DeoptimizeIf(not_equal, instr->environment());
|
| +
|
| + // Check whether the function has an instance prototype.
|
| + NearLabel non_instance;
|
| + __ testb(FieldOperand(result, Map::kBitFieldOffset),
|
| + Immediate(1 << Map::kHasNonInstancePrototype));
|
| + __ j(not_zero, &non_instance);
|
| +
|
| + // Get the prototype or initial map from the function.
|
| + __ movq(result,
|
| + FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
|
| +
|
| + // Check that the function has a prototype or an initial map.
|
| + __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
|
| + DeoptimizeIf(equal, instr->environment());
|
| +
|
| + // If the function does not have an initial map, we're done.
|
| + NearLabel done;
|
| + __ CmpObjectType(result, MAP_TYPE, kScratchRegister);
|
| + __ j(not_equal, &done);
|
| +
|
| + // Get the prototype from the initial map.
|
| + __ movq(result, FieldOperand(result, Map::kPrototypeOffset));
|
| + __ jmp(&done);
|
| +
|
| + // Non-instance prototype: Fetch prototype from constructor field
|
| + // in the function's map.
|
| + __ bind(&non_instance);
|
| + __ movq(result, FieldOperand(result, Map::kConstructorOffset));
|
| +
|
| + // All done.
|
| + __ bind(&done);
|
| +
|
| }
|
|
|
|
|
| @@ -1809,6 +1846,12 @@
|
| }
|
|
|
|
|
| +void LCodeGen::DoContext(LContext* instr) {
|
| + Register result = ToRegister(instr->result());
|
| + __ movq(result, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoGlobalObject(LGlobalObject* instr) {
|
| Register result = ToRegister(instr->result());
|
| __ movq(result, GlobalObjectOperand());
|
| @@ -1926,7 +1969,13 @@
|
|
|
|
|
| void LCodeGen::DoCallNamed(LCallNamed* instr) {
|
| - Abort("Unimplemented: %s", "DoCallNamed");
|
| + ASSERT(ToRegister(instr->result()).is(rax));
|
| +
|
| + int arity = instr->arity();
|
| + Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP);
|
| + __ Move(rcx, instr->name());
|
| + CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
| + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| }
|
|
|
|
|
| @@ -1936,7 +1985,12 @@
|
|
|
|
|
| void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
|
| - Abort("Unimplemented: %s", "DoCallGlobal");
|
| + ASSERT(ToRegister(instr->result()).is(rax));
|
| + int arity = instr->arity();
|
| + Handle<Code> ic = StubCache::ComputeCallInitialize(arity, NOT_IN_LOOP);
|
| + __ Move(rcx, instr->name());
|
| + CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr);
|
| + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| }
|
|
|
|
|
|
|