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; |
} |