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 | |
1305 // ---------------------------------------------------------------------------- | 1239 // ---------------------------------------------------------------------------- |
1306 | 1240 |
1307 %AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction, | 1241 %AddNamedProperty(GlobalFunction.prototype, "constructor", GlobalFunction, |
1308 DONT_ENUM); | 1242 DONT_ENUM); |
1309 | 1243 |
1310 utils.InstallFunctions(GlobalFunction.prototype, DONT_ENUM, [ | |
1311 "bind", FunctionBind, | |
1312 ]); | |
1313 | |
1314 // ---------------------------------------------------------------------------- | 1244 // ---------------------------------------------------------------------------- |
1315 // Iterator related spec functions. | 1245 // Iterator related spec functions. |
1316 | 1246 |
1317 // ES6 7.4.1 GetIterator(obj, method) | 1247 // ES6 7.4.1 GetIterator(obj, method) |
1318 function GetIterator(obj, method) { | 1248 function GetIterator(obj, method) { |
1319 if (IS_UNDEFINED(method)) { | 1249 if (IS_UNDEFINED(method)) { |
1320 method = obj[iteratorSymbol]; | 1250 method = obj[iteratorSymbol]; |
1321 } | 1251 } |
1322 if (!IS_CALLABLE(method)) { | 1252 if (!IS_CALLABLE(method)) { |
1323 throw MakeTypeError(kNotIterable, obj); | 1253 throw MakeTypeError(kNotIterable, obj); |
(...skipping 21 matching lines...) Expand all Loading... |
1345 to.ObjectIsFrozen = ObjectIsFrozen; | 1275 to.ObjectIsFrozen = ObjectIsFrozen; |
1346 to.ObjectIsSealed = ObjectIsSealed; | 1276 to.ObjectIsSealed = ObjectIsSealed; |
1347 to.ObjectKeys = ObjectKeys; | 1277 to.ObjectKeys = ObjectKeys; |
1348 }); | 1278 }); |
1349 | 1279 |
1350 %InstallToContext([ | 1280 %InstallToContext([ |
1351 "object_value_of", ObjectValueOf, | 1281 "object_value_of", ObjectValueOf, |
1352 ]); | 1282 ]); |
1353 | 1283 |
1354 }) | 1284 }) |
OLD | NEW |