Author: [email protected]
Date: Thu May 21 00:37:44 2009
New Revision: 2022

Modified:
    trunk/src/arm/builtins-arm.cc
    trunk/src/bootstrapper.cc
    trunk/src/builtins.cc
    trunk/src/builtins.h
    trunk/src/contexts.h
    trunk/src/execution.cc
    trunk/src/execution.h
    trunk/src/ia32/builtins-ia32.cc
    trunk/src/runtime.cc
    trunk/src/runtime.h
    trunk/src/runtime.js
    trunk/src/version.cc
    trunk/test/cctest/test-api.cc

Log:
Push bleeding_edge revision 2020.

r2020 adds calling a non function as a constructor. This is a prerequisite  
for working on bug http://crbug.com/3285.
Review URL: http://codereview.chromium.org/114036

Modified: trunk/src/arm/builtins-arm.cc
==============================================================================
--- trunk/src/arm/builtins-arm.cc       (original)
+++ trunk/src/arm/builtins-arm.cc       Thu May 21 00:37:44 2009
@@ -187,7 +187,7 @@

    // Set expected number of arguments to zero (not changing r0).
    __ mov(r2, Operand(0));
-  __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
+  __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
    __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
            RelocInfo::CODE_TARGET);
  }

Modified: trunk/src/bootstrapper.cc
==============================================================================
--- trunk/src/bootstrapper.cc   (original)
+++ trunk/src/bootstrapper.cc   Thu May 21 00:37:44 2009
@@ -820,14 +820,28 @@
       
global_context()->set_context_extension_function(*context_extension_fun);
    }

-  // Setup the call-as-function delegate.
-  Handle<Code> code =
-      Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsFunction));
-  Handle<JSFunction> delegate =
-      Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
-                           JSObject::kHeaderSize, code, true);
-  global_context()->set_call_as_function_delegate(*delegate);
-  delegate->shared()->DontAdaptArguments();
+
+  {
+    // Setup the call-as-function delegate.
+    Handle<Code> code =
+        Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsFunction));
+    Handle<JSFunction> delegate =
+        Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+                             JSObject::kHeaderSize, code, true);
+    global_context()->set_call_as_function_delegate(*delegate);
+    delegate->shared()->DontAdaptArguments();
+  }
+
+  {
+    // Setup the call-as-constructor delegate.
+    Handle<Code> code =
+         
Handle<Code>(Builtins::builtin(Builtins::HandleApiCallAsConstructor));
+    Handle<JSFunction> delegate =
+        Factory::NewFunction(Factory::empty_symbol(), JS_OBJECT_TYPE,
+                             JSObject::kHeaderSize, code, true);
+    global_context()->set_call_as_constructor_delegate(*delegate);
+    delegate->shared()->DontAdaptArguments();
+  }

    global_context()->set_special_function_table(Heap::empty_fixed_array());


Modified: trunk/src/builtins.cc
==============================================================================
--- trunk/src/builtins.cc       (original)
+++ trunk/src/builtins.cc       Thu May 21 00:37:44 2009
@@ -394,12 +394,18 @@
  BUILTIN_END


-// Handle calls to non-function objects created through the API that
-// support calls.
-BUILTIN(HandleApiCallAsFunction) {
-  // Non-functions are never called as constructors.
+// Helper function to handle calls to non-function objects created through  
the
+// API. The object can be called as either a constructor (using new) or  
just as
+// a function (without new).
+static Object* HandleApiCallAsFunctionOrConstructor(bool is_construct_call,
+                                                    int __argc__,
+                                                    Object** __argv__) {
+  // Non-functions are never called as constructors. Even if this is an  
object
+  // called as a constructor the delegate call is not a construct call.
    ASSERT(!CalledAsConstructor());

+  Handle<Object> receiver(&__argv__[0]);
+
    // Get the object called.
    JSObject* obj = JSObject::cast(*receiver);

@@ -431,7 +437,7 @@
          data,
          self,
          callee,
-        false,
+        is_construct_call,
          reinterpret_cast<void**>(__argv__ - 1),
          __argc__ - 1);
      v8::Handle<v8::Value> value;
@@ -449,6 +455,21 @@
    // Check for exceptions and return result.
    RETURN_IF_SCHEDULED_EXCEPTION();
    return result;
+}
+
+
+// Handle calls to non-function objects created through the API. This  
delegate
+// function is used when the call is a normal function call.
+BUILTIN(HandleApiCallAsFunction) {
+  return HandleApiCallAsFunctionOrConstructor(false, __argc__, __argv__);
+}
+BUILTIN_END
+
+
+// Handle calls to non-function objects created through the API. This  
delegate
+// function is used when the call is a construct call.
+BUILTIN(HandleApiCallAsConstructor) {
+  return HandleApiCallAsFunctionOrConstructor(true, __argc__, __argv__);
  }
  BUILTIN_END


Modified: trunk/src/builtins.h
==============================================================================
--- trunk/src/builtins.h        (original)
+++ trunk/src/builtins.h        Thu May 21 00:37:44 2009
@@ -42,7 +42,8 @@
    V(ArrayPop)                                      \
                                                     \
    V(HandleApiCall)                                 \
-  V(HandleApiCallAsFunction)
+  V(HandleApiCallAsFunction)                       \
+  V(HandleApiCallAsConstructor)


  // Define list of builtins implemented in assembly.
@@ -99,35 +100,36 @@
  #endif

  // Define list of builtins implemented in JavaScript.
-#define BUILTINS_LIST_JS(V)    \
-  V(EQUALS, 1)                 \
-  V(STRICT_EQUALS, 1)          \
-  V(COMPARE, 2)                \
-  V(ADD, 1)                    \
-  V(SUB, 1)                    \
-  V(MUL, 1)                    \
-  V(DIV, 1)                    \
-  V(MOD, 1)                    \
-  V(BIT_OR, 1)                 \
-  V(BIT_AND, 1)                \
-  V(BIT_XOR, 1)                \
-  V(UNARY_MINUS, 0)            \
-  V(BIT_NOT, 0)                \
-  V(SHL, 1)                    \
-  V(SAR, 1)                    \
-  V(SHR, 1)                    \
-  V(DELETE, 1)                 \
-  V(IN, 1)                     \
-  V(INSTANCE_OF, 1)            \
-  V(GET_KEYS, 0)               \
-  V(FILTER_KEY, 1)             \
-  V(CALL_NON_FUNCTION, 0)      \
-  V(TO_OBJECT, 0)              \
-  V(TO_NUMBER, 0)              \
-  V(TO_STRING, 0)              \
-  V(STRING_ADD_LEFT, 1)        \
-  V(STRING_ADD_RIGHT, 1)       \
-  V(APPLY_PREPARE, 1)          \
+#define BUILTINS_LIST_JS(V)              \
+  V(EQUALS, 1)                           \
+  V(STRICT_EQUALS, 1)                    \
+  V(COMPARE, 2)                          \
+  V(ADD, 1)                              \
+  V(SUB, 1)                              \
+  V(MUL, 1)                              \
+  V(DIV, 1)                              \
+  V(MOD, 1)                              \
+  V(BIT_OR, 1)                           \
+  V(BIT_AND, 1)                          \
+  V(BIT_XOR, 1)                          \
+  V(UNARY_MINUS, 0)                      \
+  V(BIT_NOT, 0)                          \
+  V(SHL, 1)                              \
+  V(SAR, 1)                              \
+  V(SHR, 1)                              \
+  V(DELETE, 1)                           \
+  V(IN, 1)                               \
+  V(INSTANCE_OF, 1)                      \
+  V(GET_KEYS, 0)                         \
+  V(FILTER_KEY, 1)                       \
+  V(CALL_NON_FUNCTION, 0)                \
+  V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
+  V(TO_OBJECT, 0)                        \
+  V(TO_NUMBER, 0)                        \
+  V(TO_STRING, 0)                        \
+  V(STRING_ADD_LEFT, 1)                  \
+  V(STRING_ADD_RIGHT, 1)                 \
+  V(APPLY_PREPARE, 1)                    \
    V(APPLY_OVERFLOW, 1)



Modified: trunk/src/contexts.h
==============================================================================
--- trunk/src/contexts.h        (original)
+++ trunk/src/contexts.h        Thu May 21 00:37:44 2009
@@ -90,6 +90,8 @@
    V(FUNCTION_CACHE_INDEX, JSObject, function_cache) \
    V(RUNTIME_CONTEXT_INDEX, Context, runtime_context) \
    V(CALL_AS_FUNCTION_DELEGATE_INDEX, JSFunction,  
call_as_function_delegate) \
+  V(CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, JSFunction, \
+    call_as_constructor_delegate) \
    V(EMPTY_SCRIPT_INDEX, Script, empty_script) \
    V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
    V(CONTEXT_EXTENSION_FUNCTION_INDEX, JSFunction,  
context_extension_function) \
@@ -209,6 +211,7 @@
      FUNCTION_CACHE_INDEX,
      RUNTIME_CONTEXT_INDEX,
      CALL_AS_FUNCTION_DELEGATE_INDEX,
+    CALL_AS_CONSTRUCTOR_DELEGATE_INDEX,
      EMPTY_SCRIPT_INDEX,
      SCRIPT_FUNCTION_INDEX,
      CONTEXT_EXTENSION_FUNCTION_INDEX,

Modified: trunk/src/execution.cc
==============================================================================
--- trunk/src/execution.cc      (original)
+++ trunk/src/execution.cc      Thu May 21 00:37:44 2009
@@ -188,6 +188,24 @@
  }


+Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
+  ASSERT(!object->IsJSFunction());
+
+  // If you return a function from here, it will be called when an
+  // attempt is made to call the given object as a constructor.
+
+  // Objects created through the API can have an instance-call handler
+  // that should be used when calling the object as a function.
+  if (object->IsHeapObject() &&
+      HeapObject::cast(*object)->map()->has_instance_call_handler()) {
+    return Handle<JSFunction>(
+        Top::global_context()->call_as_constructor_delegate());
+  }
+
+  return Factory::undefined_value();
+}
+
+
  // Static state for stack guards.
  StackGuard::ThreadLocal StackGuard::thread_local_;


Modified: trunk/src/execution.h
==============================================================================
--- trunk/src/execution.h       (original)
+++ trunk/src/execution.h       Thu May 21 00:37:44 2009
@@ -129,6 +129,10 @@
    // Get a function delegate (or undefined) for the given non-function
    // object. Used for support calling objects as functions.
    static Handle<Object> GetFunctionDelegate(Handle<Object> object);
+
+  // Get a function delegate (or undefined) for the given non-function
+  // object. Used for support calling objects as constructors.
+  static Handle<Object> GetConstructorDelegate(Handle<Object> object);
  };



Modified: trunk/src/ia32/builtins-ia32.cc
==============================================================================
--- trunk/src/ia32/builtins-ia32.cc     (original)
+++ trunk/src/ia32/builtins-ia32.cc     Thu May 21 00:37:44 2009
@@ -311,7 +311,7 @@

    // Set expected number of arguments to zero (not changing eax).
    __ Set(ebx, Immediate(0));
-  __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
+  __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
    __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
           RelocInfo::CODE_TARGET);
  }

Modified: trunk/src/runtime.cc
==============================================================================
--- trunk/src/runtime.cc        (original)
+++ trunk/src/runtime.cc        Thu May 21 00:37:44 2009
@@ -4356,6 +4356,14 @@
  }


+static Object* Runtime_GetConstructorDelegate(Arguments args) {
+  HandleScope scope;
+  ASSERT(args.length() == 1);
+  RUNTIME_ASSERT(!args[0]->IsJSFunction());
+  return *Execution::GetConstructorDelegate(args.at<Object>(0));
+}
+
+
  static Object* Runtime_NewContext(Arguments args) {
    NoHandleAllocation ha;
    ASSERT(args.length() == 1);

Modified: trunk/src/runtime.h
==============================================================================
--- trunk/src/runtime.h (original)
+++ trunk/src/runtime.h Thu May 21 00:37:44 2009
@@ -63,6 +63,7 @@
    /* Utilities */ \
    F(GetCalledFunction, 0) \
    F(GetFunctionDelegate, 1) \
+  F(GetConstructorDelegate, 1) \
    F(NewArguments, 1) \
    F(NewArgumentsFast, 3) \
    F(LazyCompile, 1) \

Modified: trunk/src/runtime.js
==============================================================================
--- trunk/src/runtime.js        (original)
+++ trunk/src/runtime.js        Thu May 21 00:37:44 2009
@@ -327,6 +327,18 @@
  }


+function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
+  var callee = %GetCalledFunction();
+  var delegate = %GetConstructorDelegate(callee);
+  if (!IS_FUNCTION(delegate)) {
+    throw %MakeTypeError('called_non_callable', [typeof callee]);
+  }
+
+  var parameters = %NewArguments(delegate);
+  return delegate.apply(callee, parameters);
+}
+
+
  function APPLY_PREPARE(args) {
    var length;
    // First check whether length is a positive Smi and args is an array.   
This is the

Modified: trunk/src/version.cc
==============================================================================
--- trunk/src/version.cc        (original)
+++ trunk/src/version.cc        Thu May 21 00:37:44 2009
@@ -35,7 +35,7 @@
  #define MAJOR_VERSION     1
  #define MINOR_VERSION     2
  #define BUILD_NUMBER      4
-#define PATCH_LEVEL       2
+#define PATCH_LEVEL       3
  #define CANDIDATE_VERSION false

  // Define SONAME to have the SCons build the put a specific SONAME into the

Modified: trunk/test/cctest/test-api.cc
==============================================================================
--- trunk/test/cctest/test-api.cc       (original)
+++ trunk/test/cctest/test-api.cc       Thu May 21 00:37:44 2009
@@ -4644,6 +4644,12 @@

  static v8::Handle<Value> call_as_function(const v8::Arguments& args) {
    ApiTestFuzzer::Fuzz();
+  if (args.IsConstructCall()) {
+    if (args[0]->IsInt32()) {
+       return v8_num(-args[0]->Int32Value());
+    }
+  }
+
    return args[0];
  }

@@ -4697,9 +4703,9 @@
    // Check that the call-as-function handler can be called through
    // new.  Currently, there is no way to check in the call-as-function
    // handler if it has been called through new or not.
-  value = CompileRun("new obj(42)");
+  value = CompileRun("new obj(43)");
    CHECK(!try_catch.HasCaught());
-  CHECK_EQ(42, value->Int32Value());
+  CHECK_EQ(-43, value->Int32Value());
  }



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

Reply via email to