Index: src/v8natives.js |
=================================================================== |
--- src/v8natives.js (revision 5100) |
+++ src/v8natives.js (working copy) |
@@ -539,21 +539,21 @@ |
throw MakeTypeError("define_disallowed", ["defineProperty"]); |
if (!IS_UNDEFINED(current) && !current.isConfigurable()) { |
- // Step 5 and 6 |
- if ((!desc.hasEnumerable() || |
- SameValue(desc.isEnumerable() && current.isEnumerable())) && |
- (!desc.hasConfigurable() || |
- SameValue(desc.isConfigurable(), current.isConfigurable())) && |
- (!desc.hasWritable() || |
- SameValue(desc.isWritable(), current.isWritable())) && |
- (!desc.hasValue() || |
- SameValue(desc.getValue(), current.getValue())) && |
- (!desc.hasGetter() || |
- SameValue(desc.getGet(), current.getGet())) && |
- (!desc.hasSetter() || |
- SameValue(desc.getSet(), current.getSet()))) { |
- return true; |
- } |
+ // Step 5 and 6 |
+ if ((!desc.hasEnumerable() || |
+ SameValue(desc.isEnumerable() && current.isEnumerable())) && |
+ (!desc.hasConfigurable() || |
+ SameValue(desc.isConfigurable(), current.isConfigurable())) && |
+ (!desc.hasWritable() || |
+ SameValue(desc.isWritable(), current.isWritable())) && |
+ (!desc.hasValue() || |
+ SameValue(desc.getValue(), current.getValue())) && |
+ (!desc.hasGetter() || |
+ SameValue(desc.getGet(), current.getGet())) && |
+ (!desc.hasSetter() || |
+ SameValue(desc.getSet(), current.getSet()))) { |
+ return true; |
+ } |
// Step 7 |
if (desc.isConfigurable() || desc.isEnumerable() != current.isEnumerable()) |
@@ -1099,6 +1099,57 @@ |
} |
+// ES5 15.3.4.5 |
+function FunctionBind(this_arg) { // Length is 1. |
+ if (!IS_FUNCTION(this)) { |
+ throw new $TypeError('Bind must be called on a function'); |
+ } |
+ // this_arg is not an argument that should be bound. |
+ var argc_bound = %_ArgumentsLength() - 1; |
+ if (argc_bound > 0) { |
+ var bound_args = new $Array(argc_bound); |
+ for(var i = 0; i < argc_bound; i++) { |
+ bound_args[i] = %_Arguments(i+1); |
+ } |
+ } |
+ global.print(argc_bound); |
Aaron.Heckmann_gmail.com
2010/07/27 02:21:47
Looks like this line should be removed?
|
+ var fn = this; |
+ var result = function() { |
+ // Combine the args we got from the bind call with the args |
+ // given as argument to the invocation. |
+ var argc = %_ArgumentsLength(); |
+ var args = new $Array(argc + argc_bound); |
+ // Add bound arguments. |
+ for (var i = 0; i < argc_bound; i++) { |
+ args[i] = bound_args[i]; |
+ } |
+ // Add arguments from call. |
+ for (var i = 0; i < argc; i++) { |
+ args[argc_bound + i] = %_Arguments(i); |
+ } |
+ // If this is a construct call we use a special runtime method |
+ // to generate the actual object using the bound function. |
+ if (%_IsConstructCall()) { |
+ return %NewObjectFromBound(fn, args); |
+ } |
+ return fn.apply(this_arg, args); |
+ }; |
+ |
+ // We already have caller and arguments properties on functions, |
+ // which are non-configurable. It therefore makes no sence to |
+ // try to redefine these as defined by the spec. The spec says |
+ // that bind should make these throw a TypeError if get or set |
+ // is called and make them non-enumerable and non-configurable. |
+ // To be consistent with our normal functions we leave this as it is. |
+ |
+ // Set the correct length. |
+ var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; |
+ %FunctionSetLength(result, length); |
+ |
+ return result; |
+} |
+ |
+ |
function NewFunction(arg1) { // length == 1 |
var n = %_ArgumentsLength(); |
var p = ''; |
@@ -1130,6 +1181,7 @@ |
function SetupFunction() { |
InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
+ "bind", FunctionBind, |
"toString", FunctionToString |
)); |
} |