Chromium Code Reviews| Index: src/runtime.js |
| diff --git a/src/runtime.js b/src/runtime.js |
| index 4b600df7360b3431f9a3834937a022e35d1a4648..82ff2624cb583a3b4a5ee7f4f463b0a878f33e44 100644 |
| --- a/src/runtime.js |
| +++ b/src/runtime.js |
| @@ -365,7 +365,7 @@ function IN(x) { |
| // an expensive ToBoolean conversion in the generated code. |
| function INSTANCE_OF(F) { |
| var V = this; |
| - if (!IS_FUNCTION(F)) { |
| + if (!IS_SPEC_FUNCTION(F)) { |
| throw %MakeTypeError('instanceof_function_expected', [V]); |
| } |
| @@ -405,7 +405,11 @@ function FILTER_KEY(key) { |
| function CALL_NON_FUNCTION() { |
| var delegate = %GetFunctionDelegate(this); |
| if (!IS_FUNCTION(delegate)) { |
| - throw %MakeTypeError('called_non_callable', [typeof this]); |
| + if (%IsJSFunctionProxy(this)) { |
|
Kevin Millikin (Chromium)
2011/09/08 17:30:40
Can we get into this case, where CALL_NON_FUNCTION
rossberg
2011/09/09 17:05:30
Done (subsuming part of change 7849021).
|
| + delegate = %GetCallTrap(this); |
| + } else { |
| + throw %MakeTypeError('called_non_callable', [typeof this]); |
| + } |
| } |
| return delegate.apply(this, arguments); |
| } |
| @@ -414,12 +418,44 @@ function CALL_NON_FUNCTION() { |
| function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { |
| var delegate = %GetConstructorDelegate(this); |
| if (!IS_FUNCTION(delegate)) { |
| - throw %MakeTypeError('called_non_callable', [typeof this]); |
| + if (%IsJSFunctionProxy(this)) { |
| + delegate = %GetConstructTrap(this); |
| + } else { |
| + throw %MakeTypeError('called_non_callable', [typeof this]); |
| + } |
| } |
| return delegate.apply(this, arguments); |
| } |
| +function CALL_FUNCTION_PROXY() { |
| + var arity = %_ArgumentsLength() - 1; |
| + var proxy = arguments[arity]; // The proxy comes in as an additional arg. |
|
Kevin Millikin (Chromium)
2011/09/08 17:30:40
You can also use %_Arguments(arity) to get the arg
rossberg
2011/09/09 17:05:30
Done (although we have to materialize the argument
|
| + var trap = %GetCallTrap(proxy); |
| + // TODO(rossberg): hm, shouldn't I be using $Function and friends? |
| + // But how do I get it in a builtin? |
| + return global.Function.prototype.apply.call( |
|
Kevin Millikin (Chromium)
2011/09/08 17:30:40
You can't, the JS builtins are called with the con
rossberg
2011/09/09 17:05:30
I implemented an %Apply native.
|
| + trap, this, global.Array.prototype.slice.call(arguments, 0, arity)); |
| +} |
| + |
| + |
| +function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR(proxy) { |
| + var trap = %GetConstructTrap(proxy); |
| + var receiver = void 0; |
| + if (!IS_UNDEFINED(trap)) { |
| + trap = %GetCallTrap(proxy); |
| + var proto = proxy.prototype; |
| + if (!IS_SPEC_OBJECT(proto) && proto !== null) { |
| + throw MakeTypeError("proto_object_or_null", [proto]); |
| + } |
| + receiver = new global.Object(); |
| + receiver.__proto__ = proto; |
| + } |
| + return global.Function.prototype.apply.call( |
| + trap, this, global.Array.prototype.shift.call(arguments)); |
| +} |
| + |
| + |
| function APPLY_PREPARE(args) { |
| var length; |
| // First check whether length is a positive Smi and args is an |
| @@ -427,7 +463,8 @@ function APPLY_PREPARE(args) { |
| // that takes care of more eventualities. |
| if (IS_ARRAY(args)) { |
| length = args.length; |
| - if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)) { |
| + if (%_IsSmi(length) && length >= 0 && length < 0x800000 && |
| + IS_SPEC_FUNCTION(this)) { |
| return length; |
| } |
| } |
| @@ -441,7 +478,7 @@ function APPLY_PREPARE(args) { |
| throw %MakeRangeError('stack_overflow', []); |
| } |
| - if (!IS_FUNCTION(this)) { |
| + if (!IS_SPEC_FUNCTION(this)) { |
| throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ]); |
| } |
| @@ -609,13 +646,13 @@ function IsPrimitive(x) { |
| // ECMA-262, section 8.6.2.6, page 28. |
| function DefaultNumber(x) { |
| var valueOf = x.valueOf; |
| - if (IS_FUNCTION(valueOf)) { |
| + if (IS_SPEC_FUNCTION(valueOf)) { |
| var v = %_CallFunction(x, valueOf); |
| if (%IsPrimitive(v)) return v; |
| } |
| var toString = x.toString; |
| - if (IS_FUNCTION(toString)) { |
| + if (IS_SPEC_FUNCTION(toString)) { |
| var s = %_CallFunction(x, toString); |
| if (%IsPrimitive(s)) return s; |
| } |
| @@ -627,13 +664,13 @@ function DefaultNumber(x) { |
| // ECMA-262, section 8.6.2.6, page 28. |
| function DefaultString(x) { |
| var toString = x.toString; |
| - if (IS_FUNCTION(toString)) { |
| + if (IS_SPEC_FUNCTION(toString)) { |
| var s = %_CallFunction(x, toString); |
| if (%IsPrimitive(s)) return s; |
| } |
| var valueOf = x.valueOf; |
| - if (IS_FUNCTION(valueOf)) { |
| + if (IS_SPEC_FUNCTION(valueOf)) { |
| var v = %_CallFunction(x, valueOf); |
| if (%IsPrimitive(v)) return v; |
| } |