Author: [email protected]
Date: Fri Jun 26 04:35:42 2009
New Revision: 2282

Modified:
    branches/bleeding_edge/src/objects.h
    branches/bleeding_edge/src/x64/codegen-x64.cc

Log:
X64 Implementation: Correct type, add VisitCallEval
Review URL: http://codereview.chromium.org/149066

Modified: branches/bleeding_edge/src/objects.h
==============================================================================
--- branches/bleeding_edge/src/objects.h        (original)
+++ branches/bleeding_edge/src/objects.h        Fri Jun 26 04:35:42 2009
@@ -1639,6 +1639,9 @@
    // Garbage collection support.
    static int SizeFor(int length) { return kHeaderSize + length *  
kPointerSize; }

+  // Code Generation support.
+  static int OffsetOfElementAt(int index) { return SizeFor(index); }
+
    // Casting.
    static inline FixedArray* cast(Object* obj);


Modified: branches/bleeding_edge/src/x64/codegen-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/codegen-x64.cc       (original)
+++ branches/bleeding_edge/src/x64/codegen-x64.cc       Fri Jun 26 04:35:42 2009
@@ -504,6 +504,27 @@
  }


+class CallFunctionStub: public CodeStub {
+ public:
+  CallFunctionStub(int argc, InLoopFlag in_loop)
+      : argc_(argc), in_loop_(in_loop) { }
+
+  void Generate(MacroAssembler* masm);
+
+ private:
+  int argc_;
+  InLoopFlag in_loop_;
+
+#ifdef DEBUG
+  void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); }
+#endif
+
+  Major MajorKey() { return CallFunction; }
+  int MinorKey() { return argc_; }
+  InLoopFlag InLoop() { return in_loop_; }
+};
+
+
  void CodeGenerator::VisitAndSpill(Statement* statement) {
    // TODO(X64): No architecture specific code. Move to shared location.
    ASSERT(in_spilled_code());
@@ -2485,8 +2506,64 @@
  }


-void CodeGenerator::VisitCallEval(CallEval* a) {
-  UNIMPLEMENTED();
+void CodeGenerator::VisitCallEval(CallEval* node) {
+  Comment cmnt(masm_, "[ CallEval");
+
+  // In a call to eval, we first call %ResolvePossiblyDirectEval to resolve
+  // the function we need to call and the receiver of the call.
+  // Then we call the resolved function using the given arguments.
+
+  ZoneList<Expression*>* args = node->arguments();
+  Expression* function = node->expression();
+
+  CodeForStatementPosition(node);
+
+  // Prepare the stack for the call to the resolved function.
+  Load(function);
+
+  // Allocate a frame slot for the receiver.
+  frame_->Push(Factory::undefined_value());
+  int arg_count = args->length();
+  for (int i = 0; i < arg_count; i++) {
+    Load(args->at(i));
+  }
+
+  // Prepare the stack for the call to ResolvePossiblyDirectEval.
+  frame_->PushElementAt(arg_count + 1);
+  if (arg_count > 0) {
+    frame_->PushElementAt(arg_count);
+  } else {
+    frame_->Push(Factory::undefined_value());
+  }
+
+  // Resolve the call.
+  Result result =
+      frame_->CallRuntime(Runtime::kResolvePossiblyDirectEval, 2);
+
+  // Touch up the stack with the right values for the function and the
+  // receiver.  Use a scratch register to avoid destroying the result.
+  Result scratch = allocator_->Allocate();
+  ASSERT(scratch.is_valid());
+  __ movl(scratch.reg(),
+          FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(0)));
+  frame_->SetElementAt(arg_count + 1, &scratch);
+
+  // We can reuse the result register now.
+  frame_->Spill(result.reg());
+  __ movl(result.reg(),
+          FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(1)));
+  frame_->SetElementAt(arg_count, &result);
+
+  // Call the function.
+  CodeForSourcePosition(node->position());
+  InLoopFlag in_loop = loop_nesting() > 0 ? IN_LOOP : NOT_IN_LOOP;
+  CallFunctionStub call_function(arg_count, in_loop);
+  result = frame_->CallStub(&call_function, arg_count + 1);
+
+  // Restore the context and overwrite the function on the stack with
+  // the result.
+  frame_->RestoreContextRegister();
+  frame_->SetElementAt(0, &result);
  }


@@ -3742,10 +3819,10 @@
      __ movq(kScratchRegister, slot->var()->name(),  
RelocInfo::EMBEDDED_OBJECT);
      frame_->EmitPush(kScratchRegister);
      if (typeof_state == INSIDE_TYPEOF) {
-      // value =
-      //    frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError,  
2);
+       value =
+         frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
      } else {
-      // value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
+       value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2);
      }

      done.Bind(&value);
@@ -5589,55 +5666,6 @@
  }


-class CallFunctionStub: public CodeStub {
- public:
-  CallFunctionStub(int argc, InLoopFlag in_loop)
-      : argc_(argc), in_loop_(in_loop) { }
-
-  void Generate(MacroAssembler* masm);
-
- private:
-  int argc_;
-  InLoopFlag in_loop_;
-
-#ifdef DEBUG
-  void Print() { PrintF("CallFunctionStub (args %d)\n", argc_); }
-#endif
-
-  Major MajorKey() { return CallFunction; }
-  int MinorKey() { return argc_; }
-  InLoopFlag InLoop() { return in_loop_; }
-};
-
-
-void CallFunctionStub::Generate(MacroAssembler* masm) {
-  Label slow;
-
-  // Get the function to call from the stack.
-  // +2 ~ receiver, return address
-  __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize));
-
-  // Check that the function really is a JavaScript function.
-  __ testl(rdi, Immediate(kSmiTagMask));
-  __ j(zero, &slow);
-  // Goto slow case if we do not have a function.
-  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
-  __ j(not_equal, &slow);
-
-  // Fast-case: Just invoke the function.
-  ParameterCount actual(argc_);
-  __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
-
-  // Slow-case: Non-function called.
-  __ bind(&slow);
-  __ Set(rax, argc_);
-  __ Set(rbx, 0);
-  __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
-  Handle<Code>  
adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
-  __ Jump(adaptor, RelocInfo::CODE_TARGET);
-}
-
-
  // Call the function just below TOS on the stack with the given
  // arguments. The receiver is the TOS.
  void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
@@ -5691,6 +5719,7 @@
    __ TailCallRuntime(ExternalReference(Runtime::kNewArgumentsFast), 3);
  }

+
  void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
    // The key is in rdx and the parameter count is in rax.

@@ -5805,7 +5834,6 @@
  }


-
  void CEntryStub::GenerateCore(MacroAssembler* masm,
                                Label* throw_normal_exception,
                                Label* throw_out_of_memory_exception,
@@ -5954,6 +5982,34 @@
  }


+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  Label slow;
+
+  // Get the function to call from the stack.
+  // +2 ~ receiver, return address
+  __ movq(rdi, Operand(rsp, (argc_ + 2) * kPointerSize));
+
+  // Check that the function really is a JavaScript function.
+  __ testl(rdi, Immediate(kSmiTagMask));
+  __ j(zero, &slow);
+  // Goto slow case if we do not have a function.
+  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+  __ j(not_equal, &slow);
+
+  // Fast-case: Just invoke the function.
+  ParameterCount actual(argc_);
+  __ InvokeFunction(rdi, actual, JUMP_FUNCTION);
+
+  // Slow-case: Non-function called.
+  __ bind(&slow);
+  __ Set(rax, argc_);
+  __ Set(rbx, 0);
+  __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION);
+  Handle<Code>  
adaptor(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
+  __ Jump(adaptor, RelocInfo::CODE_TARGET);
+}
+
+
  void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
    // rax: number of arguments including receiver
    // rbx: pointer to C function  (C callee-saved)
@@ -6248,7 +6304,7 @@
    __ bind(&load_smi_lhs);
    ASSERT(kSmiTagSize == 1);
    ASSERT(kSmiTag == 0);
-  __ lea(kScratchRegister, Operand(lhs, lhs, times_1, 0);
+  __ lea(kScratchRegister, Operand(lhs, lhs, times_1, 0));
    __ push(kScratchRegister);
    __ fild_s(Operand(rsp, 0));
    __ pop(kScratchRegister);

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to