OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils) { | 5 (function(global, utils) { |
6 | 6 |
7 %CheckIsBootstrapping(); | 7 %CheckIsBootstrapping(); |
8 | 8 |
9 // ---------------------------------------------------------------------------- | 9 // ---------------------------------------------------------------------------- |
10 // Imports | 10 // Imports |
(...skipping 1218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 "parseInt", GlobalParseInt, | 1229 "parseInt", GlobalParseInt, |
1230 "parseFloat", GlobalParseFloat | 1230 "parseFloat", GlobalParseFloat |
1231 ]); | 1231 ]); |
1232 | 1232 |
1233 %SetForceInlineFlag(NumberIsNaN); | 1233 %SetForceInlineFlag(NumberIsNaN); |
1234 | 1234 |
1235 | 1235 |
1236 // ---------------------------------------------------------------------------- | 1236 // ---------------------------------------------------------------------------- |
1237 // Function | 1237 // Function |
1238 | 1238 |
| 1239 // ES6 9.2.3.2 Function.prototype.bind(thisArg , ...args) |
| 1240 function FunctionBind(this_arg) { // Length is 1. |
| 1241 if (!IS_CALLABLE(this)) throw MakeTypeError(kFunctionBind); |
| 1242 |
| 1243 var boundFunction = function () { |
| 1244 // Poison .arguments and .caller, but is otherwise not detectable. |
| 1245 "use strict"; |
| 1246 // This function must not use any object literals (Object, Array, RegExp), |
| 1247 // since the literals-array is being used to store the bound data. |
| 1248 if (!IS_UNDEFINED(new.target)) { |
| 1249 return %NewObjectFromBound(boundFunction); |
| 1250 } |
| 1251 var bindings = %BoundFunctionGetBindings(boundFunction); |
| 1252 |
| 1253 var argc = %_ArgumentsLength(); |
| 1254 if (argc == 0) { |
| 1255 return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2); |
| 1256 } |
| 1257 if (bindings.length === 2) { |
| 1258 return %Apply(bindings[0], bindings[1], arguments, 0, argc); |
| 1259 } |
| 1260 var bound_argc = bindings.length - 2; |
| 1261 var argv = new InternalArray(bound_argc + argc); |
| 1262 for (var i = 0; i < bound_argc; i++) { |
| 1263 argv[i] = bindings[i + 2]; |
| 1264 } |
| 1265 for (var j = 0; j < argc; j++) { |
| 1266 argv[i++] = %_Arguments(j); |
| 1267 } |
| 1268 return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc); |
| 1269 }; |
| 1270 |
| 1271 var proto = %_GetPrototype(this); // in ES6 9.4.1.3 BoundFunctionCreate |
| 1272 |
| 1273 var new_length = 0; |
| 1274 if (ObjectGetOwnPropertyDescriptor(this, "length") !== UNDEFINED) { |
| 1275 var old_length = this.length; |
| 1276 if (IS_NUMBER(old_length)) { |
| 1277 var argc = %_ArgumentsLength(); |
| 1278 if (argc > 0) argc--; // Don't count the thisArg as parameter. |
| 1279 new_length = TO_INTEGER(old_length) - argc; |
| 1280 if (new_length < 0) new_length = 0; |
| 1281 } |
| 1282 } |
| 1283 |
| 1284 // This runtime function finds any remaining arguments on the stack, |
| 1285 // so we don't pass the arguments object. |
| 1286 var result = %FunctionBindArguments(boundFunction, this, this_arg, |
| 1287 new_length, proto); |
| 1288 |
| 1289 var name = this.name; |
| 1290 var bound_name = IS_STRING(name) ? name : ""; |
| 1291 %DefineDataPropertyUnchecked(result, "name", "bound " + bound_name, |
| 1292 DONT_ENUM | READ_ONLY); |
| 1293 |
| 1294 // We already have caller and arguments properties on functions, |
| 1295 // which are non-configurable. It therefore makes no sence to |
| 1296 // try to redefine these as defined by the spec. The spec says |
| 1297 // that bind should make these throw a TypeError if get or set |
| 1298 // is called and make them non-enumerable and non-configurable. |
| 1299 // To be consistent with our normal functions we leave this as it is. |
| 1300 // TODO(lrn): Do set these to be thrower. |
| 1301 return result; |
| 1302 } |
| 1303 |
| 1304 |
1239 // ---------------------------------------------------------------------------- | 1305 // ---------------------------------------------------------------------------- |
1240 | 1306 |
1241 %AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction, | 1307 %AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction, |
1242 DONT_ENUM); | 1308 DONT_ENUM); |
1243 | 1309 |
| 1310 utils.InstallFunctions(GlobalFunction.prototype, DONT_ENUM, [ |
| 1311 "bind", FunctionBind, |
| 1312 ]); |
| 1313 |
1244 // ---------------------------------------------------------------------------- | 1314 // ---------------------------------------------------------------------------- |
1245 // Iterator related spec functions. | 1315 // Iterator related spec functions. |
1246 | 1316 |
1247 // ES6 7.4.1 GetIterator(obj, method) | 1317 // ES6 7.4.1 GetIterator(obj, method) |
1248 function GetIterator(obj, method) { | 1318 function GetIterator(obj, method) { |
1249 if (IS_UNDEFINED(method)) { | 1319 if (IS_UNDEFINED(method)) { |
1250 method = obj[iteratorSymbol]; | 1320 method = obj[iteratorSymbol]; |
1251 } | 1321 } |
1252 if (!IS_CALLABLE(method)) { | 1322 if (!IS_CALLABLE(method)) { |
1253 throw MakeTypeError(kNotIterable, obj); | 1323 throw MakeTypeError(kNotIterable, obj); |
(...skipping 21 matching lines...) Expand all Loading... |
1275 to.ObjectIsFrozen = ObjectIsFrozen; | 1345 to.ObjectIsFrozen = ObjectIsFrozen; |
1276 to.ObjectIsSealed = ObjectIsSealed; | 1346 to.ObjectIsSealed = ObjectIsSealed; |
1277 to.ObjectKeys = ObjectKeys; | 1347 to.ObjectKeys = ObjectKeys; |
1278 }); | 1348 }); |
1279 | 1349 |
1280 %InstallToContext([ | 1350 %InstallToContext([ |
1281 "object_value_of", ObjectValueOf, | 1351 "object_value_of", ObjectValueOf, |
1282 ]); | 1352 ]); |
1283 | 1353 |
1284 }) | 1354 }) |
OLD | NEW |