Index: src/runtime.js |
diff --git a/src/runtime.js b/src/runtime.js |
index 82c668a6e26438475b00f59cacb0b2ceb2788836..b2e902288946dbbfa0ef77e359ba38c66a124057 100644 |
--- a/src/runtime.js |
+++ b/src/runtime.js |
@@ -424,9 +424,23 @@ |
----------------------------- |
*/ |
+function CALL_NON_FUNCTION() { |
+ var delegate = %GetFunctionDelegate(this); |
+ return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); |
+} |
+ |
+ |
function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { |
var delegate = %GetConstructorDelegate(this); |
return %Apply(delegate, this, arguments, 0, %_ArgumentsLength()); |
+} |
+ |
+ |
+function CALL_FUNCTION_PROXY() { |
+ var arity = %_ArgumentsLength() - 1; |
+ var proxy = %_Arguments(arity); // The proxy comes in as an additional arg. |
+ var trap = %GetCallTrap(proxy); |
+ return %Apply(trap, this, arguments, 0, arity); |
} |
@@ -439,19 +453,13 @@ |
function APPLY_PREPARE(args) { |
var length; |
- |
- // First check that the receiver is callable. |
- if (!IS_CALLABLE(this)) { |
- throw %make_type_error(kApplyNonFunction, %to_string_fun(this), |
- typeof this); |
- } |
- |
// First check whether length is a positive Smi and args is an |
// array. This is the fast case. If this fails, we do the slow case |
// that takes care of more eventualities. |
if (IS_ARRAY(args)) { |
length = args.length; |
- if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { |
+ if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && |
+ IS_CALLABLE(this)) { |
return length; |
} |
} |
@@ -463,6 +471,11 @@ |
// multiplying with pointer size. |
if (length > kSafeArgumentsLength) throw %make_range_error(kStackOverflow); |
+ if (!IS_CALLABLE(this)) { |
+ throw %make_type_error(kApplyNonFunction, %to_string_fun(this), |
+ typeof this); |
+ } |
+ |
// Make sure the arguments list has the right type. |
if (args != null && !IS_SPEC_OBJECT(args)) { |
throw %make_type_error(kWrongArgs, "Function.prototype.apply"); |
@@ -476,21 +489,19 @@ |
function REFLECT_APPLY_PREPARE(args) { |
var length; |
- |
- // First check that the receiver is callable. |
- if (!IS_CALLABLE(this)) { |
- throw %make_type_error(kApplyNonFunction, %to_string_fun(this), |
- typeof this); |
- } |
- |
// First check whether length is a positive Smi and args is an |
// array. This is the fast case. If this fails, we do the slow case |
// that takes care of more eventualities. |
if (IS_ARRAY(args)) { |
length = args.length; |
- if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength) { |
+ if (%_IsSmi(length) && length >= 0 && length < kSafeArgumentsLength && |
+ IS_CALLABLE(this)) { |
return length; |
} |
+ } |
+ |
+ if (!IS_CALLABLE(this)) { |
+ throw %make_type_error(kCalledNonCallable, %to_string_fun(this)); |
} |
if (!IS_SPEC_OBJECT(args)) { |
@@ -791,7 +802,9 @@ |
"bit_xor_builtin", BIT_XOR, |
"bit_xor_strong_builtin", BIT_XOR_STRONG, |
"call_function_proxy_as_constructor_builtin", CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, |
+ "call_function_proxy_builtin", CALL_FUNCTION_PROXY, |
"call_non_function_as_constructor_builtin", CALL_NON_FUNCTION_AS_CONSTRUCTOR, |
+ "call_non_function_builtin", CALL_NON_FUNCTION, |
"compare_builtin", COMPARE, |
"compare_strong_builtin", COMPARE_STRONG, |
"concat_iterable_to_array_builtin", CONCAT_ITERABLE_TO_ARRAY, |