~ubuntu-branches/ubuntu/vivid/nodejs/vivid

« back to all changes in this revision

Viewing changes to deps/v8/src/v8natives.js

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
28
28
// This file relies on the fact that the following declarations have been made
29
29
//
30
30
// in runtime.js:
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;
36
 
// const $NaN = 0/0;
 
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;
 
36
// var $NaN = 0/0;
37
37
//
38
38
// in math.js:
39
 
// const $floor = MathFloor
 
39
// var $floor = MathFloor
40
40
 
41
 
const $isNaN = GlobalIsNaN;
42
 
const $isFinite = GlobalIsFinite;
 
41
var $isNaN = GlobalIsNaN;
 
42
var $isFinite = GlobalIsFinite;
43
43
 
44
44
// ----------------------------------------------------------------------------
45
45
 
60
60
  %ToFastProperties(object);
61
61
}
62
62
 
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);
72
 
}
73
 
 
74
 
 
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
139
127
    // The spec says ToString should be evaluated before ToInt32.
140
128
    string = TO_STRING_INLINE(string);
141
129
    radix = TO_INT32(radix);
142
 
    if (!(radix == 0 || (2 <= radix && radix <= 36)))
 
130
    if (!(radix == 0 || (2 <= radix && radix <= 36))) {
143
131
      return $NaN;
 
132
    }
144
133
  }
145
134
 
146
135
  if (%_HasCachedArrayIndex(string) &&
162
151
function GlobalEval(x) {
163
152
  if (!IS_STRING(x)) return x;
164
153
 
165
 
  var receiver = this;
166
154
  var global_receiver = %GlobalReceiver(global);
167
 
 
168
 
  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
169
 
    receiver = global_receiver;
170
 
  }
171
 
 
172
 
  var this_is_global_receiver = (receiver === global_receiver);
173
155
  var global_is_detached = (global === global_receiver);
174
156
 
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');
181
165
  }
182
166
 
183
167
  var f = %CompileString(x);
184
168
  if (!IS_FUNCTION(f)) return f;
185
169
 
186
 
  return %_CallFunction(receiver, f);
 
170
  return %_CallFunction(global_receiver, f);
187
171
}
188
172
 
189
173
 
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);
197
181
 
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);
200
184
 
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);
203
188
 
204
189
  // Set up non-enumerable function on the global object.
205
190
  InstallFunctions(global, DONT_ENUM, $Array(
299
284
    receiver = %GlobalReceiver(global);
300
285
  }
301
286
  if (!IS_SPEC_FUNCTION(fun)) {
302
 
    throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
 
287
    throw new $TypeError(
 
288
        'Object.prototype.__defineGetter__: Expecting function');
303
289
  }
304
290
  var desc = new PropertyDescriptor();
305
291
  desc.setGet(fun);
345
331
 
346
332
 
347
333
function ObjectKeys(obj) {
348
 
  if (!IS_SPEC_OBJECT(obj))
349
 
    throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
 
334
  if (!IS_SPEC_OBJECT(obj)) {
 
335
    throw MakeTypeError("called_on_non_object", ["Object.keys"]);
 
336
  }
350
337
  if (%IsJSProxy(obj)) {
351
338
    var handler = %GetHandler(obj);
352
339
    var names = CallTrap0(handler, "keys", DerivedKeysTrap);
353
 
    return ToStringArray(names);
 
340
    return ToStringArray(names, "keys");
354
341
  }
355
342
  return %LocalKeys(obj);
356
343
}
372
359
 
373
360
// ES5 8.10.3.
374
361
function IsGenericDescriptor(desc) {
 
362
  if (IS_UNDEFINED(desc)) return false;
375
363
  return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
376
364
}
377
365
 
476
464
 
477
465
// For Harmony proxies.
478
466
function ToCompletePropertyDescriptor(obj) {
479
 
  var desc = ToPropertyDescriptor(obj)
 
467
  var desc = ToPropertyDescriptor(obj);
480
468
  if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
481
469
    if (!desc.hasValue()) desc.setValue(void 0);
482
470
    if (!desc.hasWritable()) desc.setWritable(false);
672
660
}
673
661
 
674
662
 
 
663
// ES5 section 8.12.7.
 
664
function Delete(obj, p, should_throw) {
 
665
  var desc = GetOwnProperty(obj, p);
 
666
  if (IS_UNDEFINED(desc)) return true;
 
667
  if (desc.isConfigurable()) {
 
668
    %DeleteProperty(obj, p, 0);
 
669
    return true;
 
670
  } else if (should_throw) {
 
671
    throw MakeTypeError("define_disallowed", [p]);
 
672
  } else {
 
673
    return;
 
674
  }
 
675
}
 
676
 
 
677
 
675
678
// Harmony proxies.
676
679
function DefineProxyProperty(obj, p, attributes, should_throw) {
677
680
  var handler = %GetHandler(obj);
689
692
 
690
693
 
691
694
// ES5 8.12.9.
692
 
function DefineOwnProperty(obj, p, desc, should_throw) {
693
 
  if (%IsJSProxy(obj)) {
694
 
    var attributes = FromGenericPropertyDescriptor(desc);
695
 
    return DefineProxyProperty(obj, p, attributes, should_throw);
696
 
  }
697
 
 
 
695
function DefineObjectProperty(obj, p, desc, should_throw) {
698
696
  var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
699
697
  // A false value here means that access checks failed.
700
698
  if (current_or_access === false) return void 0;
708
706
    if (should_throw) {
709
707
      throw MakeTypeError("define_disallowed", [p]);
710
708
    } else {
711
 
      return;
 
709
      return false;
712
710
    }
713
711
  }
714
712
 
738
736
        if (should_throw) {
739
737
          throw MakeTypeError("redefine_disallowed", [p]);
740
738
        } else {
741
 
          return;
 
739
          return false;
742
740
        }
743
741
      }
744
742
      // Step 8
748
746
          if (should_throw) {
749
747
            throw MakeTypeError("redefine_disallowed", [p]);
750
748
          } else {
751
 
            return;
 
749
            return false;
752
750
          }
753
751
        }
754
752
        // Step 10a
757
755
            if (should_throw) {
758
756
              throw MakeTypeError("redefine_disallowed", [p]);
759
757
            } else {
760
 
              return;
 
758
              return false;
761
759
            }
762
760
          }
763
761
          if (!current.isWritable() && desc.hasValue() &&
765
763
            if (should_throw) {
766
764
              throw MakeTypeError("redefine_disallowed", [p]);
767
765
            } else {
768
 
              return;
 
766
              return false;
769
767
            }
770
768
          }
771
769
        }
775
773
            if (should_throw) {
776
774
              throw MakeTypeError("redefine_disallowed", [p]);
777
775
            } else {
778
 
              return;
 
776
              return false;
779
777
            }
780
778
          }
781
779
          if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
782
780
            if (should_throw) {
783
781
              throw MakeTypeError("redefine_disallowed", [p]);
784
782
            } else {
785
 
              return;
 
783
              return false;
786
784
            }
787
785
          }
788
786
        }
836
834
    }
837
835
 
838
836
    %DefineOrRedefineDataProperty(obj, p, value, flag);
839
 
  } else if (IsGenericDescriptor(desc)) {
840
 
    // Step 12 - updating an existing accessor property with generic
841
 
    //           descriptor. Changing flags only.
842
 
    %DefineOrRedefineAccessorProperty(obj, p, GETTER, current.getGet(), flag);
843
837
  } else {
844
838
    // There are 3 cases that lead here:
845
839
    // Step 4b - defining a new accessor property.
847
841
    //                 property.
848
842
    // Step 12 - updating an existing accessor property with an accessor
849
843
    //           descriptor.
850
 
    if (desc.hasGetter()) {
851
 
      %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
852
 
    }
853
 
    if (desc.hasSetter()) {
854
 
      %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
855
 
    }
 
844
    var getter = desc.hasGetter() ? desc.getGet() : null;
 
845
    var setter = desc.hasSetter() ? desc.getSet() : null;
 
846
    %DefineOrRedefineAccessorProperty(obj, p, getter, setter, flag);
856
847
  }
857
848
  return true;
858
849
}
859
850
 
860
851
 
 
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.
 
857
 
 
858
  // Step 3 - Special handling for length property.
 
859
  if (p == "length") {
 
860
    var length = obj.length;
 
861
    if (!desc.hasValue()) {
 
862
      return DefineObjectProperty(obj, "length", desc, should_throw);
 
863
    }
 
864
    var new_length = ToUint32(desc.getValue());
 
865
    if (new_length != ToNumber(desc.getValue())) {
 
866
      throw new $RangeError('defineProperty() array length out of range');
 
867
    }
 
868
    var length_desc = GetOwnProperty(obj, "length");
 
869
    if (new_length != length && !length_desc.isWritable()) {
 
870
      if (should_throw) {
 
871
        throw MakeTypeError("redefine_disallowed", [p]);
 
872
      } else {
 
873
        return false;
 
874
      }
 
875
    }
 
876
    var threw = false;
 
877
    while (new_length < length--) {
 
878
      if (!Delete(obj, ToString(length), false)) {
 
879
        new_length = length + 1;
 
880
        threw = true;
 
881
        break;
 
882
      }
 
883
    }
 
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) {
 
890
      if (should_throw) {
 
891
        throw MakeTypeError("redefine_disallowed", [p]);
 
892
      } else {
 
893
        return false;
 
894
      }
 
895
    }
 
896
    return true;
 
897
  }
 
898
 
 
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)) {
 
906
      if (should_throw) {
 
907
        throw MakeTypeError("define_disallowed", [p]);
 
908
      } else {
 
909
        return false;
 
910
      }
 
911
    }
 
912
    if (index >= length) {
 
913
      obj.length = index + 1;
 
914
    }
 
915
    return true;
 
916
  }
 
917
 
 
918
  // Step 5 - Fallback to default implementation.
 
919
  return DefineObjectProperty(obj, p, desc, should_throw);
 
920
}
 
921
 
 
922
 
 
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);
 
930
  } else {
 
931
    return DefineObjectProperty(obj, p, desc, should_throw);
 
932
  }
 
933
}
 
934
 
 
935
 
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"]);
 
940
  }
865
941
  return %GetPrototype(obj);
866
942
}
867
943
 
868
944
 
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"]);
 
950
  }
874
951
  var desc = GetOwnProperty(obj, p);
875
952
  return FromPropertyDescriptor(desc);
876
953
}
883
960
  }
884
961
  var n = ToUint32(obj.length);
885
962
  var array = new $Array(n);
886
 
  var names = {}
 
963
  var names = {};  // TODO(rossberg): use sets once they are ready.
887
964
  for (var index = 0; index < n; index++) {
888
965
    var s = ToString(obj[index]);
889
 
    if (s in names) {
890
 
      throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s])
 
966
    if (%HasLocalProperty(names, s)) {
 
967
      throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]);
891
968
    }
892
969
    array[index] = s;
893
 
    names.s = 0;
 
970
    names[s] = 0;
894
971
  }
895
972
  return array;
896
973
}
898
975
 
899
976
// ES5 section 15.2.3.4.
900
977
function ObjectGetOwnPropertyNames(obj) {
901
 
  if (!IS_SPEC_OBJECT(obj))
902
 
    throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
903
 
 
 
978
  if (!IS_SPEC_OBJECT(obj)) {
 
979
    throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
 
980
  }
904
981
  // Special handling for proxies.
905
982
  if (%IsJSProxy(obj)) {
906
983
    var handler = %GetHandler(obj);
917
994
  if (%GetInterceptorInfo(obj) & 1) {
918
995
    var indexedInterceptorNames =
919
996
        %GetIndexedInterceptorElementNames(obj);
920
 
    if (indexedInterceptorNames)
 
997
    if (indexedInterceptorNames) {
921
998
      propertyNames = propertyNames.concat(indexedInterceptorNames);
 
999
    }
922
1000
  }
923
1001
 
924
1002
  // Find all the named properties.
944
1022
    // We need to check for the exact property value since for intrinsic
945
1023
    // properties like toString if(propertySet["toString"]) will always
946
1024
    // succeed.
947
 
    if (propertySet[name] === true)
 
1025
    if (propertySet[name] === true) {
948
1026
      continue;
 
1027
    }
949
1028
    propertySet[name] = true;
950
1029
    propertyNames[j++] = name;
951
1030
  }
970
1049
// ES5 section 15.2.3.6.
971
1050
function ObjectDefineProperty(obj, p, attributes) {
972
1051
  if (!IS_SPEC_OBJECT(obj)) {
973
 
    throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]);
 
1052
    throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]);
974
1053
  }
975
1054
  var name = ToString(p);
976
1055
  if (%IsJSProxy(obj)) {
1021
1100
 
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"]);
 
1105
  }
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]]));
 
1111
  }
 
1112
  for (var i = 0; i < names.length; i++) {
 
1113
    DefineOwnProperty(obj, names[i], descriptors[i], true);
1032
1114
  }
1033
1115
  return obj;
1034
1116
}
1042
1124
    throw MakeTypeError("handler_returned_undefined", [handler, "fix"]);
1043
1125
  }
1044
1126
 
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);
 
1140
    obj.length = 0;
1051
1141
  } else {
1052
1142
    %Fix(obj);
1053
1143
  }
1058
1148
// ES5 section 15.2.3.8.
1059
1149
function ObjectSeal(obj) {
1060
1150
  if (!IS_SPEC_OBJECT(obj)) {
1061
 
    throw MakeTypeError("obj_ctor_property_non_object", ["seal"]);
 
1151
    throw MakeTypeError("called_on_non_object", ["Object.seal"]);
1062
1152
  }
1063
1153
  if (%IsJSProxy(obj)) {
1064
1154
    ProxyFix(obj);
1080
1170
// ES5 section 15.2.3.9.
1081
1171
function ObjectFreeze(obj) {
1082
1172
  if (!IS_SPEC_OBJECT(obj)) {
1083
 
    throw MakeTypeError("obj_ctor_property_non_object", ["freeze"]);
 
1173
    throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
1084
1174
  }
1085
1175
  if (%IsJSProxy(obj)) {
1086
1176
    ProxyFix(obj);
1103
1193
// ES5 section 15.2.3.10
1104
1194
function ObjectPreventExtension(obj) {
1105
1195
  if (!IS_SPEC_OBJECT(obj)) {
1106
 
    throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
 
1196
    throw MakeTypeError("called_on_non_object", ["Object.preventExtension"]);
1107
1197
  }
1108
1198
  if (%IsJSProxy(obj)) {
1109
1199
    ProxyFix(obj);
1116
1206
// ES5 section 15.2.3.11
1117
1207
function ObjectIsSealed(obj) {
1118
1208
  if (!IS_SPEC_OBJECT(obj)) {
1119
 
    throw MakeTypeError("obj_ctor_property_non_object", ["isSealed"]);
 
1209
    throw MakeTypeError("called_on_non_object", ["Object.isSealed"]);
1120
1210
  }
1121
1211
  if (%IsJSProxy(obj)) {
1122
1212
    return false;
1137
1227
// ES5 section 15.2.3.12
1138
1228
function ObjectIsFrozen(obj) {
1139
1229
  if (!IS_SPEC_OBJECT(obj)) {
1140
 
    throw MakeTypeError("obj_ctor_property_non_object", ["isFrozen"]);
 
1230
    throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]);
1141
1231
  }
1142
1232
  if (%IsJSProxy(obj)) {
1143
1233
    return false;
1159
1249
// ES5 section 15.2.3.13
1160
1250
function ObjectIsExtensible(obj) {
1161
1251
  if (!IS_SPEC_OBJECT(obj)) {
1162
 
    throw MakeTypeError("obj_ctor_property_non_object", ["isExtensible"]);
 
1252
    throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]);
1163
1253
  }
1164
1254
  if (%IsJSProxy(obj)) {
1165
1255
    return true;
1168
1258
}
1169
1259
 
1170
1260
 
 
1261
// Harmony egal.
 
1262
function ObjectIs(obj1, obj2) {
 
1263
  if (obj1 === obj2) {
 
1264
    return (obj1 !== 0) || (1 / obj1 === 1 / obj2);
 
1265
  } else {
 
1266
    return (obj1 !== obj1) && (obj2 !== obj2);
 
1267
  }
 
1268
}
 
1269
 
 
1270
 
1171
1271
%SetCode($Object, function(x) {
1172
1272
  if (%_IsConstructCall()) {
1173
1273
    if (x == null) return this;
1207
1307
    "getPrototypeOf", ObjectGetPrototypeOf,
1208
1308
    "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
1209
1309
    "getOwnPropertyNames", ObjectGetOwnPropertyNames,
 
1310
    "is", ObjectIs,
1210
1311
    "isExtensible", ObjectIsExtensible,
1211
1312
    "isFrozen", ObjectIsFrozen,
1212
1313
    "isSealed", ObjectIsSealed,
1237
1338
function BooleanValueOf() {
1238
1339
  // NOTE: Both Boolean objects and values can enter here as
1239
1340
  // 'this'. This is not as dictated by ECMA-262.
1240
 
  if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this))
 
1341
  if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) {
1241
1342
    throw new $TypeError('Boolean.prototype.valueOf is not generic');
 
1343
  }
1242
1344
  return %_ValueOf(this);
1243
1345
}
1244
1346
 
1278
1380
  // 'this'. This is not as dictated by ECMA-262.
1279
1381
  var number = this;
1280
1382
  if (!IS_NUMBER(this)) {
1281
 
    if (!IS_NUMBER_WRAPPER(this))
 
1383
    if (!IS_NUMBER_WRAPPER(this)) {
1282
1384
      throw new $TypeError('Number.prototype.toString is not generic');
 
1385
    }
1283
1386
    // Get the value of this number in case it's an object.
1284
1387
    number = %_ValueOf(this);
1285
1388
  }
1312
1415
function NumberValueOf() {
1313
1416
  // NOTE: Both Number objects and values can enter here as
1314
1417
  // 'this'. This is not as dictated by ECMA-262.
1315
 
  if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this))
 
1418
  if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) {
1316
1419
    throw new $TypeError('Number.prototype.valueOf is not generic');
 
1420
  }
1317
1421
  return %_ValueOf(this);
1318
1422
}
1319
1423
 
1339
1443
  if (!IS_UNDEFINED(fractionDigits)) {
1340
1444
    f = TO_INTEGER(fractionDigits);
1341
1445
    if (f < 0 || f > 20) {
1342
 
      throw new $RangeError("toExponential() argument must be between 0 and 20");
 
1446
      throw new $RangeError(
 
1447
          "toExponential() argument must be between 0 and 20");
1343
1448
    }
1344
1449
  }
1345
1450
  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1367
1472
}
1368
1473
 
1369
1474
 
 
1475
// Harmony isFinite.
 
1476
function NumberIsFinite(number) {
 
1477
  return IS_NUMBER(number) && NUMBER_IS_FINITE(number);
 
1478
}
 
1479
 
 
1480
 
 
1481
// Harmony isNaN.
 
1482
function NumberIsNaN(number) {
 
1483
  return IS_NUMBER(number) && NUMBER_IS_NAN(number);
 
1484
}
 
1485
 
 
1486
 
1370
1487
// ----------------------------------------------------------------------------
1371
1488
 
1372
1489
function SetUpNumber() {
1383
1500
               DONT_ENUM | DONT_DELETE | READ_ONLY);
1384
1501
 
1385
1502
  // ECMA-262 section 15.7.3.2.
1386
 
  %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
 
1503
  %SetProperty($Number, "MIN_VALUE", 5e-324,
 
1504
               DONT_ENUM | DONT_DELETE | READ_ONLY);
1387
1505
 
1388
1506
  // ECMA-262 section 15.7.3.3.
1389
1507
  %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
1410
1528
    "toExponential", NumberToExponential,
1411
1529
    "toPrecision", NumberToPrecision
1412
1530
  ));
 
1531
  InstallFunctions($Number, DONT_ENUM, $Array(
 
1532
    "isFinite", NumberIsFinite,
 
1533
    "isNaN", NumberIsNaN
 
1534
  ));
1413
1535
}
1414
1536
 
1415
1537
SetUpNumber();
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');
1459
1581
  }
1460
 
  // this_arg is not an argument that should be bound.
1461
 
  var argc_bound = (%_ArgumentsLength() || 1) - 1;
1462
 
  var fn = this;
1463
 
 
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);
1471
 
      }
1472
 
      return %Apply(fn, this_arg, arguments, 0, %_ArgumentsLength());
1473
 
    };
1474
 
  } else {
1475
 
    var bound_args = new InternalArray(argc_bound);
1476
 
    for(var i = 0; i < argc_bound; i++) {
1477
 
      bound_args[i] = %_Arguments(i+1);
1478
 
    }
1479
 
 
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);
1488
 
      }
1489
 
 
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.
 
1584
    "use strict";
 
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);
 
1589
    }
 
1590
    var bindings = %BoundFunctionGetBindings(boundFunction);
 
1591
 
 
1592
    var argc = %_ArgumentsLength();
 
1593
    if (argc == 0) {
 
1594
      return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
 
1595
    }
 
1596
    if (bindings.length === 2) {
 
1597
      return %Apply(bindings[0], bindings[1], arguments, 0, argc);
 
1598
    }
 
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];
 
1603
    }
 
1604
    for (var j = 0; j < argc; j++) {
 
1605
      argv[i++] = %_Arguments(j);
 
1606
    }
 
1607
    return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
 
1608
  };
 
1609
 
 
1610
  %FunctionRemovePrototype(boundFunction);
 
1611
  var new_length = 0;
 
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];
1497
 
      }
1498
 
      // Add arguments from call.
1499
 
      for (var i = 0; i < argc; i++) {
1500
 
        args[argc_bound + i] = %_Arguments(i);
1501
 
      }
1502
 
      return %Apply(fn, this_arg, args, 0, argc + argc_bound);
1503
 
    };
 
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;
 
1622
    }
1504
1623
  }
 
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);
1505
1628
 
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.
1512
 
 
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.
1518
 
  try {
1519
 
    var old_length = ToInteger(this.length);
1520
 
    var length = (old_length - argc_bound) > 0 ? old_length - argc_bound : 0;
1521
 
    %BoundFunctionSetLength(result, length);
1522
 
  } catch(x) {}
 
1635
  // TODO(lrn): Do set these to be thrower.
1523
1636
  return result;
1524
1637
}
1525
1638
 
1541
1654
 
1542
1655
  // The call to SetNewFunctionAttributes will ensure the prototype
1543
1656
  // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
1544
 
  var f = %CompileString(source)();
 
1657
  var global_receiver = %GlobalReceiver(global);
 
1658
  var f = %_CallFunction(global_receiver, %CompileString(source));
 
1659
 
1545
1660
  %FunctionMarkNameShouldPrintAsAnonymous(f);
1546
1661
  return %SetNewFunctionAttributes(f);
1547
1662
}