28
28
// This file relies on the fact that the following declarations have been made
31
// const $Object = global.Object;
32
// const $Boolean = global.Boolean;
33
// const $Number = global.Number;
34
// const $Function = global.Function;
35
// const $Array = global.Array;
31
// var $Object = global.Object;
32
// var $Boolean = global.Boolean;
33
// var $Number = global.Number;
34
// var $Function = global.Function;
35
// var $Array = global.Array;
39
// const $floor = MathFloor
39
// var $floor = MathFloor
41
const $isNaN = GlobalIsNaN;
42
const $isFinite = GlobalIsFinite;
41
var $isNaN = GlobalIsNaN;
42
var $isFinite = GlobalIsFinite;
44
44
// ----------------------------------------------------------------------------
60
60
%ToFastProperties(object);
63
// Emulates JSC by installing functions on a hidden prototype that
64
// lies above the current object/prototype. This lets you override
65
// functions on String.prototype etc. and then restore the old function
66
// with delete. See http://code.google.com/p/chromium/issues/detail?id=1717
67
function InstallFunctionsOnHiddenPrototype(object, attributes, functions) {
68
%CheckIsBootstrapping();
69
var hidden_prototype = new $Object();
70
%SetHiddenPrototype(object, hidden_prototype);
71
InstallFunctions(hidden_prototype, attributes, functions);
75
63
// Prevents changes to the prototype of a built-infunction.
76
64
// The "prototype" property of the function object is made non-configurable,
77
65
// and the prototype object is made non-extensible. The latter prevents
162
151
function GlobalEval(x) {
163
152
if (!IS_STRING(x)) return x;
166
154
var global_receiver = %GlobalReceiver(global);
168
if (receiver == null && !IS_UNDETECTABLE(receiver)) {
169
receiver = global_receiver;
172
var this_is_global_receiver = (receiver === global_receiver);
173
155
var global_is_detached = (global === global_receiver);
175
157
// For consistency with JSC we require the global object passed to
176
158
// eval to be the global object from which 'eval' originated. This
177
159
// is not mandated by the spec.
178
if (!this_is_global_receiver || global_is_detached) {
179
throw new $EvalError('The "this" object passed to eval must ' +
160
// We only throw if the global has been detached, since we need the
161
// receiver as this-value for the call.
162
if (global_is_detached) {
163
throw new $EvalError('The "this" value passed to eval must ' +
180
164
'be the global object from which eval originated');
183
167
var f = %CompileString(x);
184
168
if (!IS_FUNCTION(f)) return f;
186
return %_CallFunction(receiver, f);
170
return %_CallFunction(global_receiver, f);
193
177
function SetUpGlobal() {
194
178
%CheckIsBootstrapping();
195
179
// ECMA 262 - 15.1.1.1.
196
%SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
180
%SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
198
182
// ECMA-262 - 15.1.1.2.
199
%SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
183
%SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE | READ_ONLY);
201
185
// ECMA-262 - 15.1.1.3.
202
%SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
186
%SetProperty(global, "undefined", void 0,
187
DONT_ENUM | DONT_DELETE | READ_ONLY);
204
189
// Set up non-enumerable function on the global object.
205
190
InstallFunctions(global, DONT_ENUM, $Array(
848
842
// Step 12 - updating an existing accessor property with an accessor
850
if (desc.hasGetter()) {
851
%DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
853
if (desc.hasSetter()) {
854
%DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
844
var getter = desc.hasGetter() ? desc.getGet() : null;
845
var setter = desc.hasSetter() ? desc.getSet() : null;
846
%DefineOrRedefineAccessorProperty(obj, p, getter, setter, flag);
852
// ES5 section 15.4.5.1.
853
function DefineArrayProperty(obj, p, desc, should_throw) {
854
// Note that the length of an array is not actually stored as part of the
855
// property, hence we use generated code throughout this function instead of
856
// DefineObjectProperty() to modify its value.
858
// Step 3 - Special handling for length property.
860
var length = obj.length;
861
if (!desc.hasValue()) {
862
return DefineObjectProperty(obj, "length", desc, should_throw);
864
var new_length = ToUint32(desc.getValue());
865
if (new_length != ToNumber(desc.getValue())) {
866
throw new $RangeError('defineProperty() array length out of range');
868
var length_desc = GetOwnProperty(obj, "length");
869
if (new_length != length && !length_desc.isWritable()) {
871
throw MakeTypeError("redefine_disallowed", [p]);
877
while (new_length < length--) {
878
if (!Delete(obj, ToString(length), false)) {
879
new_length = length + 1;
884
// Make sure the below call to DefineObjectProperty() doesn't overwrite
885
// any magic "length" property by removing the value.
886
obj.length = new_length;
887
desc.value_ = void 0;
888
desc.hasValue_ = false;
889
if (!DefineObjectProperty(obj, "length", desc, should_throw) || threw) {
891
throw MakeTypeError("redefine_disallowed", [p]);
899
// Step 4 - Special handling for array index.
900
var index = ToUint32(p);
901
if (index == ToNumber(p) && index != 4294967295) {
902
var length = obj.length;
903
var length_desc = GetOwnProperty(obj, "length");
904
if ((index >= length && !length_desc.isWritable()) ||
905
!DefineObjectProperty(obj, p, desc, true)) {
907
throw MakeTypeError("define_disallowed", [p]);
912
if (index >= length) {
913
obj.length = index + 1;
918
// Step 5 - Fallback to default implementation.
919
return DefineObjectProperty(obj, p, desc, should_throw);
923
// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
924
function DefineOwnProperty(obj, p, desc, should_throw) {
925
if (%IsJSProxy(obj)) {
926
var attributes = FromGenericPropertyDescriptor(desc);
927
return DefineProxyProperty(obj, p, attributes, should_throw);
928
} else if (IS_ARRAY(obj)) {
929
return DefineArrayProperty(obj, p, desc, should_throw);
931
return DefineObjectProperty(obj, p, desc, should_throw);
861
936
// ES5 section 15.2.3.2.
862
937
function ObjectGetPrototypeOf(obj) {
863
if (!IS_SPEC_OBJECT(obj))
864
throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
938
if (!IS_SPEC_OBJECT(obj)) {
939
throw MakeTypeError("called_on_non_object", ["Object.getPrototypeOf"]);
865
941
return %GetPrototype(obj);
869
945
// ES5 section 15.2.3.3
870
946
function ObjectGetOwnPropertyDescriptor(obj, p) {
871
if (!IS_SPEC_OBJECT(obj))
872
throw MakeTypeError("obj_ctor_property_non_object",
873
["getOwnPropertyDescriptor"]);
947
if (!IS_SPEC_OBJECT(obj)) {
948
throw MakeTypeError("called_on_non_object",
949
["Object.getOwnPropertyDescriptor"]);
874
951
var desc = GetOwnProperty(obj, p);
875
952
return FromPropertyDescriptor(desc);
1022
1101
// ES5 section 15.2.3.7.
1023
1102
function ObjectDefineProperties(obj, properties) {
1024
if (!IS_SPEC_OBJECT(obj))
1025
throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]);
1103
if (!IS_SPEC_OBJECT(obj)) {
1104
throw MakeTypeError("called_on_non_object", ["Object.defineProperties"]);
1026
1106
var props = ToObject(properties);
1027
1107
var names = GetOwnEnumerablePropertyNames(props);
1028
for (var i = 0; i < names.length; i++) {
1029
var name = names[i];
1030
var desc = ToPropertyDescriptor(props[name]);
1031
DefineOwnProperty(obj, name, desc, true);
1108
var descriptors = new InternalArray();
1109
for (var i = 0; i < names.length; i++) {
1110
descriptors.push(ToPropertyDescriptor(props[names[i]]));
1112
for (var i = 0; i < names.length; i++) {
1113
DefineOwnProperty(obj, names[i], descriptors[i], true);
1042
1124
throw MakeTypeError("handler_returned_undefined", [handler, "fix"]);
1045
if (IS_SPEC_FUNCTION(obj)) {
1127
if (%IsJSFunctionProxy(obj)) {
1046
1128
var callTrap = %GetCallTrap(obj);
1047
1129
var constructTrap = %GetConstructTrap(obj);
1048
1130
var code = DelegateCallAndConstruct(callTrap, constructTrap);
1049
1131
%Fix(obj); // becomes a regular function
1050
1132
%SetCode(obj, code);
1133
// TODO(rossberg): What about length and other properties? Not specified.
1134
// We just put in some half-reasonable defaults for now.
1135
var prototype = new $Object();
1136
$Object.defineProperty(prototype, "constructor",
1137
{value: obj, writable: true, enumerable: false, configurable: true});
1138
// TODO(v8:1530): defineProperty does not handle prototype and length.
1139
%FunctionSetPrototype(obj, prototype);
1455
1577
// ES5 15.3.4.5
1456
1578
function FunctionBind(this_arg) { // Length is 1.
1457
1579
if (!IS_SPEC_FUNCTION(this)) {
1458
throw new $TypeError('Bind must be called on a function');
1580
throw new $TypeError('Bind must be called on a function');
1460
// this_arg is not an argument that should be bound.
1461
var argc_bound = (%_ArgumentsLength() || 1) - 1;
1464
if (argc_bound == 0) {
1465
var result = function() {
1466
if (%_IsConstructCall()) {
1467
// %NewObjectFromBound implicitly uses arguments passed to this
1468
// function. We do not pass the arguments object explicitly to avoid
1469
// materializing it and guarantee that this function will be optimized.
1470
return %NewObjectFromBound(fn, null);
1472
return %Apply(fn, this_arg, arguments, 0, %_ArgumentsLength());
1475
var bound_args = new InternalArray(argc_bound);
1476
for(var i = 0; i < argc_bound; i++) {
1477
bound_args[i] = %_Arguments(i+1);
1480
var result = function() {
1481
// If this is a construct call we use a special runtime method
1482
// to generate the actual object using the bound function.
1483
if (%_IsConstructCall()) {
1484
// %NewObjectFromBound implicitly uses arguments passed to this
1485
// function. We do not pass the arguments object explicitly to avoid
1486
// materializing it and guarantee that this function will be optimized.
1487
return %NewObjectFromBound(fn, bound_args);
1490
// Combine the args we got from the bind call with the args
1491
// given as argument to the invocation.
1582
var boundFunction = function () {
1583
// Poison .arguments and .caller, but is otherwise not detectable.
1585
// This function must not use any object literals (Object, Array, RegExp),
1586
// since the literals-array is being used to store the bound data.
1587
if (%_IsConstructCall()) {
1588
return %NewObjectFromBound(boundFunction);
1590
var bindings = %BoundFunctionGetBindings(boundFunction);
1592
var argc = %_ArgumentsLength();
1594
return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
1596
if (bindings.length === 2) {
1597
return %Apply(bindings[0], bindings[1], arguments, 0, argc);
1599
var bound_argc = bindings.length - 2;
1600
var argv = new InternalArray(bound_argc + argc);
1601
for (var i = 0; i < bound_argc; i++) {
1602
argv[i] = bindings[i + 2];
1604
for (var j = 0; j < argc; j++) {
1605
argv[i++] = %_Arguments(j);
1607
return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
1610
%FunctionRemovePrototype(boundFunction);
1612
if (%_ClassOf(this) == "Function") {
1613
// Function or FunctionProxy.
1614
var old_length = this.length;
1615
// FunctionProxies might provide a non-UInt32 value. If so, ignore it.
1616
if ((typeof old_length === "number") &&
1617
((old_length >>> 0) === old_length)) {
1492
1618
var argc = %_ArgumentsLength();
1493
var args = new InternalArray(argc + argc_bound);
1494
// Add bound arguments.
1495
for (var i = 0; i < argc_bound; i++) {
1496
args[i] = bound_args[i];
1498
// Add arguments from call.
1499
for (var i = 0; i < argc; i++) {
1500
args[argc_bound + i] = %_Arguments(i);
1502
return %Apply(fn, this_arg, args, 0, argc + argc_bound);
1619
if (argc > 0) argc--; // Don't count the thisArg as parameter.
1620
new_length = old_length - argc;
1621
if (new_length < 0) new_length = 0;
1624
// This runtime function finds any remaining arguments on the stack,
1625
// so we don't pass the arguments object.
1626
var result = %FunctionBindArguments(boundFunction, this,
1627
this_arg, new_length);
1506
1629
// We already have caller and arguments properties on functions,
1507
1630
// which are non-configurable. It therefore makes no sence to
1509
1632
// that bind should make these throw a TypeError if get or set
1510
1633
// is called and make them non-enumerable and non-configurable.
1511
1634
// To be consistent with our normal functions we leave this as it is.
1513
%FunctionRemovePrototype(result);
1514
%FunctionSetBound(result);
1515
// Set the correct length. If this is a function proxy, this.length might
1516
// throw, or return a bogus result. Leave length alone in that case.
1517
// TODO(rossberg): This is underspecified in the current proxy proposal.
1519
var old_length = ToInteger(this.length);
1520
var length = (old_length - argc_bound) > 0 ? old_length - argc_bound : 0;
1521
%BoundFunctionSetLength(result, length);
1635
// TODO(lrn): Do set these to be thrower.