Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 38199f8c5826fbbee560d6dde3bb78a317009d35..af200fdbc5b1a4a56b8d87c8c5fca33ea42eb4c7 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -612,6 +612,19 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSProxy) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateJSFunctionProxy) { |
+ ASSERT(args.length() == 4); |
+ Object* handler = args[0]; |
+ Object* call_trap = args[1]; |
+ Object* construct_trap = args[2]; |
+ Object* prototype = args[3]; |
+ Object* used_prototype = |
+ prototype->IsJSReceiver() ? prototype : isolate->heap()->null_value(); |
+ return isolate->heap()->AllocateJSFunctionProxy( |
+ handler, call_trap, construct_trap, used_prototype); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) { |
ASSERT(args.length() == 1); |
Object* obj = args[0]; |
@@ -619,6 +632,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSProxy) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsJSFunctionProxy) { |
+ ASSERT(args.length() == 1); |
+ Object* obj = args[0]; |
+ return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy()); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { |
ASSERT(args.length() == 1); |
CONVERT_CHECKED(JSProxy, proxy, args[0]); |
@@ -626,6 +646,20 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetHandler) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetCallTrap) { |
+ ASSERT(args.length() == 1); |
+ CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]); |
+ return proxy->call_trap(); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetConstructTrap) { |
+ ASSERT(args.length() == 1); |
+ CONVERT_CHECKED(JSFunctionProxy, proxy, args[0]); |
+ return proxy->construct_trap(); |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) { |
ASSERT(args.length() == 1); |
CONVERT_CHECKED(JSProxy, proxy, args[0]); |
@@ -4860,6 +4894,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_Typeof) { |
ASSERT(heap_obj->IsUndefined()); |
return isolate->heap()->undefined_symbol(); |
case JS_FUNCTION_TYPE: |
+ case JS_FUNCTION_PROXY_TYPE: |
return isolate->heap()->function_symbol(); |
default: |
// For any kind of object not handled above, the spec rule for |
@@ -8212,6 +8247,49 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) { |
} |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Apply) { |
+ HandleScope scope(isolate); |
+ ASSERT(args.length() == 5); |
+ CONVERT_CHECKED(JSReceiver, fun, args[0]); |
+ Object* receiver = args[1]; |
+ CONVERT_CHECKED(JSObject, arguments, args[2]); |
+ CONVERT_CHECKED(Smi, shift, args[3]); |
+ CONVERT_CHECKED(Smi, arity, args[4]); |
+ |
+ int offset = shift->value(); |
+ int argc = arity->value(); |
+ ASSERT(offset >= 0); |
+ ASSERT(argc >= 0); |
+ |
+ // If there are too many arguments, allocate argv via malloc. |
+ const int argv_small_size = 10; |
+ Handle<Object> argv_small_buffer[argv_small_size]; |
+ SmartPointer<Handle<Object> > argv_large_buffer; |
+ Handle<Object>* argv = argv_small_buffer; |
+ if (argc > argv_small_size) { |
+ argv = new Handle<Object>[argc]; |
+ if (argv == NULL) return isolate->StackOverflow(); |
+ argv_large_buffer = SmartPointer<Handle<Object> >(argv); |
+ } |
+ |
+ for (int i = 0; i < argc; ++i) { |
+ MaybeObject* maybe = arguments->GetElement(offset + i); |
+ Object* object; |
+ if (!maybe->To<Object>(&object)) return maybe; |
+ argv[i] = Handle<Object>(object); |
+ } |
+ |
+ bool threw = false; |
+ Handle<JSReceiver> hfun(fun); |
+ Handle<Object> hreceiver(receiver); |
+ Handle<Object> result = Execution::Call( |
+ hfun, hreceiver, argc, reinterpret_cast<Object***>(argv), &threw, true); |
+ |
+ if (threw) return Failure::Exception(); |
+ return *result; |
+} |
+ |
+ |
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFunctionDelegate) { |
HandleScope scope(isolate); |
ASSERT(args.length() == 1); |