Version 3.24.11

Remove generated makefiles on linux when running gyp_v8 (Chromium issue 331475)

Fix building d8 with readline support due to API changes

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@18467 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index c095881..f5d43b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-01-07: Version 3.24.11
+
+        Remove generated makefiles on linux when running gyp_v8
+        (Chromium issue 331475)
+
+        Fix building d8 with readline support due to API changes
+
+        Performance and stability improvements on all platforms.
+
+
 2014-01-03: Version 3.24.10
 
         Reland r18383: More API cleanup (Chromium issue 324225).
diff --git a/build/gyp_v8 b/build/gyp_v8
index ddf88ce..f2a60d1 100755
--- a/build/gyp_v8
+++ b/build/gyp_v8
@@ -159,6 +159,9 @@
   # Generate for the architectures supported on the given platform.
   gyp_args = list(args)
   if platform.system() == 'Linux':
+    # Work around for crbug.com/331475.
+    for f in glob.glob(os.path.join(v8_root, 'out', 'Makefile.*')):
+      os.unlink(f)
     # --generator-output defines where the Makefile goes.
     gyp_args.append('--generator-output=out')
     # -Goutput_dir defines where the build output goes, relative to the
diff --git a/include/v8.h b/include/v8.h
index c073fb3..1771969 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -738,7 +738,7 @@
 template<class T>
 class UniquePersistent : public PersistentBase<T> {
   struct RValue {
-    V8_INLINE explicit RValue(UniquePersistent* object) : object(object) {}
+    V8_INLINE explicit RValue(UniquePersistent* obj) : object(obj) {}
     UniquePersistent* object;
   };
 
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 5a47ef4..6c374b3 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -34,6 +34,7 @@
 #include "deoptimizer.h"
 #include "full-codegen.h"
 #include "runtime.h"
+#include "stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -1091,12 +1092,8 @@
     // Use the global receiver object from the called function as the
     // receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalIndex =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ ldr(r2, FieldMemOperand(cp, kGlobalIndex));
-    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
-    __ ldr(r2, FieldMemOperand(r2, kGlobalIndex));
-    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
+  __ ldr(r2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+  __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
 
     __ bind(&patch_receiver);
     __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2));
@@ -1287,11 +1284,7 @@
 
     // Use the current global receiver object as the receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalOffset =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ ldr(r0, FieldMemOperand(cp, kGlobalOffset));
-    __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset));
-    __ ldr(r0, FieldMemOperand(r0, kGlobalOffset));
+    __ ldr(r0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
     __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
 
     // Push the receiver.
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index f70271b..8af47b7 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -3182,31 +3182,47 @@
   // r2 : cache cell for call target
   Label slow, non_function;
 
-  // The receiver might implicitly be the global object. This is
-  // indicated by passing the hole as the receiver to the call
-  // function stub.
-  if (ReceiverMightBeImplicit()) {
-    Label call;
-    // Get the receiver from the stack.
-    // function, receiver [, arguments]
-    __ ldr(r4, MemOperand(sp, argc_ * kPointerSize));
-    // Call as function is indicated with the hole.
-    __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
-    __ b(ne, &call);
-    // Patch the receiver on the stack with the global receiver object.
-    __ ldr(r3,
-           MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
-    __ ldr(r3, FieldMemOperand(r3, GlobalObject::kGlobalReceiverOffset));
-    __ str(r3, MemOperand(sp, argc_ * kPointerSize));
-    __ bind(&call);
-  }
-
   // Check that the function is really a JavaScript function.
   // r1: pushed function (to be verified)
   __ JumpIfSmi(r1, &non_function);
-  // Get the map of the function object.
-  __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
-  __ b(ne, &slow);
+
+  // The receiver might implicitly be the global object. This is
+  // indicated by passing the hole as the receiver to the call
+  // function stub.
+  if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
+    Label try_call, call, patch_current_context;
+    if (ReceiverMightBeImplicit()) {
+      // Get the receiver from the stack.
+      // function, receiver [, arguments]
+      __ ldr(r4, MemOperand(sp, argc_ * kPointerSize));
+      // Call as function is indicated with the hole.
+      __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
+      __ b(ne, &try_call);
+    }
+    // Patch the receiver on the stack with the global receiver object.
+    // Goto slow case if we do not have a function.
+    __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
+    __ b(ne, &patch_current_context);
+    CallStubCompiler::FetchGlobalProxy(masm, r3, r1);
+    __ str(r3, MemOperand(sp, argc_ * kPointerSize));
+    __ jmp(&call);
+
+    __ bind(&patch_current_context);
+    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+    __ str(r4, MemOperand(sp, argc_ * kPointerSize));
+    __ jmp(&slow);
+
+    __ bind(&try_call);
+    // Get the map of the function object.
+    __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
+    __ b(ne, &slow);
+
+    __ bind(&call);
+  } else {
+    // Get the map of the function object.
+    __ CompareObjectType(r1, r3, r3, JS_FUNCTION_TYPE);
+    __ b(ne, &slow);
+  }
 
   if (RecordCallTarget()) {
     GenerateRecordCallTarget(masm);
@@ -3251,7 +3267,7 @@
   __ mov(r0, Operand(argc_ + 1, RelocInfo::NONE32));
   __ mov(r2, Operand::Zero());
   __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
-  __ SetCallKind(r5, CALL_AS_METHOD);
+  __ SetCallKind(r5, CALL_AS_FUNCTION);
   {
     Handle<Code> adaptor =
       masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index b362f12..da7eb99 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -2815,12 +2815,12 @@
     { PreservePositionScope scope(masm()->positions_recorder());
       VisitForStackValue(callee);
     }
-    // Load global receiver object.
-    __ ldr(r1, GlobalObjectOperand());
-    __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalReceiverOffset));
+    // Push the hole as receiver.
+    // It will be correctly replaced in the call stub.
+    __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
     __ push(r1);
     // Emit function call.
-    EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
+    EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT);
   }
 
 #ifdef DEBUG
diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
index ea247b3..a8943e1 100644
--- a/src/arm/ic-arm.cc
+++ b/src/arm/ic-arm.cc
@@ -491,7 +491,7 @@
 
     // Patch the receiver on the stack.
     __ bind(&global);
-    __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, r2, r1);
     __ str(r2, MemOperand(sp, argc * kPointerSize));
     __ bind(&invoke);
   }
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 0463ce4..c58fdb1 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3491,11 +3491,8 @@
   __ b(&result_in_receiver);
 
   __ bind(&global_object);
+  CallStubCompiler::FetchGlobalProxy(masm(), receiver, function);
 
-  __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  __ ldr(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
-  __ ldr(result,
-         FieldMemOperand(result, JSGlobalObject::kGlobalReceiverOffset));
   if (result.is(receiver)) {
     __ bind(&result_in_receiver);
   } else {
@@ -3993,7 +3990,10 @@
   ASSERT(ToRegister(instr->result()).is(r0));
 
   int arity = instr->arity();
-  CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
+  CallFunctionFlags flags =
+      instr->hydrogen()->IsContextualCall() ?
+          RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
+  CallFunctionStub stub(arity, flags);
   if (instr->hydrogen()->IsTailCall()) {
     if (NeedsEagerFrame()) __ mov(sp, fp);
     __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 4d9fc0d..5350b6b 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -2341,11 +2341,23 @@
 }
 
 
-void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Handle<JSFunction> function) {
   if (object->IsGlobalObject()) {
     const int argc = arguments().immediate();
     const int receiver_offset = argc * kPointerSize;
-    __ ldr(r3, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset));
+    __ Move(r3, handle(function->context()->global_proxy()));
+    __ str(r3, MemOperand(sp, receiver_offset));
+  }
+}
+
+
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Register function) {
+  if (object->IsGlobalObject()) {
+    FetchGlobalProxy(masm(), r3, function);
+    const int argc = arguments().immediate();
+    const int receiver_offset = argc * kPointerSize;
     __ str(r3, MemOperand(sp, receiver_offset));
   }
 }
@@ -2444,7 +2456,7 @@
   ASSERT(function.is(r1));
   // Check that the function really is a function.
   GenerateFunctionCheck(function, r3, miss);
-  PatchGlobalProxy(object);
+  PatchGlobalProxy(object, function);
 
   // Invoke the function.
   __ InvokeFunction(r1, arguments(), JUMP_FUNCTION,
@@ -2562,6 +2574,15 @@
 #define __ ACCESS_MASM(masm)
 
 
+void CallStubCompiler::FetchGlobalProxy(MacroAssembler* masm,
+                                        Register target,
+                                        Register function) {
+  __ ldr(target, FieldMemOperand(function, JSFunction::kContextOffset));
+  __ ldr(target, ContextOperand(target, Context::GLOBAL_OBJECT_INDEX));
+  __ ldr(target, FieldMemOperand(target, GlobalObject::kGlobalReceiverOffset));
+}
+
+
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
     Handle<JSFunction> setter) {
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index f27ca7a..7b8af06 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1669,6 +1669,8 @@
   builtins->set_native_context(*native_context());
   builtins->set_global_context(*native_context());
   builtins->set_global_receiver(*builtins);
+  builtins->set_global_receiver(native_context()->global_proxy());
+
 
   // Set up the 'global' properties of the builtins object. The
   // 'global' property that refers to the global object is the only
@@ -1682,6 +1684,11 @@
   CHECK_NOT_EMPTY_HANDLE(isolate(),
                          JSObject::SetLocalPropertyIgnoreAttributes(
                              builtins, global_string, global_obj, attributes));
+  Handle<String> builtins_string =
+      factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("builtins"));
+  CHECK_NOT_EMPTY_HANDLE(isolate(),
+                         JSObject::SetLocalPropertyIgnoreAttributes(
+                             builtins, builtins_string, builtins, attributes));
 
   // Set up the reference from the global object to the builtins object.
   JSGlobalObject::cast(native_context()->global_object())->
@@ -2581,6 +2588,8 @@
 
     HookUpGlobalProxy(inner_global, global_proxy);
     HookUpInnerGlobal(inner_global);
+    native_context()->builtins()->set_global_receiver(
+        native_context()->global_proxy());
 
     if (!ConfigureGlobalObjects(global_template)) return;
   } else {
diff --git a/src/code-stubs.h b/src/code-stubs.h
index bb9ff78..3c3c194 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -1550,8 +1550,8 @@
   virtual void PrintName(StringStream* stream);
 
   // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
-  class FlagBits: public BitField<CallFunctionFlags, 0, 2> {};
-  class ArgcBits: public BitField<unsigned, 2, 32 - 2> {};
+  class FlagBits: public BitField<CallFunctionFlags, 0, 3> {};
+  class ArgcBits: public BitField<unsigned, 3, 32 - 3> {};
 
   Major MajorKey() { return CallFunction; }
   int MinorKey() {
@@ -1563,6 +1563,10 @@
     return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0;
   }
 
+  bool ReceiverIsImplicit() {
+    return (flags_ & RECEIVER_IS_IMPLICIT) != 0;
+  }
+
   bool RecordCallTarget() {
     return (flags_ & RECORD_CALL_TARGET) != 0;
   }
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 0cd1cc2..2c909fa 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -30,6 +30,7 @@
 #include "d8.h"
 #include "d8-debug.h"
 #include "debug-agent.h"
+#include "platform/socket.h"
 
 
 namespace v8 {
diff --git a/src/d8-readline.cc b/src/d8-readline.cc
index 15b1361..42cb0c5 100644
--- a/src/d8-readline.cc
+++ b/src/d8-readline.cc
@@ -163,7 +163,7 @@
     completions = Local<Array>::New(isolate, current_completions);
   }
   if (current_index < completions->Length()) {
-    Handle<Integer> index = Integer::New(current_index);
+    Handle<Integer> index = Integer::New(isolate, current_index);
     Handle<Value> str_obj = completions->Get(index);
     current_index++;
     String::Utf8Value str(str_obj);
diff --git a/src/debug.h b/src/debug.h
index d1b3b23..564f9e8 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -38,7 +38,6 @@
 #include "frames-inl.h"
 #include "hashmap.h"
 #include "platform.h"
-#include "platform/socket.h"
 #include "string-stream.h"
 #include "v8threads.h"
 
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index a32a418..71ae304 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2414,7 +2414,8 @@
 
 enum CallMode {
   NORMAL_CALL,
-  TAIL_CALL
+  TAIL_CALL,
+  NORMAL_CONTEXTUAL_CALL
 };
 
 
@@ -2425,7 +2426,7 @@
       HCallFunction, HValue*, int, CallMode);
 
   bool IsTailCall() const { return call_mode_ == TAIL_CALL; }
-
+  bool IsContextualCall() const { return call_mode_ == NORMAL_CONTEXTUAL_CALL; }
   HValue* context() { return first(); }
   HValue* function() { return second(); }
 
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 7bdc02f..03e666c 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -7618,6 +7618,27 @@
 }
 
 
+void HOptimizedGraphBuilder::InstallGlobalReceiverInExpressionStack(
+    int receiver_index,
+    Handle<JSFunction> function) {
+  // TODO(dcarney): Fix deserializer to be able to hookup the global receiver
+  // and object during deserialization and embed the global receiver here
+  // directly.
+  // Install global receiver on stack.
+  HValue* function_constant = Add<HConstant>(function);
+  HValue* context = Add<HLoadNamedField>(
+      function_constant,
+      HObjectAccess::ForJSObjectOffset(JSFunction::kContextOffset));
+  HValue* global_object = Add<HLoadNamedField>(
+      context,
+      HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
+  HValue* global_receiver = Add<HLoadNamedField>(
+      global_object,
+      HObjectAccess::ForJSObjectOffset(GlobalObject::kGlobalReceiverOffset));
+  environment()->SetExpressionStackAt(receiver_index, global_receiver);
+}
+
+
 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
@@ -7738,13 +7759,11 @@
         HValue* function = Pop();
         Add<HCheckValue>(function, expr->target());
 
-        // Replace the global object with the global receiver.
-        HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object);
-        // Index of the receiver from the top of the expression stack.
+        // Install global receiver on stack.
         const int receiver_index = argument_count - 1;
         ASSERT(environment()->ExpressionStackAt(receiver_index)->
                IsGlobalObject());
-        environment()->SetExpressionStackAt(receiver_index, global_receiver);
+        InstallGlobalReceiverInExpressionStack(receiver_index, expr->target());
 
         if (TryInlineBuiltinFunctionCall(expr, false)) {  // Nothing to drop.
           if (FLAG_trace_inlining) {
@@ -7761,9 +7780,12 @@
         }
 
         if (CallStubCompiler::HasCustomCallGenerator(expr->target())) {
+          // We're about to install a contextual IC, which expects the global
+          // object as receiver rather than the global proxy.
+          environment()->SetExpressionStackAt(receiver_index, global_object);
           // When the target has a custom call IC generator, use the IC,
           // because it is likely to generate better code.
-          call = PreProcessCall(New<HCallNamed>(var->name(), argument_count));
+          call = PreProcessCall(New<HCallGlobal>(var->name(), argument_count));
         } else {
           call = PreProcessCall(New<HCallKnownGlobal>(
               expr->target(), argument_count));
@@ -7788,6 +7810,12 @@
       CHECK_ALIVE(VisitExpressions(expr->arguments()));
       Add<HCheckValue>(function, expr->target());
 
+      // Install global receiver on stack.
+      const int receiver_index = argument_count - 1;
+      ASSERT(environment()->ExpressionStackAt(receiver_index)->
+             IsGlobalReceiver());
+      InstallGlobalReceiverInExpressionStack(receiver_index, expr->target());
+
       if (TryInlineBuiltinFunctionCall(expr, true)) {  // Drop the function.
         if (FLAG_trace_inlining) {
           PrintF("Inlining builtin ");
@@ -7808,12 +7836,11 @@
     } else {
       CHECK_ALIVE(VisitForValue(expr->expression()));
       HValue* function = Top();
-      HGlobalObject* global_object = Add<HGlobalObject>();
-      HGlobalReceiver* receiver = Add<HGlobalReceiver>(global_object);
+      HValue* receiver = graph()->GetConstantHole();
       Push(Add<HPushArgument>(receiver));
       CHECK_ALIVE(VisitArgumentList(expr->arguments()));
-
-      call = New<HCallFunction>(function, argument_count);
+      call = New<HCallFunction>(
+          function, argument_count, NORMAL_CONTEXTUAL_CALL);
       Drop(argument_count + 1);
     }
   }
diff --git a/src/hydrogen.h b/src/hydrogen.h
index ca3fb43..2af2469 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -2502,6 +2502,9 @@
                                 HValue* receiver,
                                 Handle<Map> receiver_map);
 
+  void InstallGlobalReceiverInExpressionStack(int index,
+                                              Handle<JSFunction> function);
+
   // The translation state of the currently-being-translated function.
   FunctionState* function_state_;
 
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 1f73a7d..67503e3 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -32,6 +32,7 @@
 #include "codegen.h"
 #include "deoptimizer.h"
 #include "full-codegen.h"
+#include "stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -783,12 +784,7 @@
     // Use the global receiver object from the called function as the
     // receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalIndex =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ mov(ebx, FieldOperand(esi, kGlobalIndex));
-    __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
-    __ mov(ebx, FieldOperand(ebx, kGlobalIndex));
-    __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, ebx, edi);
 
     __ bind(&patch_receiver);
     __ mov(Operand(esp, eax, times_4, 0), ebx);
@@ -961,12 +957,7 @@
 
     // Use the current global receiver object as the receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalOffset =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ mov(ebx, FieldOperand(esi, kGlobalOffset));
-    __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
-    __ mov(ebx, FieldOperand(ebx, kGlobalOffset));
-    __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, ebx, edi);
 
     // Push the receiver.
     __ bind(&push_receiver);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 305a6d8..2ba08c5 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -2517,29 +2517,46 @@
   Isolate* isolate = masm->isolate();
   Label slow, non_function;
 
+  // Check that the function really is a JavaScript function.
+  __ JumpIfSmi(edi, &non_function);
+
   // The receiver might implicitly be the global object. This is
   // indicated by passing the hole as the receiver to the call
   // function stub.
-  if (ReceiverMightBeImplicit()) {
-    Label receiver_ok;
-    // Get the receiver from the stack.
-    // +1 ~ return address
-    __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
-    // Call as function is indicated with the hole.
-    __ cmp(eax, isolate->factory()->the_hole_value());
-    __ j(not_equal, &receiver_ok, Label::kNear);
+  if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
+    Label try_call, call, patch_current_context;
+    if (ReceiverMightBeImplicit()) {
+      // Get the receiver from the stack.
+      // +1 ~ return address
+      __ mov(eax, Operand(esp, (argc_ + 1) * kPointerSize));
+      // Call as function is indicated with the hole.
+      __ cmp(eax, isolate->factory()->the_hole_value());
+      __ j(not_equal, &try_call, Label::kNear);
+    }
     // Patch the receiver on the stack with the global receiver object.
-    __ mov(ecx, GlobalObjectOperand());
-    __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+    __ j(not_equal, &patch_current_context);
+    CallStubCompiler::FetchGlobalProxy(masm, ecx, edi);
     __ mov(Operand(esp, (argc_ + 1) * kPointerSize), ecx);
-    __ bind(&receiver_ok);
-  }
+    __ jmp(&call, Label::kNear);
 
-  // Check that the function really is a JavaScript function.
-  __ JumpIfSmi(edi, &non_function);
-  // Goto slow case if we do not have a function.
-  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
-  __ j(not_equal, &slow);
+    __ bind(&patch_current_context);
+    __ mov(edx, isolate->factory()->undefined_value());
+    __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edx);
+    __ jmp(&slow);
+
+    __ bind(&try_call);
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+    __ j(not_equal, &slow);
+
+    __ bind(&call);
+  } else {
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+    __ j(not_equal, &slow);
+  }
 
   if (RecordCallTarget()) {
     GenerateRecordCallTarget(masm);
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index e43e525..d3b1dd8 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -2769,11 +2769,11 @@
     { PreservePositionScope scope(masm()->positions_recorder());
       VisitForStackValue(callee);
     }
-    // Load global receiver object.
-    __ mov(ebx, GlobalObjectOperand());
-    __ push(FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
+    // Push the hole as receiver.
+    // It will be correctly replaced in the call stub.
+    __ push(Immediate(isolate()->factory()->the_hole_value()));
     // Emit function call.
-    EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
+    EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT);
   }
 
 #ifdef DEBUG
diff --git a/src/ia32/ic-ia32.cc b/src/ia32/ic-ia32.cc
index 2973beb..4db8802 100644
--- a/src/ia32/ic-ia32.cc
+++ b/src/ia32/ic-ia32.cc
@@ -1112,8 +1112,9 @@
 
     // Patch the receiver on the stack.
     __ bind(&global);
-    __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, edx, edi);
     __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
+
     __ bind(&invoke);
   }
 
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 1a20fc3..ade9ee3 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -3675,10 +3675,7 @@
   // TODO(kmillikin): We have a hydrogen value for the global object.  See
   // if it's better to use it than to explicitly fetch it from the context
   // here.
-  __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
-  __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
-  __ mov(receiver,
-         FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+  CallStubCompiler::FetchGlobalProxy(masm(), receiver, function);
   __ bind(&receiver_ok);
 }
 
@@ -4245,7 +4242,10 @@
   ASSERT(ToRegister(instr->result()).is(eax));
 
   int arity = instr->arity();
-  CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
+  CallFunctionFlags flags =
+      instr->hydrogen()->IsContextualCall() ?
+          RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
+  CallFunctionStub stub(arity, flags);
   if (instr->hydrogen()->IsTailCall()) {
     if (NeedsEagerFrame()) __ leave();
     __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 6e720f1..6bf6179 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -1166,7 +1166,7 @@
 
 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
   LOperand* receiver = UseRegister(instr->receiver());
-  LOperand* function = UseRegisterAtStart(instr->function());
+  LOperand* function = UseRegister(instr->function());
   LOperand* temp = TempRegister();
   LWrapReceiver* result =
       new(zone()) LWrapReceiver(receiver, function, temp);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 6ab3964..d63c2bb 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -2468,11 +2468,23 @@
 }
 
 
-void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Handle<JSFunction> function) {
   if (object->IsGlobalObject()) {
     const int argc = arguments().immediate();
     const int receiver_offset = (argc + 1) * kPointerSize;
-    __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
+    __ LoadHeapObject(edx, handle(function->context()->global_proxy()));
+    __ mov(Operand(esp, receiver_offset), edx);
+  }
+}
+
+
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Register function) {
+  if (object->IsGlobalObject()) {
+    FetchGlobalProxy(masm(), edx, function);
+    const int argc = arguments().immediate();
+    const int receiver_offset = (argc + 1) * kPointerSize;
     __ mov(Operand(esp, receiver_offset), edx);
   }
 }
@@ -2566,7 +2578,7 @@
   GenerateFunctionCheck(function, ebx, miss);
 
   if (!function.is(edi)) __ mov(edi, function);
-  PatchGlobalProxy(object);
+  PatchGlobalProxy(object, function);
 
   // Invoke the function.
   __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
@@ -2681,6 +2693,15 @@
 #define __ ACCESS_MASM(masm)
 
 
+void CallStubCompiler::FetchGlobalProxy(MacroAssembler* masm,
+                                        Register target,
+                                        Register function) {
+  __ mov(target, FieldOperand(function, JSFunction::kContextOffset));
+  __ mov(target, ContextOperand(target, Context::GLOBAL_OBJECT_INDEX));
+  __ mov(target, FieldOperand(target, GlobalObject::kGlobalReceiverOffset));
+}
+
+
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
     Handle<JSFunction> setter) {
diff --git a/src/runtime.cc b/src/runtime.cc
index 713d450..281c650 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -6525,7 +6525,7 @@
       if (!maybe_o->ToObject(&o)) return maybe_o;
     }
     SeqOneByteString* result = SeqOneByteString::cast(o);
-    bool has_changed_character;
+    bool has_changed_character = false;
     bool is_ascii = FastAsciiConvert<Converter>(
         reinterpret_cast<char*>(result->GetChars()),
         reinterpret_cast<char*>(SeqOneByteString::cast(s)->GetChars()),
@@ -9252,7 +9252,7 @@
     // GetProperty below can cause GC.
     Handle<Object> receiver_handle(
         object->IsGlobalObject()
-            ? GlobalObject::cast(*object)->global_receiver()
+            ? Object::cast(isolate->heap()->the_hole_value())
             : object->IsJSProxy() ? static_cast<Object*>(*object)
                 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
         isolate);
diff --git a/src/runtime.js b/src/runtime.js
index 35bc07a..2a949ae 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -48,7 +48,6 @@
 var $Function = global.Function;
 var $Boolean = global.Boolean;
 var $NaN = %GetRootNaN();
-var builtins = this;
 
 // ECMA-262 Section 11.9.3.
 function EQUALS(y) {
diff --git a/src/spaces.cc b/src/spaces.cc
index ee19a02..70e482f 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1079,12 +1079,7 @@
         // upgraded to handle small pages.
         size = AreaSize();
       } else {
-#if V8_TARGET_ARCH_MIPS
-        // TODO(plind): Investigate larger code stubs size on MIPS.
         size = 480 * KB;
-#else
-        size = 416 * KB;
-#endif
       }
       break;
     default:
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index dc2c340..e8b94f1 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1155,7 +1155,7 @@
 
 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
                                             Handle<JSFunction> function) {
-  PatchGlobalProxy(object);
+  PatchGlobalProxy(object, function);
   GenerateJumpFunctionIgnoreReceiver(function);
 }
 
@@ -1163,7 +1163,7 @@
 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
                                             Register actual_closure,
                                             Handle<JSFunction> function) {
-  PatchGlobalProxy(object);
+  PatchGlobalProxy(object, function);
   ParameterCount expected(function);
   __ InvokeFunction(actual_closure, expected, arguments(),
                     JUMP_FUNCTION, NullCallWrapper(), call_kind());
diff --git a/src/stub-cache.h b/src/stub-cache.h
index ebf0bd3..0cf9e8f 100644
--- a/src/stub-cache.h
+++ b/src/stub-cache.h
@@ -912,7 +912,11 @@
 
   // Patch the global proxy over the global object if the global object is the
   // receiver.
-  void PatchGlobalProxy(Handle<Object> object);
+  static void FetchGlobalProxy(MacroAssembler* masm,
+                               Register target,
+                               Register function);
+  void PatchGlobalProxy(Handle<Object> object, Register function);
+  void PatchGlobalProxy(Handle<Object> object, Handle<JSFunction> function);
 
   // Returns the register containing the holder of |name|.
   Register HandlerFrontendHeader(Handle<Object> object,
diff --git a/src/v8globals.h b/src/v8globals.h
index a9980e5..da290b2 100644
--- a/src/v8globals.h
+++ b/src/v8globals.h
@@ -293,8 +293,10 @@
   // Receiver might implicitly be the global objects. If it is, the
   // hole is passed to the call function stub.
   RECEIVER_MIGHT_BE_IMPLICIT = 1 << 0,
+  // Receiver is implicit and the hole has been passed to the stub.
+  RECEIVER_IS_IMPLICIT = 1 << 1,
   // The call target is cached in the instruction stream.
-  RECORD_CALL_TARGET = 1 << 1
+  RECORD_CALL_TARGET = 1 << 2
 };
 
 
diff --git a/src/version.cc b/src/version.cc
index db263a8..3e0bf84 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,7 +34,7 @@
 // system so their names cannot be changed without changing the scripts.
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     24
-#define BUILD_NUMBER      10
+#define BUILD_NUMBER      11
 #define PATCH_LEVEL       0
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 7803073..b2cd558 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -32,6 +32,7 @@
 #include "codegen.h"
 #include "deoptimizer.h"
 #include "full-codegen.h"
+#include "stub-cache.h"
 
 namespace v8 {
 namespace internal {
@@ -846,12 +847,7 @@
     // Use the global receiver object from the called function as the
     // receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalIndex =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ movq(rbx, FieldOperand(rsi, kGlobalIndex));
-    __ movq(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
-    __ movq(rbx, FieldOperand(rbx, kGlobalIndex));
-    __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, rbx, rdi);
 
     __ bind(&patch_receiver);
     __ movq(args.GetArgumentOperand(1), rbx);
@@ -1031,13 +1027,7 @@
 
     // Use the current global receiver object as the receiver.
     __ bind(&use_global_receiver);
-    const int kGlobalOffset =
-        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
-    __ movq(rbx, FieldOperand(rsi, kGlobalOffset));
-    __ movq(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
-    __ movq(rbx, FieldOperand(rbx, kGlobalOffset));
-    __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
-
+    CallStubCompiler::FetchGlobalProxy(masm, rbx, rdi);
     // Push the receiver.
     __ bind(&push_receiver);
     __ push(rbx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 920843d..b8e783d 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -2350,28 +2350,45 @@
   Label slow, non_function;
   StackArgumentsAccessor args(rsp, argc_);
 
+  // Check that the function really is a JavaScript function.
+  __ JumpIfSmi(rdi, &non_function);
+
   // The receiver might implicitly be the global object. This is
   // indicated by passing the hole as the receiver to the call
   // function stub.
-  if (ReceiverMightBeImplicit()) {
-    Label call;
-    // Get the receiver from the stack.
-    __ movq(rax, args.GetReceiverOperand());
-    // Call as function is indicated with the hole.
-    __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
-    __ j(not_equal, &call, Label::kNear);
+  if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
+    Label try_call, call, patch_current_context;
+    if (ReceiverMightBeImplicit()) {
+      // Get the receiver from the stack.
+      __ movq(rax, args.GetReceiverOperand());
+      // Call as function is indicated with the hole.
+      __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
+      __ j(not_equal, &try_call, Label::kNear);
+    }
     // Patch the receiver on the stack with the global receiver object.
-    __ movq(rcx, GlobalObjectOperand());
-    __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+    __ j(not_equal, &patch_current_context);
+    CallStubCompiler::FetchGlobalProxy(masm, rcx, rdi);
     __ movq(args.GetReceiverOperand(), rcx);
-    __ bind(&call);
-  }
+    __ jmp(&call, Label::kNear);
 
-  // Check that the function really is a JavaScript function.
-  __ JumpIfSmi(rdi, &non_function);
-  // Goto slow case if we do not have a function.
-  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
-  __ j(not_equal, &slow);
+    __ bind(&patch_current_context);
+    __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
+    __ movq(args.GetReceiverOperand(), kScratchRegister);
+    __ jmp(&slow);
+
+    __ bind(&try_call);
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+    __ j(not_equal, &slow);
+
+    __ bind(&call);
+  } else {
+    // Goto slow case if we do not have a function.
+    __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+    __ j(not_equal, &slow);
+  }
 
   if (RecordCallTarget()) {
     GenerateRecordCallTarget(masm);
@@ -2414,7 +2431,7 @@
   __ PushReturnAddressFrom(rcx);
   __ Set(rax, argc_ + 1);
   __ Set(rbx, 0);
-  __ SetCallKind(rcx, CALL_AS_METHOD);
+  __ SetCallKind(rcx, CALL_AS_FUNCTION);
   __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
   {
     Handle<Code> adaptor =
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index a56f223..99206b9 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -2746,11 +2746,11 @@
     { PreservePositionScope scope(masm()->positions_recorder());
       VisitForStackValue(callee);
     }
-    // Load global receiver object.
-    __ movq(rbx, GlobalObjectOperand());
-    __ push(FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
+    // Push the hole as receiver.
+    // It will be correctly replaced in the call stub.
+    __ PushRoot(Heap::kTheHoleValueRootIndex);
     // Emit function call.
-    EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS);
+    EmitCallWithStub(expr, RECEIVER_IS_IMPLICIT);
   }
 
 #ifdef DEBUG
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 9448d37..b2d33e0 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -998,7 +998,7 @@
 
     // Patch the receiver on the stack.
     __ bind(&global);
-    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
+    CallStubCompiler::FetchGlobalProxy(masm, rdx, rdi);
     __ movq(args.GetReceiverOperand(), rdx);
     __ bind(&invoke);
   }
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index d35219c..e6a20f2 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3250,10 +3250,7 @@
   // TODO(kmillikin): We have a hydrogen value for the global object.  See
   // if it's better to use it than to explicitly fetch it from the context
   // here.
-  __ movq(receiver, Operand(rbp, StandardFrameConstants::kContextOffset));
-  __ movq(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
-  __ movq(receiver,
-          FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset));
+  CallStubCompiler::FetchGlobalProxy(masm(), receiver, function);
   __ bind(&receiver_ok);
 }
 
@@ -3818,7 +3815,10 @@
   ASSERT(ToRegister(instr->result()).is(rax));
 
   int arity = instr->arity();
-  CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
+  CallFunctionFlags flags =
+      instr->hydrogen()->IsContextualCall() ?
+          RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
+  CallFunctionStub stub(arity, flags);
   if (instr->hydrogen()->IsTailCall()) {
     if (NeedsEagerFrame()) __ leave();
     __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 950ee28..3bbe1fc 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -2378,10 +2378,21 @@
 }
 
 
-void CallStubCompiler::PatchGlobalProxy(Handle<Object> object) {
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Handle<JSFunction> function) {
   if (object->IsGlobalObject()) {
     StackArgumentsAccessor args(rsp, arguments());
-    __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
+    __ MoveHeapObject(rdx, handle(function->context()->global_proxy()));
+    __ movq(args.GetReceiverOperand(), rdx);
+  }
+}
+
+
+void CallStubCompiler::PatchGlobalProxy(Handle<Object> object,
+                                        Register function) {
+  if (object->IsGlobalObject()) {
+    FetchGlobalProxy(masm(), rdx, function);
+    StackArgumentsAccessor args(rsp, arguments().immediate());
     __ movq(args.GetReceiverOperand(), rdx);
   }
 }
@@ -2475,7 +2486,7 @@
   GenerateFunctionCheck(function, rbx, miss);
 
   if (!function.is(rdi)) __ movq(rdi, function);
-  PatchGlobalProxy(object);
+  PatchGlobalProxy(object, function);
 
   // Invoke the function.
   __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION,
@@ -2588,6 +2599,15 @@
 #define __ ACCESS_MASM(masm)
 
 
+void CallStubCompiler::FetchGlobalProxy(MacroAssembler* masm,
+                                        Register target,
+                                        Register function) {
+  __ movq(target, FieldOperand(function, JSFunction::kContextOffset));
+  __ movq(target, ContextOperand(target, Context::GLOBAL_OBJECT_INDEX));
+  __ movq(target, FieldOperand(target, GlobalObject::kGlobalReceiverOffset));
+}
+
+
 void StoreStubCompiler::GenerateStoreViaSetter(
     MacroAssembler* masm,
     Handle<JSFunction> setter) {
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index eeb7865..372c70d 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -8704,12 +8704,23 @@
 }
 
 
+void GetThisX(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  info.GetReturnValue().Set(
+      info.GetIsolate()->GetCurrentContext()->Global()->Get(v8_str("x")));
+}
+
+
 TEST(DetachedAccesses) {
   LocalContext env1;
   v8::HandleScope scope(env1->GetIsolate());
 
   // Create second environment.
-  v8::Handle<Context> env2 = Context::New(env1->GetIsolate());
+  Local<ObjectTemplate> inner_global_template =
+      FunctionTemplate::New(env1->GetIsolate())->InstanceTemplate();
+  inner_global_template ->SetAccessorProperty(
+      v8_str("this_x"), FunctionTemplate::New(env1->GetIsolate(), GetThisX));
+  v8::Local<Context> env2 =
+      Context::New(env1->GetIsolate(), NULL, inner_global_template);
 
   Local<Value> foo = v8_str("foo");
 
@@ -8717,15 +8728,21 @@
   env1->SetSecurityToken(foo);
   env2->SetSecurityToken(foo);
 
+  env1->Global()->Set(v8_str("x"), v8_str("env1_x"));
+
   {
     v8::Context::Scope scope(env2);
+    env2->Global()->Set(v8_str("x"), v8_str("env2_x"));
     CompileRun(
-        "var x = 'x';"
-        "function get_x() { return this.x; }"
-        "function get_x_w() { return get_x(); }"
-        "");
+        "function bound_x() { return x; }"
+        "function get_x()   { return this.x; }"
+        "function get_x_w() { return (function() {return this.x;})(); }");
+    env1->Global()->Set(v8_str("bound_x"), CompileRun("bound_x"));
     env1->Global()->Set(v8_str("get_x"), CompileRun("get_x"));
     env1->Global()->Set(v8_str("get_x_w"), CompileRun("get_x_w"));
+    env1->Global()->Set(
+        v8_str("this_x"),
+        CompileRun("Object.getOwnPropertyDescriptor(this, 'this_x').get"));
   }
 
   Local<Object> env2_global = env2->Global();
@@ -8733,10 +8750,14 @@
   env2->DetachGlobal();
 
   Local<Value> result;
+  result = CompileRun("bound_x()");
+  CHECK_EQ(v8_str("env2_x"), result);
   result = CompileRun("get_x()");
   CHECK(result->IsUndefined());
   result = CompileRun("get_x_w()");
   CHECK(result->IsUndefined());
+  result = CompileRun("this_x()");
+  CHECK_EQ(v8_str("env2_x"), result);
 
   // Reattach env2's proxy
   env2 = Context::New(env1->GetIsolate(),
@@ -8746,13 +8767,62 @@
   env2->SetSecurityToken(foo);
   {
     v8::Context::Scope scope(env2);
-    CompileRun("var x = 'x2';");
+    env2->Global()->Set(v8_str("x"), v8_str("env3_x"));
+    env2->Global()->Set(v8_str("env1"), env1->Global());
+    result = CompileRun(
+        "results = [];"
+        "for (var i = 0; i < 4; i++ ) {"
+        "  results.push(env1.bound_x());"
+        "  results.push(env1.get_x());"
+        "  results.push(env1.get_x_w());"
+        "  results.push(env1.this_x());"
+        "}"
+        "results");
+    Local<v8::Array> results = Local<v8::Array>::Cast(result);
+    CHECK_EQ(16, results->Length());
+    for (int i = 0; i < 16; i += 4) {
+      CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+      CHECK_EQ(v8_str("env1_x"), results->Get(i + 1));
+      CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+      CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+    }
   }
 
-  result = CompileRun("get_x()");
-  CHECK(result->IsUndefined());
-  result = CompileRun("get_x_w()");
-  CHECK_EQ(v8_str("x2"), result);
+  result = CompileRun(
+      "results = [];"
+      "for (var i = 0; i < 4; i++ ) {"
+      "  results.push(bound_x());"
+      "  results.push(get_x());"
+      "  results.push(get_x_w());"
+      "  results.push(this_x());"
+      "}"
+      "results");
+  Local<v8::Array> results = Local<v8::Array>::Cast(result);
+  CHECK_EQ(16, results->Length());
+  for (int i = 0; i < 16; i += 4) {
+    CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+    CHECK_EQ(v8_str("env3_x"), results->Get(i + 1));
+    CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+    CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+  }
+
+  result = CompileRun(
+      "results = [];"
+      "for (var i = 0; i < 4; i++ ) {"
+      "  results.push(this.bound_x());"
+      "  results.push(this.get_x());"
+      "  results.push(this.get_x_w());"
+      "  results.push(this.this_x());"
+      "}"
+      "results");
+  results = Local<v8::Array>::Cast(result);
+  CHECK_EQ(16, results->Length());
+  for (int i = 0; i < 16; i += 4) {
+    CHECK_EQ(v8_str("env2_x"), results->Get(i + 0));
+    CHECK_EQ(v8_str("env1_x"), results->Get(i + 1));
+    CHECK_EQ(v8_str("env3_x"), results->Get(i + 2));
+    CHECK_EQ(v8_str("env2_x"), results->Get(i + 3));
+  }
 }
 
 
@@ -20110,11 +20180,10 @@
   CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[1]")));
   CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]")));
 
-  // TODO(1547): Make the following also return "i".
   // Calling with environment record as base.
-  TestReceiver(o, context->Global(), "func()");
+  TestReceiver(i, foreign_context->Global(), "func()");
   // Calling with no base.
-  TestReceiver(o, context->Global(), "(1,func)()");
+  TestReceiver(i, foreign_context->Global(), "(1,func)()");
 }
 
 
diff --git a/test/mjsunit/contextual-calls.js b/test/mjsunit/contextual-calls.js
new file mode 100644
index 0000000..10c3e8d
--- /dev/null
+++ b/test/mjsunit/contextual-calls.js
@@ -0,0 +1,103 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var realms = [Realm.current(), Realm.create()];
+globals = [Realm.global(0), Realm.global(1)];
+Realm.shared = {}
+
+function install(name, value) {
+  Realm.shared[name] = value;
+  for (i in realms) {
+    Realm.eval(realms[i], name + " = Realm.shared['" + name + "'];");
+  }
+}
+
+install('return_this', function() { return this; });
+install('return_this_strict', function () { 'use strict'; return this; });
+
+// test behaviour of 'with' scope
+for (i in realms) {
+  Realm.shared.results = [];
+  // in the second case, 'this' is found in the with scope,
+  // so the receiver is 'this'
+  Realm.eval(realms[i],"                                                       \
+      with('irrelevant') {                                                     \
+        Realm.shared.results.push(return_this());                              \
+        Realm.shared.results.push(return_this_strict());                       \
+      }                                                                        \
+      with(this) {                                                             \
+        Realm.shared.results.push(return_this());                              \
+        Realm.shared.results.push(return_this_strict());                       \
+      }                                                                        \
+    ");
+  assertSame(globals[0], Realm.shared.results[0]);
+  assertSame(undefined, Realm.shared.results[1]);
+  assertSame(globals[i], Realm.shared.results[2]);
+  assertSame(globals[i], Realm.shared.results[3]);
+}
+
+// test 'apply' and 'call'
+for (i in realms) {
+  // 'apply' without a receiver is a contextual call
+  assertSame(globals[0], Realm.eval(realms[i],'return_this.apply()')) ;
+  assertSame(undefined, Realm.eval(realms[i],'return_this_strict.apply()'));
+  assertSame(globals[0], Realm.eval(realms[i],'return_this.apply(null)')) ;
+  assertSame(null, Realm.eval(realms[i],'return_this_strict.apply(null)'));
+  // 'call' without a receiver is a contextual call
+  assertSame(globals[0], Realm.eval(realms[i],'return_this.call()')) ;
+  assertSame(undefined, Realm.eval(realms[i],'return_this_strict.call()'));
+  assertSame(globals[0], Realm.eval(realms[i],'return_this.call(null)')) ;
+  assertSame(null, Realm.eval(realms[i],'return_this_strict.call(null)'));
+}
+
+// test ics
+for (var i = 0; i < 4; i++) {
+  assertSame(globals[0], return_this());
+  assertSame(undefined, return_this_strict());
+}
+
+// BUG(1547)
+
+Realm.eval(realms[0], "var name = 'o'");
+Realm.eval(realms[1], "var name = 'i'");
+
+install('f', function() { return this.name; });
+install('g', function() { "use strict"; return this ? this.name : "u"; });
+
+for (i in realms) {
+  result = Realm.eval(realms[i], "                                             \
+      (function(){return f();})() +                                            \
+      (function(){return (1,f)();})() +                                        \
+      (function(){'use strict'; return f();})() +                              \
+      (function(){'use strict'; return (1,f)();})() +                          \
+      (function(){return g();})() +                                            \
+      (function(){return (1,g)();})() +                                        \
+      (function(){'use strict'; return g();})() +                              \
+      (function(){'use strict'; return (1,g)();})();                           \
+    ");
+  assertSame("oooouuuu", result);
+}
diff --git a/test/mjsunit/harmony/proxies-function.js b/test/mjsunit/harmony/proxies-function.js
index 6b8d098..8c91e9b 100644
--- a/test/mjsunit/harmony/proxies-function.js
+++ b/test/mjsunit/harmony/proxies-function.js
@@ -53,8 +53,7 @@
 
 function TestCall(isStrict, callTrap) {
   assertEquals(42, callTrap(5, 37))
-  // TODO(rossberg): strict mode seems to be broken on x64...
-  // assertSame(isStrict ? undefined : global_object, receiver)
+  assertSame(isStrict ? undefined : global_object, receiver)
 
   var handler = {
     get: function(r, k) {
@@ -67,8 +66,7 @@
 
   receiver = 333
   assertEquals(42, f(11, 31))
-  // TODO(rossberg): strict mode seems to be broken on x64...
-  // assertSame(isStrict ? undefined : global_object, receiver)
+  assertSame(isStrict ? undefined : global_object, receiver)
   receiver = 333
   assertEquals(42, o.f(10, 32))
   assertSame(o, receiver)
@@ -746,3 +744,31 @@
 
 TestCalls()
 */
+
+var realms = [Realm.create(), Realm.create()];
+Realm.shared = {};
+
+Realm.eval(realms[0], "function f() { return this; };");
+Realm.eval(realms[0], "Realm.shared.f = f;");
+Realm.eval(realms[0], "Realm.shared.fg = this;");
+Realm.eval(realms[1], "function g() { return this; };");
+Realm.eval(realms[1], "Realm.shared.g = g;");
+Realm.eval(realms[1], "Realm.shared.gg = this;");
+
+var fp = Proxy.createFunction({}, Realm.shared.f);
+var gp = Proxy.createFunction({}, Realm.shared.g);
+
+for (var i = 0; i < 10; i++) {
+  assertEquals(Realm.shared.fg, fp());
+  assertEquals(Realm.shared.gg, gp());
+
+  with (this) {
+    assertEquals(Realm.shared.fg, fp());
+    assertEquals(Realm.shared.gg, gp());
+  }
+
+  with ({}) {
+    assertEquals(Realm.shared.fg, fp());
+    assertEquals(Realm.shared.gg, gp());
+  }
+}