13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This file relies on the fact that the following declarations have been made
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in runtime.js:
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Object = global.Object;
323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Boolean = global.Boolean;
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Number = global.Number;
343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Function = global.Function;
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $Array = global.Array;
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $NaN = 0/0;
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// in math.js:
393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// var $floor = MathFloor
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $isNaN = GlobalIsNaN;
423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar $isFinite = GlobalIsFinite;
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper function used to install functions on objects.
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction InstallFunctions(object, attributes, functions) {
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (functions.length >= 8) {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < functions.length; i += 2) {
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var key = functions[i];
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var f = functions[i + 1];
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    %FunctionSetName(f, key);
566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    %FunctionRemovePrototype(f);
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    %SetProperty(object, key, f, attributes);
583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %SetNativeFlag(f);
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
60402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  %ToFastProperties(object);
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Prevents changes to the prototype of a built-infunction.
64589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// The "prototype" property of the function object is made non-configurable,
65589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// and the prototype object is made non-extensible. The latter prevents
66589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// changing the __proto__ property.
67589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpLockedPrototype(constructor, fields, methods) {
68589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
69589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var prototype = constructor.prototype;
70589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Install functions first, because this function is used to initialize
71589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // PropertyDescriptor itself.
72589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  var property_count = (methods.length >> 1) + (fields ? fields.length : 0);
73589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (property_count >= 4) {
74589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %OptimizeObjectForAddingMultipleProperties(prototype, property_count);
75589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
76589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (fields) {
77589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    for (var i = 0; i < fields.length; i++) {
78589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      %SetProperty(prototype, fields[i], void 0, DONT_ENUM | DONT_DELETE);
79589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
80589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
81589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  for (var i = 0; i < methods.length; i += 2) {
82589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var key = methods[i];
83589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var f = methods[i + 1];
84589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
85589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetNativeFlag(f);
86589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
87589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  prototype.__proto__ = null;
88589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %ToFastProperties(prototype);
89589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
90589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
91589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA 262 - 15.1.4
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GlobalIsNaN(number) {
97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_NUMBER(number)) number = NonNumberToNumber(number);
98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return NUMBER_IS_NAN(number);
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA 262 - 15.1.5
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GlobalIsFinite(number) {
104086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_NUMBER(number)) number = NonNumberToNumber(number);
105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return NUMBER_IS_FINITE(number);
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.1.2.2
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GlobalParseInt(string, radix) {
111e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if (IS_UNDEFINED(radix) || radix === 10 || radix === 0) {
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Some people use parseInt instead of Math.floor.  This
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // optimization makes parseInt on a Smi 12 times faster (60ns
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // vs 800ns).  The following optimization makes parseInt on a
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // non-Smi number 9 times faster (230ns vs 2070ns).  Together
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // they make parseInt on a string 1.4% slower (274ns vs 270ns).
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (%_IsSmi(string)) return string;
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (IS_NUMBER(string) &&
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        ((0.01 < string && string < 1e9) ||
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block            (-1e9 < string && string < -0.01))) {
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Truncate number.
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return string | 0;
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
12469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    string = TO_STRING_INLINE(string);
1253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    radix = radix | 0;
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
12769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    // The spec says ToString should be evaluated before ToInt32.
12869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    string = TO_STRING_INLINE(string);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    radix = TO_INT32(radix);
1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!(radix == 0 || (2 <= radix && radix <= 36))) {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return $NaN;
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
13469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
13580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (%_HasCachedArrayIndex(string) &&
13680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      (radix == 0 || radix == 10)) {
13780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    return %_GetCachedArrayIndex(string);
13880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  }
13980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return %StringParseInt(string, radix);
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.1.2.3
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GlobalParseFloat(string) {
14580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  string = TO_STRING_INLINE(string);
14680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  if (%_HasCachedArrayIndex(string)) return %_GetCachedArrayIndex(string);
14780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  return %StringParseFloat(string);
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GlobalEval(x) {
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_STRING(x)) return x;
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var global_receiver = %GlobalReceiver(global);
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var global_is_detached = (global === global_receiver);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // For consistency with JSC we require the global object passed to
1583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // eval to be the global object from which 'eval' originated. This
1593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // is not mandated by the spec.
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // We only throw if the global has been detached, since we need the
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // receiver as this-value for the call.
1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (global_is_detached) {
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw new $EvalError('The "this" value passed to eval must ' +
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         'be the global object from which eval originated');
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1673e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  var f = %CompileString(x);
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_FUNCTION(f)) return f;
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return %_CallFunction(global_receiver, f);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
176589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Set up global object.
177589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpGlobal() {
178589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA 262 - 15.1.1.1.
1803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 - 15.1.1.2.
1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE | READ_ONLY);
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 - 15.1.1.3.
1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %SetProperty(global, "undefined", void 0,
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               DONT_ENUM | DONT_DELETE | READ_ONLY);
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set up non-enumerable function on the global object.
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions(global, DONT_ENUM, $Array(
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "isNaN", GlobalIsNaN,
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "isFinite", GlobalIsFinite,
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "parseInt", GlobalParseInt,
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "parseFloat", GlobalParseFloat,
195053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    "eval", GlobalEval
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
199589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpGlobal();
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Boolean (first part of definition)
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode($Boolean, function(x) {
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsConstructCall()) {
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    %_SetValueOf(this, ToBoolean(x));
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ToBoolean(x);
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block});
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetPrototype($Boolean, new $Boolean(false));
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Object
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block$Object.prototype.constructor = $Object;
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.2
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectToString() {
224257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return '[object Undefined]';
226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
22769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (IS_NULL(this)) return '[object Null]';
228d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return "[object " + %_ClassOf(ToObject(this)) + "]";
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.3
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectToLocaleString() {
234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Object.prototype.toLocaleString"]);
237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.toString();
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.4
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectValueOf() {
244d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  return ToObject(this);
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.5
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectHasOwnProperty(V) {
25069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (%IsJSProxy(this)) {
25169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    var handler = %GetHandler(this);
25269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return CallTrap1(handler, "hasOwn", DerivedHasOwnTrap, TO_STRING_INLINE(V));
25369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return %HasLocalProperty(TO_OBJECT_INLINE(this), TO_STRING_INLINE(V));
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.6
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectIsPrototypeOf(V) {
260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Object.prototype.isPrototypeOf"]);
263257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
2643bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(V)) return false;
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %IsInPrototypeChain(this, V);
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 - 15.2.4.6
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectPropertyIsEnumerable(V) {
27169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var P = ToString(V);
27269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (%IsJSProxy(this)) {
27369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    var desc = GetOwnProperty(this, P);
27469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return IS_UNDEFINED(desc) ? false : desc.isEnumerable();
27569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
27669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return %IsPropertyEnumerable(ToObject(this), P);
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Extensions for providing property getters and setters.
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectDefineGetter(name, fun) {
2823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var receiver = this;
2833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
2843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    receiver = %GlobalReceiver(global);
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
286589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_SPEC_FUNCTION(fun)) {
2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw new $TypeError(
2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        'Object.prototype.__defineGetter__: Expecting function');
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  var desc = new PropertyDescriptor();
29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setGet(fun);
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setEnumerable(true);
29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setConfigurable(true);
2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectLookupGetter(name) {
2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var receiver = this;
3003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
3013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    receiver = %GlobalReceiver(global);
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return %LookupAccessor(ToObject(receiver), ToString(name), GETTER);
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectDefineSetter(name, fun) {
3083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var receiver = this;
3093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
3103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    receiver = %GlobalReceiver(global);
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
312589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_SPEC_FUNCTION(fun)) {
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $TypeError(
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        'Object.prototype.__defineSetter__: Expecting function');
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
31644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  var desc = new PropertyDescriptor();
31744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setSet(fun);
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setEnumerable(true);
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  desc.setConfigurable(true);
3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  DefineOwnProperty(ToObject(receiver), ToString(name), desc, false);
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectLookupSetter(name) {
3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var receiver = this;
3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (receiver == null && !IS_UNDETECTABLE(receiver)) {
3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    receiver = %GlobalReceiver(global);
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return %LookupAccessor(ToObject(receiver), ToString(name), SETTER);
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ObjectKeys(obj) {
3343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(obj)) {
3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.keys"]);
3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
3373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
3383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var handler = %GetHandler(obj);
33969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    var names = CallTrap0(handler, "keys", DerivedKeysTrap);
3403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return ToStringArray(names);
3413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %LocalKeys(obj);
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 8.10.1.
347e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction IsAccessorDescriptor(desc) {
348e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IS_UNDEFINED(desc)) return false;
3493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return desc.hasGetter() || desc.hasSetter();
350e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
351e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
352e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
353e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 8.10.2.
354e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction IsDataDescriptor(desc) {
355e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IS_UNDEFINED(desc)) return false;
3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return desc.hasValue() || desc.hasWritable();
357e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
358e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
359e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
360e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 8.10.3.
361e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction IsGenericDescriptor(desc) {
3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IS_UNDEFINED(desc)) return false;
363e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
364e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
365e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
366e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
367e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction IsInconsistentDescriptor(desc) {
368e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
369e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
370e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
372e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 8.10.4
373e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction FromPropertyDescriptor(desc) {
3743100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (IS_UNDEFINED(desc)) return desc;
375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
376e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IsDataDescriptor(desc)) {
377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return { value: desc.getValue(),
378257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             writable: desc.isWritable(),
379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             enumerable: desc.isEnumerable(),
380257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             configurable: desc.isConfigurable() };
381e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
382257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Must be an AccessorDescriptor then. We never return a generic descriptor.
383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return { get: desc.getGet(),
384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch           set: desc.getSet(),
385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch           enumerable: desc.isEnumerable(),
386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch           configurable: desc.isConfigurable() };
387e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
388e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
3893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Harmony Proxies
3913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction FromGenericPropertyDescriptor(desc) {
3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IS_UNDEFINED(desc)) return desc;
3933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var obj = new $Object();
3943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasValue()) {
3963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "value", desc.getValue(), NONE);
3973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
3983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasWritable()) {
3993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "writable", desc.isWritable(), NONE);
4003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4013fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasGetter()) {
4023fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "get", desc.getGet(), NONE);
4033fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4043fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasSetter()) {
4053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "set", desc.getSet(), NONE);
4063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasEnumerable()) {
4083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "enumerable",
4093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                    desc.isEnumerable(), NONE);
4103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (desc.hasConfigurable()) {
4123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    %IgnoreAttributesAndSetProperty(obj, "configurable",
4133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                    desc.isConfigurable(), NONE);
4143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return obj;
4163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
419e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 8.10.5.
420e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ToPropertyDescriptor(obj) {
4213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
422e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    throw MakeTypeError("property_desc_object", [obj]);
423e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
424e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var desc = new PropertyDescriptor();
425e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
426e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("enumerable" in obj) {
427e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setEnumerable(ToBoolean(obj.enumerable));
428e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
429e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
430e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("configurable" in obj) {
431e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setConfigurable(ToBoolean(obj.configurable));
432e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
433e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
434e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("value" in obj) {
435e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setValue(obj.value);
436e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
437e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
438e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("writable" in obj) {
439e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setWritable(ToBoolean(obj.writable));
440e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
441e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
442e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("get" in obj) {
443e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var get = obj.get;
444589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (!IS_UNDEFINED(get) && !IS_SPEC_FUNCTION(get)) {
445e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      throw MakeTypeError("getter_must_be_callable", [get]);
446e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
447e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setGet(get);
448e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
449e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
450e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if ("set" in obj) {
451e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var set = obj.set;
452589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (!IS_UNDEFINED(set) && !IS_SPEC_FUNCTION(set)) {
453e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      throw MakeTypeError("setter_must_be_callable", [set]);
454e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
455e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    desc.setSet(set);
456e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
457e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
458e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (IsInconsistentDescriptor(desc)) {
459e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    throw MakeTypeError("value_and_accessor", [obj]);
460e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
461e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return desc;
462e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
463e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
464e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
4653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// For Harmony proxies.
4663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction ToCompletePropertyDescriptor(obj) {
4673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var desc = ToPropertyDescriptor(obj);
4683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IsGenericDescriptor(desc) || IsDataDescriptor(desc)) {
4693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!desc.hasValue()) desc.setValue(void 0);
4703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!desc.hasWritable()) desc.setWritable(false);
4713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
4723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Is accessor descriptor.
4733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!desc.hasGetter()) desc.setGet(void 0);
4743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!desc.hasSetter()) desc.setSet(void 0);
4753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
4763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!desc.hasEnumerable()) desc.setEnumerable(false);
4773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!desc.hasConfigurable()) desc.setConfigurable(false);
4783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return desc;
4793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
4803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
4813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
482e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction PropertyDescriptor() {
483e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Initialize here so they are all in-object and have the same map.
484e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Default values from ES5 8.6.1.
485e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.value_ = void 0;
486e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.hasValue_ = false;
487e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.writable_ = false;
488e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.hasWritable_ = false;
489e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.enumerable_ = false;
4903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  this.hasEnumerable_ = false;
491e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.configurable_ = false;
4923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  this.hasConfigurable_ = false;
493e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.get_ = void 0;
494e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.hasGetter_ = false;
495e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.set_ = void 0;
496e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  this.hasSetter_ = false;
497e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
498e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
499589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(PropertyDescriptor, $Array(
500589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "value_",
501589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasValue_",
502589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "writable_",
503589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasWritable_",
504589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "enumerable_",
505589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasEnumerable_",
506589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "configurable_",
507589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasConfigurable_",
508589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "get_",
509589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasGetter_",
510589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "set_",
511589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasSetter_"
512589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  ), $Array(
513589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "toString", function() {
514589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return "[object PropertyDescriptor]";
515589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
516589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setValue", function(value) {
517589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.value_ = value;
518589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.hasValue_ = true;
519589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
520589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "getValue", function() {
521589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.value_;
522589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
523589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasValue", function() {
524589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasValue_;
525589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
526589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setEnumerable", function(enumerable) {
527589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.enumerable_ = enumerable;
528589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        this.hasEnumerable_ = true;
529589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
530589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "isEnumerable", function () {
531589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.enumerable_;
532589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
533589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasEnumerable", function() {
534589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasEnumerable_;
535589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
536589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setWritable", function(writable) {
537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.writable_ = writable;
538589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.hasWritable_ = true;
539589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
540589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "isWritable", function() {
541589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.writable_;
542589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
543589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasWritable", function() {
544589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasWritable_;
545589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
546589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setConfigurable", function(configurable) {
547589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.configurable_ = configurable;
548589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.hasConfigurable_ = true;
549589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
550589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasConfigurable", function() {
551589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasConfigurable_;
552589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
553589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "isConfigurable", function() {
554589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.configurable_;
555589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
556589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setGet", function(get) {
557589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.get_ = get;
558589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        this.hasGetter_ = true;
559589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
560589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "getGet", function() {
561589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.get_;
562589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
563589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasGetter", function() {
564589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasGetter_;
565589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
566589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "setSet", function(set) {
567589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.set_ = set;
568589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      this.hasSetter_ = true;
569589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
570589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "getSet", function() {
571589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.set_;
572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    },
573589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "hasSetter", function() {
574589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      return this.hasSetter_;
575589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }));
5763100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5773100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
5781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// Converts an array returned from Runtime_GetOwnProperty to an actual
5791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// property descriptor. For a description of the array layout please
5801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// see the runtime.cc file.
5811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockfunction ConvertDescriptorArrayToDescriptor(desc_array) {
58244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (desc_array === false) {
5831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    throw 'Internal error: invalid desc_array';
5841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
585e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
5861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (IS_UNDEFINED(desc_array)) {
5871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return void 0;
5881e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
589b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var desc = new PropertyDescriptor();
5911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // This is an accessor.
5921e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (desc_array[IS_ACCESSOR_INDEX]) {
5931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    desc.setGet(desc_array[GETTER_INDEX]);
5941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    desc.setSet(desc_array[SETTER_INDEX]);
595e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
5961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    desc.setValue(desc_array[VALUE_INDEX]);
5971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    desc.setWritable(desc_array[WRITABLE_INDEX]);
598e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
5991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
6001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
601e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
602e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return desc;
603e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
604e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
605e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
60669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch// For Harmony proxies.
60769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction GetTrap(handler, name, defaultTrap) {
60869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var trap = handler[name];
60969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  if (IS_UNDEFINED(trap)) {
61069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if (IS_UNDEFINED(defaultTrap)) {
61169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      throw MakeTypeError("handler_trap_missing", [handler, name]);
61269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
61369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    trap = defaultTrap;
614589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else if (!IS_SPEC_FUNCTION(trap)) {
61569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    throw MakeTypeError("handler_trap_must_be_callable", [handler, name]);
61669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
61769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return trap;
61869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
61969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
62069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
62169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction CallTrap0(handler, name, defaultTrap) {
62269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return %_CallFunction(handler, GetTrap(handler, name, defaultTrap));
62369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
62469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
62569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
62669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction CallTrap1(handler, name, defaultTrap, x) {
62769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return %_CallFunction(handler, x, GetTrap(handler, name, defaultTrap));
62869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
62969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
63069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
63169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction CallTrap2(handler, name, defaultTrap, x, y) {
63269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return %_CallFunction(handler, x, y, GetTrap(handler, name, defaultTrap));
63369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
63469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
63569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
6361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// ES5 section 8.12.1.
63769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction GetOwnProperty(obj, v) {
63869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var p = ToString(v);
6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var handler = %GetHandler(obj);
64169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    var descriptor = CallTrap1(handler, "getOwnPropertyDescriptor", void 0, p);
6423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (IS_UNDEFINED(descriptor)) return descriptor;
6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var desc = ToCompletePropertyDescriptor(descriptor);
6443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (!desc.isConfigurable()) {
6453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      throw MakeTypeError("proxy_prop_not_configurable",
6463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                          [handler, "getOwnPropertyDescriptor", p, descriptor]);
6473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
6483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return desc;
6493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
6503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // GetOwnProperty returns an array indexed by the constants
6521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // defined in macros.py.
6531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // If p is not a property on obj undefined is returned.
65469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var props = %GetOwnProperty(ToObject(obj), ToString(v));
6551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // A false value here means that access checks failed.
65744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (props === false) return void 0;
6581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return ConvertDescriptorArrayToDescriptor(props);
6601e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
6611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ES5 section 8.12.7.
6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction Delete(obj, p, should_throw) {
6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var desc = GetOwnProperty(obj, p);
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (IS_UNDEFINED(desc)) return true;
6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (desc.isConfigurable()) {
6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    %DeleteProperty(obj, p, 0);
6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (should_throw) {
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("define_disallowed", [p]);
6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return;
6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Harmony proxies.
6793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction DefineProxyProperty(obj, p, attributes, should_throw) {
6803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var handler = %GetHandler(obj);
68169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var result = CallTrap2(handler, "defineProperty", void 0, p, attributes);
6823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!ToBoolean(result)) {
6833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (should_throw) {
6843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      throw MakeTypeError("handler_returned_false",
6853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                          [handler, "defineProperty"]);
6863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
6873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      return false;
6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
6893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
6903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return true;
6913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
6923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
6946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// ES5 8.12.9.
6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction DefineObjectProperty(obj, p, desc, should_throw) {
6961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
6971e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // A false value here means that access checks failed.
69844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (current_or_access === false) return void 0;
6991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
7001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var current = ConvertDescriptorArrayToDescriptor(current_or_access);
7013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  var extensible = %IsExtensible(ToObject(obj));
7023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Error handling according to spec.
7043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Step 3
70544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (IS_UNDEFINED(current) && !extensible) {
70644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (should_throw) {
7073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      throw MakeTypeError("define_disallowed", [p]);
70844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    } else {
7093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return false;
71044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
71144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
7123100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (!IS_UNDEFINED(current)) {
71450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    // Step 5 and 6
7151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if ((IsGenericDescriptor(desc) ||
7161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block         IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
7171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        (!desc.hasEnumerable() ||
7181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block         SameValue(desc.isEnumerable(), current.isEnumerable())) &&
719f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch        (!desc.hasConfigurable() ||
72050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         SameValue(desc.isConfigurable(), current.isConfigurable())) &&
721f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch        (!desc.hasWritable() ||
72250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         SameValue(desc.isWritable(), current.isWritable())) &&
72350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen        (!desc.hasValue() ||
72450ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         SameValue(desc.getValue(), current.getValue())) &&
72550ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen        (!desc.hasGetter() ||
72650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         SameValue(desc.getGet(), current.getGet())) &&
72750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen        (!desc.hasSetter() ||
72850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         SameValue(desc.getSet(), current.getSet()))) {
72950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen      return true;
73050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    }
7311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    if (!current.isConfigurable()) {
7321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // Step 7
7331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      if (desc.isConfigurable() ||
7341e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          (desc.hasEnumerable() &&
735e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch           desc.isEnumerable() != current.isEnumerable())) {
73644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        if (should_throw) {
7373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch          throw MakeTypeError("redefine_disallowed", [p]);
73844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        } else {
7393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          return false;
74044f0eee88ff00398ff7f715fab053374d808c90dSteve Block        }
741e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      }
7421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // Step 8
7431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      if (!IsGenericDescriptor(desc)) {
7441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // Step 9a
745e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
74644f0eee88ff00398ff7f715fab053374d808c90dSteve Block          if (should_throw) {
7473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            throw MakeTypeError("redefine_disallowed", [p]);
74844f0eee88ff00398ff7f715fab053374d808c90dSteve Block          } else {
7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            return false;
75044f0eee88ff00398ff7f715fab053374d808c90dSteve Block          }
751e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch        }
7521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // Step 10a
7531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
754e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          if (!current.isWritable() && desc.isWritable()) {
75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block            if (should_throw) {
7563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              throw MakeTypeError("redefine_disallowed", [p]);
75744f0eee88ff00398ff7f715fab053374d808c90dSteve Block            } else {
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              return false;
75944f0eee88ff00398ff7f715fab053374d808c90dSteve Block            }
760e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          }
7611e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          if (!current.isWritable() && desc.hasValue() &&
7621e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block              !SameValue(desc.getValue(), current.getValue())) {
76344f0eee88ff00398ff7f715fab053374d808c90dSteve Block            if (should_throw) {
7643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              throw MakeTypeError("redefine_disallowed", [p]);
76544f0eee88ff00398ff7f715fab053374d808c90dSteve Block            } else {
7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              return false;
76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block            }
7681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          }
7691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        }
7701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // Step 11
7711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
772e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) {
77344f0eee88ff00398ff7f715fab053374d808c90dSteve Block            if (should_throw) {
7743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              throw MakeTypeError("redefine_disallowed", [p]);
77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block            } else {
7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              return false;
77744f0eee88ff00398ff7f715fab053374d808c90dSteve Block            }
7781e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block          }
779e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
78044f0eee88ff00398ff7f715fab053374d808c90dSteve Block            if (should_throw) {
7813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch              throw MakeTypeError("redefine_disallowed", [p]);
78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block            } else {
7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch              return false;
78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block            }
785e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch          }
7861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        }
7873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu      }
7883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    }
7893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
7903100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
7916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Send flags - enumerable and configurable are common - writable is
7923100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // only send to the data descriptor.
7933100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Take special care if enumerable and configurable is not defined on
7943100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // desc (we need to preserve the existing values from current).
7953100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  var flag = NONE;
7963100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (desc.hasEnumerable()) {
7973100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
7983100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  } else if (!IS_UNDEFINED(current)) {
7993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= current.isEnumerable() ? 0 : DONT_ENUM;
8003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  } else {
8013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= DONT_ENUM;
8023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  }
8033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
8043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  if (desc.hasConfigurable()) {
8053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
8063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  } else if (!IS_UNDEFINED(current)) {
8073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= current.isConfigurable() ? 0 : DONT_DELETE;
8083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  } else
8093100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    flag |= DONT_DELETE;
8103100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
8111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (IsDataDescriptor(desc) ||
8121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (IsGenericDescriptor(desc) &&
8131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block       (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
8141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // There are 3 cases that lead here:
8151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Step 4a - defining a new data property.
8161e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Steps 9b & 12 - replacing an existing accessor property with a data
8171e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    //                 property.
8181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Step 12 - updating an existing data property with a data or generic
8191e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    //           descriptor.
8201e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
821f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    if (desc.hasWritable()) {
822f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      flag |= desc.isWritable() ? 0 : READ_ONLY;
823f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    } else if (!IS_UNDEFINED(current)) {
824f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      flag |= current.isWritable() ? 0 : READ_ONLY;
825f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    } else {
826f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke      flag |= READ_ONLY;
827f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    }
8281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var value = void 0;  // Default value is undefined.
830b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    if (desc.hasValue()) {
831b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      value = desc.getValue();
8321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
833b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      value = current.getValue();
834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    }
8351e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    %DefineOrRedefineDataProperty(obj, p, value, flag);
837e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  } else {
8381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // There are 3 cases that lead here:
8391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Step 4b - defining a new accessor property.
8401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Steps 9c & 12 - replacing an existing data property with an accessor
8411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    //                 property.
8421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // Step 12 - updating an existing accessor property with an accessor
8431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    //           descriptor.
8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var getter = desc.hasGetter() ? desc.getGet() : null;
8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var setter = desc.hasSetter() ? desc.getSet() : null;
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    %DefineOrRedefineAccessorProperty(obj, p, getter, setter, flag);
8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return true;
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ES5 section 15.4.5.1.
8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction DefineArrayProperty(obj, p, desc, should_throw) {
8543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Note that the length of an array is not actually stored as part of the
8553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // property, hence we use generated code throughout this function instead of
8563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // DefineObjectProperty() to modify its value.
8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Step 3 - Special handling for length property.
8593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (p == "length") {
8603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var length = obj.length;
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!desc.hasValue()) {
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return DefineObjectProperty(obj, "length", desc, should_throw);
8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var new_length = ToUint32(desc.getValue());
8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (new_length != ToNumber(desc.getValue())) {
8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      throw new $RangeError('defineProperty() array length out of range');
867c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    }
8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var length_desc = GetOwnProperty(obj, "length");
8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (new_length != length && !length_desc.isWritable()) {
8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (should_throw) {
8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        throw MakeTypeError("redefine_disallowed", [p]);
8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
8733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return false;
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var threw = false;
8773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    while (new_length < length--) {
8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (!Delete(obj, ToString(length), false)) {
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        new_length = length + 1;
8803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        threw = true;
8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        break;
8823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
883c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch    }
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Make sure the below call to DefineObjectProperty() doesn't overwrite
8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // any magic "length" property by removing the value.
8863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    obj.length = new_length;
8873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    desc.value_ = void 0;
8883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    desc.hasValue_ = false;
8893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!DefineObjectProperty(obj, "length", desc, should_throw) || threw) {
8903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (should_throw) {
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        throw MakeTypeError("redefine_disallowed", [p]);
8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return false;
8943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
8953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
8963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
8973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
8993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Step 4 - Special handling for array index.
9003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var index = ToUint32(p);
9013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (index == ToNumber(p) && index != 4294967295) {
9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var length = obj.length;
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var length_desc = GetOwnProperty(obj, "length");
9043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if ((index >= length && !length_desc.isWritable()) ||
9053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        !DefineObjectProperty(obj, p, desc, true)) {
9063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (should_throw) {
9073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        throw MakeTypeError("define_disallowed", [p]);
9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      } else {
9093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        return false;
9103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
9113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (index >= length) {
9133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      obj.length = index + 1;
9143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
9153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return true;
9163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Step 5 - Fallback to default implementation.
9193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return DefineObjectProperty(obj, p, desc, should_throw);
9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
9213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
9233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
9243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction DefineOwnProperty(obj, p, desc, should_throw) {
9253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (%IsJSProxy(obj)) {
9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var attributes = FromGenericPropertyDescriptor(desc);
9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineProxyProperty(obj, p, attributes, should_throw);
9283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (IS_ARRAY(obj)) {
9293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineArrayProperty(obj, p, desc, should_throw);
9303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
9313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return DefineObjectProperty(obj, p, desc, should_throw);
932c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch  }
933c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch}
934c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
935c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch
936e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 section 15.2.3.2.
937e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ObjectGetPrototypeOf(obj) {
9383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(obj)) {
9393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.getPrototypeOf"]);
9403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return %GetPrototype(obj);
942e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
943e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
944e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
9456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block// ES5 section 15.2.3.3
946e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ObjectGetOwnPropertyDescriptor(obj, p) {
9473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(obj)) {
9483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object",
9493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        ["Object.getOwnPropertyDescriptor"]);
9503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
951e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var desc = GetOwnProperty(obj, p);
952e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return FromPropertyDescriptor(desc);
953e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
954e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
955e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
9563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// For Harmony proxies
9573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction ToStringArray(obj, trap) {
9583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
9593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]);
9603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
9613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var n = ToUint32(obj.length);
9623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var array = new $Array(n);
9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var names = {};  // TODO(rossberg): use sets once they are ready.
9643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (var index = 0; index < n; index++) {
9653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var s = ToString(obj[index]);
9663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (s in names) {
9673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]);
9683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
9693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    array[index] = s;
9703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    names[s] = 0;
9713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
9723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return array;
9733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
9743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
9753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
976e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 section 15.2.3.4.
977e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ObjectGetOwnPropertyNames(obj) {
9783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(obj)) {
9793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
9803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
9813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Special handling for proxies.
9823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
9833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var handler = %GetHandler(obj);
98469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    var names = CallTrap0(handler, "getOwnPropertyNames", void 0);
9853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return ToStringArray(names, "getOwnPropertyNames");
9863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
9873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
988e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Find all the indexed properties.
989e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
990e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Get the local element names.
991e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var propertyNames = %GetLocalElementNames(obj);
992e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
993e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Get names for indexed interceptor properties.
994e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (%GetInterceptorInfo(obj) & 1) {
995e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var indexedInterceptorNames =
996e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        %GetIndexedInterceptorElementNames(obj);
9973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (indexedInterceptorNames) {
998e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      propertyNames = propertyNames.concat(indexedInterceptorNames);
9993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1000e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
1001e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1002e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Find all the named properties.
1003e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1004e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Get the local property names.
1005e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  propertyNames = propertyNames.concat(%GetLocalPropertyNames(obj));
1006e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1007e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Get names for named interceptor properties if any.
1008e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1009e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (%GetInterceptorInfo(obj) & 2) {
1010e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    var namedInterceptorNames =
1011e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke        %GetNamedInterceptorPropertyNames(obj);
1012e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    if (namedInterceptorNames) {
1013e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke      propertyNames = propertyNames.concat(namedInterceptorNames);
1014e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    }
1015e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
1016e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
10178defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Property names are expected to be unique strings.
10188defd9ff6930b4e24729971a61cf7469daf119beSteve Block  var propertySet = {};
10198defd9ff6930b4e24729971a61cf7469daf119beSteve Block  var j = 0;
10208defd9ff6930b4e24729971a61cf7469daf119beSteve Block  for (var i = 0; i < propertyNames.length; ++i) {
10218defd9ff6930b4e24729971a61cf7469daf119beSteve Block    var name = ToString(propertyNames[i]);
10228defd9ff6930b4e24729971a61cf7469daf119beSteve Block    // We need to check for the exact property value since for intrinsic
10238defd9ff6930b4e24729971a61cf7469daf119beSteve Block    // properties like toString if(propertySet["toString"]) will always
10248defd9ff6930b4e24729971a61cf7469daf119beSteve Block    // succeed.
10253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (propertySet[name] === true) {
10268defd9ff6930b4e24729971a61cf7469daf119beSteve Block      continue;
10273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
10288defd9ff6930b4e24729971a61cf7469daf119beSteve Block    propertySet[name] = true;
10298defd9ff6930b4e24729971a61cf7469daf119beSteve Block    propertyNames[j++] = name;
10308defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
10318defd9ff6930b4e24729971a61cf7469daf119beSteve Block  propertyNames.length = j;
1032402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
1033e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return propertyNames;
1034e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1035e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1036e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1037e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// ES5 section 15.2.3.5.
1038e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ObjectCreate(proto, properties) {
10393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(proto) && proto !== null) {
1040e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    throw MakeTypeError("proto_object_or_null", [proto]);
1041e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
1042e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var obj = new $Object();
1043e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  obj.__proto__ = proto;
1044e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
1045e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  return obj;
1046e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1047e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1048e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
10493100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ES5 section 15.2.3.6.
10503100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescufunction ObjectDefineProperty(obj, p, attributes) {
10513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
10523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]);
1053f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
10543100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  var name = ToString(p);
10553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
10563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // Clone the attributes object for protection.
10573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // TODO(rossberg): not spec'ed yet, so not sure if this should involve
10583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // non-own properties as it does (or non-enumerable ones, as it doesn't?).
1059589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var attributesClone = {};
10603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    for (var a in attributes) {
10613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      attributesClone[a] = attributes[a];
10623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
10633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    DefineProxyProperty(obj, name, attributesClone, true);
10643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // The following would implement the spec as in the current proposal,
10653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // but after recent comments on es-discuss, is most likely obsolete.
10663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    /*
10673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var defineObj = FromGenericPropertyDescriptor(desc);
10683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var names = ObjectGetOwnPropertyNames(attributes);
10693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var standardNames =
10703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      {value: 0, writable: 0, get: 0, set: 0, enumerable: 0, configurable: 0};
10713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    for (var i = 0; i < names.length; i++) {
10723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      var N = names[i];
10733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (!(%HasLocalProperty(standardNames, N))) {
10743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        var attr = GetOwnProperty(attributes, N);
10753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        DefineOwnProperty(descObj, N, attr, true);
10763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      }
10773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
10783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // This is really confusing the types, but it is what the proxies spec
10793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    // currently requires:
10803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    desc = descObj;
10813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    */
10823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
10833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    var desc = ToPropertyDescriptor(attributes);
10843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    DefineOwnProperty(obj, name, desc, true);
10853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
10863100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return obj;
10873100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
10883100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
10893100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
109069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochfunction GetOwnEnumerablePropertyNames(properties) {
109169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var names = new InternalArray();
109269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  for (var key in properties) {
109369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    if (%HasLocalProperty(properties, key)) {
109469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      names.push(key);
109569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    }
109669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
109769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  return names;
109869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
109969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
110069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
11013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu// ES5 section 15.2.3.7.
1102e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkefunction ObjectDefineProperties(obj, properties) {
11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(obj)) {
11043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.defineProperties"]);
11053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  var props = ToObject(properties);
110769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var names = GetOwnEnumerablePropertyNames(props);
11083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var descriptors = new InternalArray();
110969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  for (var i = 0; i < names.length; i++) {
11103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    descriptors.push(ToPropertyDescriptor(props[names[i]]));
11113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
11123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  for (var i = 0; i < names.length; i++) {
11133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    DefineOwnProperty(obj, names[i], descriptors[i], true);
1114e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
11153100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return obj;
1116e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke}
1117e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1118e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
11193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Harmony proxies.
11203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochfunction ProxyFix(obj) {
11213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var handler = %GetHandler(obj);
112269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  var props = CallTrap0(handler, "fix", void 0);
11233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (IS_UNDEFINED(props)) {
11243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    throw MakeTypeError("handler_returned_undefined", [handler, "fix"]);
11253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
1126589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
11273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (%IsJSFunctionProxy(obj)) {
1128589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var callTrap = %GetCallTrap(obj);
1129589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var constructTrap = %GetConstructTrap(obj);
1130589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var code = DelegateCallAndConstruct(callTrap, constructTrap);
1131589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %Fix(obj);  // becomes a regular function
1132589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetCode(obj, code);
11333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(rossberg): What about length and other properties? Not specified.
11343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // We just put in some half-reasonable defaults for now.
11353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var prototype = new $Object();
11363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    $Object.defineProperty(prototype, "constructor",
11373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      {value: obj, writable: true, enumerable: false, configurable: true});
11383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // TODO(v8:1530): defineProperty does not handle prototype and length.
11393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    %FunctionSetPrototype(obj, prototype);
11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    obj.length = 0;
1141589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  } else {
1142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %Fix(obj);
1143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
11443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ObjectDefineProperties(obj, props);
11453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
11463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
11483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// ES5 section 15.2.3.8.
11493bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochfunction ObjectSeal(obj) {
11503bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
11513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.seal"]);
11523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
11533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
11543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ProxyFix(obj);
11553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11563bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  var names = ObjectGetOwnPropertyNames(obj);
115780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (var i = 0; i < names.length; i++) {
115880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    var name = names[i];
11593bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    var desc = GetOwnProperty(obj, name);
11603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (desc.isConfigurable()) {
11613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      desc.setConfigurable(false);
11623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      DefineOwnProperty(obj, name, desc, true);
11633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
1164f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
11653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  %PreventExtensions(obj);
11663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return obj;
11673bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
11683bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
11693bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
11703bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// ES5 section 15.2.3.9.
11713bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochfunction ObjectFreeze(obj) {
11723bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
11733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
11743bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
11763fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ProxyFix(obj);
11773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
11783bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  var names = ObjectGetOwnPropertyNames(obj);
117980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (var i = 0; i < names.length; i++) {
118080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    var name = names[i];
11813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    var desc = GetOwnProperty(obj, name);
11823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (desc.isWritable() || desc.isConfigurable()) {
11833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (IsDataDescriptor(desc)) desc.setWritable(false);
11843fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      desc.setConfigurable(false);
11853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      DefineOwnProperty(obj, name, desc, true);
11863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
1187f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
11883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  %PreventExtensions(obj);
11893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return obj;
11903bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
11913bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
11923bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
11938defd9ff6930b4e24729971a61cf7469daf119beSteve Block// ES5 section 15.2.3.10
11948defd9ff6930b4e24729971a61cf7469daf119beSteve Blockfunction ObjectPreventExtension(obj) {
11953bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.preventExtension"]);
11978defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
11983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
11993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    ProxyFix(obj);
12003fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12018defd9ff6930b4e24729971a61cf7469daf119beSteve Block  %PreventExtensions(obj);
12028defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return obj;
12038defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
12048defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12058defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// ES5 section 15.2.3.11
12073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochfunction ObjectIsSealed(obj) {
12083bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.isSealed"]);
12103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
12123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return false;
12133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  var names = ObjectGetOwnPropertyNames(obj);
121580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (var i = 0; i < names.length; i++) {
121680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    var name = names[i];
12173bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    var desc = GetOwnProperty(obj, name);
12183bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    if (desc.isConfigurable()) return false;
12193bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12203bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!ObjectIsExtensible(obj)) {
12213bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    return true;
12223bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12233bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return false;
12243bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
12253bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
12263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
12273bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch// ES5 section 15.2.3.12
12283bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochfunction ObjectIsFrozen(obj) {
12293bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
12303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]);
12313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
12333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return false;
12343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12353bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  var names = ObjectGetOwnPropertyNames(obj);
123680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  for (var i = 0; i < names.length; i++) {
123780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    var name = names[i];
12383bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    var desc = GetOwnProperty(obj, name);
12393bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    if (IsDataDescriptor(desc) && desc.isWritable()) return false;
12403bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    if (desc.isConfigurable()) return false;
12413bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12423bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!ObjectIsExtensible(obj)) {
12433bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    return true;
12443bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  }
12453bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return false;
12463bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
12473bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
12483bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
12498defd9ff6930b4e24729971a61cf7469daf119beSteve Block// ES5 section 15.2.3.13
12508defd9ff6930b4e24729971a61cf7469daf119beSteve Blockfunction ObjectIsExtensible(obj) {
12513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!IS_SPEC_OBJECT(obj)) {
12523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]);
12533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
12543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (%IsJSProxy(obj)) {
12553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return true;
12568defd9ff6930b4e24729971a61cf7469daf119beSteve Block  }
12578defd9ff6930b4e24729971a61cf7469daf119beSteve Block  return %IsExtensible(obj);
12588defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
12598defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12608defd9ff6930b4e24729971a61cf7469daf119beSteve Block
12613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Harmony egal.
12623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction ObjectIs(obj1, obj2) {
12633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (obj1 === obj2) {
12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (obj1 !== 0) || (1 / obj1 === 1 / obj2);
12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else {
12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return (obj1 !== obj1) && (obj2 !== obj2);
12673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
12683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
12693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
12703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode($Object, function(x) {
1272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsConstructCall()) {
1273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (x == null) return this;
1274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ToObject(x);
1275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (x == null) return { };
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ToObject(x);
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block});
1280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen%SetExpectedNumberOfProperties($Object, 4);
1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1284589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// Object
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1286589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpObject() {
1287589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
1288589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set Up non-enumerable functions on the Object.prototype object.
1289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions($Object.prototype, DONT_ENUM, $Array(
1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toString", ObjectToString,
1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toLocaleString", ObjectToLocaleString,
1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "valueOf", ObjectValueOf,
1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "hasOwnProperty", ObjectHasOwnProperty,
1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "isPrototypeOf", ObjectIsPrototypeOf,
1295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "propertyIsEnumerable", ObjectPropertyIsEnumerable,
1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "__defineGetter__", ObjectDefineGetter,
1297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "__lookupGetter__", ObjectLookupGetter,
1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "__defineSetter__", ObjectDefineSetter,
1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "__lookupSetter__", ObjectLookupSetter
1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
1301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions($Object, DONT_ENUM, $Array(
1302e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    "keys", ObjectKeys,
1303e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    "create", ObjectCreate,
13043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    "defineProperty", ObjectDefineProperty,
13053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    "defineProperties", ObjectDefineProperties,
13063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    "freeze", ObjectFreeze,
1307e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    "getPrototypeOf", ObjectGetPrototypeOf,
1308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
13098defd9ff6930b4e24729971a61cf7469daf119beSteve Block    "getOwnPropertyNames", ObjectGetOwnPropertyNames,
13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    "is", ObjectIs,
13118defd9ff6930b4e24729971a61cf7469daf119beSteve Block    "isExtensible", ObjectIsExtensible,
13123bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    "isFrozen", ObjectIsFrozen,
13133bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    "isSealed", ObjectIsSealed,
13143bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    "preventExtensions", ObjectPreventExtension,
13153bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch    "seal", ObjectSeal
1316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1319589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpObject();
1320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Boolean
1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BooleanToString() {
1325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOTE: Both Boolean objects and values can enter here as
1326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 'this'. This is not as dictated by ECMA-262.
1327086aeeaae12517475c22695a200be45495516549Ben Murdoch  var b = this;
1328086aeeaae12517475c22695a200be45495516549Ben Murdoch  if (!IS_BOOLEAN(b)) {
1329086aeeaae12517475c22695a200be45495516549Ben Murdoch    if (!IS_BOOLEAN_WRAPPER(b)) {
1330086aeeaae12517475c22695a200be45495516549Ben Murdoch      throw new $TypeError('Boolean.prototype.toString is not generic');
1331086aeeaae12517475c22695a200be45495516549Ben Murdoch    }
1332086aeeaae12517475c22695a200be45495516549Ben Murdoch    b = %_ValueOf(b);
1333086aeeaae12517475c22695a200be45495516549Ben Murdoch  }
1334086aeeaae12517475c22695a200be45495516549Ben Murdoch  return b ? 'true' : 'false';
1335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction BooleanValueOf() {
1339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOTE: Both Boolean objects and values can enter here as
1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 'this'. This is not as dictated by ECMA-262.
13413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) {
1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $TypeError('Boolean.prototype.valueOf is not generic');
13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %_ValueOf(this);
1345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1351589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpBoolean () {
1352589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
1354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toString", BooleanToString,
1355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    "valueOf", BooleanValueOf
1356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
1357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpBoolean();
1360589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Number
1364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Set the Number function and constructor.
1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode($Number, function(x) {
1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
1368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (%_IsConstructCall()) {
1369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    %_SetValueOf(this, value);
1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return value;
1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block});
1374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetPrototype($Number, new $Number(0));
1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.2.
1378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberToString(radix) {
1379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOTE: Both Number objects and values can enter here as
1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 'this'. This is not as dictated by ECMA-262.
1381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var number = this;
1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_NUMBER(this)) {
13833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!IS_NUMBER_WRAPPER(this)) {
1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      throw new $TypeError('Number.prototype.toString is not generic');
13853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
1386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Get the value of this number in case it's an object.
1387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    number = %_ValueOf(this);
1388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Fast case: Convert number in radix 10.
1390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_UNDEFINED(radix) || radix === 10) {
1391086aeeaae12517475c22695a200be45495516549Ben Murdoch    return %_NumberToString(number);
1392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert the radix to an integer and check the range.
1395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  radix = TO_INTEGER(radix);
1396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (radix < 2 || radix > 36) {
1397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $RangeError('toString() radix argument must be between 2 and 36');
1398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convert the number to a string in the given radix.
1400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToRadixString(number, radix);
1401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.3
1405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberToLocaleString() {
1406257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1407257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
1408257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Number.prototype.toLocaleString"]);
1409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.toString();
1411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.4
1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberValueOf() {
1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // NOTE: Both Number objects and values can enter here as
1417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // 'this'. This is not as dictated by ECMA-262.
14183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this)) {
1419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $TypeError('Number.prototype.valueOf is not generic');
14203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
1421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %_ValueOf(this);
1422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.5
1426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberToFixed(fractionDigits) {
1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var f = TO_INTEGER(fractionDigits);
1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (f < 0 || f > 20) {
1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $RangeError("toFixed() digits argument must be between 0 and 20");
1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1432257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
1433257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Number.prototype.toFixed"]);
1434257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x = ToNumber(this);
1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToFixed(x, f);
1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.6
1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberToExponential(fractionDigits) {
1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var f = -1;
1443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_UNDEFINED(fractionDigits)) {
1444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    f = TO_INTEGER(fractionDigits);
1445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (f < 0 || f > 20) {
14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      throw new $RangeError(
14473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          "toExponential() argument must be between 0 and 20");
1448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1450257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1451257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
1452257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Number.prototype.toExponential"]);
1453257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x = ToNumber(this);
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToExponential(x, f);
1456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ECMA-262 section 15.7.4.7
1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NumberToPrecision(precision) {
1461257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) {
1462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw MakeTypeError("called_on_null_or_undefined",
1463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                        ["Number.prototype.toPrecision"]);
1464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this));
1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var p = TO_INTEGER(precision);
1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (p < 1 || p > 21) {
1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $RangeError("toPrecision() argument must be between 1 and 21");
1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var x = ToNumber(this);
1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %NumberToPrecision(x, p);
1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
14753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Harmony isFinite.
14763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction NumberIsFinite(number) {
14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return IS_NUMBER(number) && NUMBER_IS_FINITE(number);
14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Harmony isNaN.
14823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction NumberIsNaN(number) {
14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return IS_NUMBER(number) && NUMBER_IS_NAN(number);
14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
14863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1489589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpNumber() {
1490589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
1491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %OptimizeObjectForAddingMultipleProperties($Number.prototype, 8);
1492589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set up the constructor property on the Number prototype object.
1493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
1494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %OptimizeObjectForAddingMultipleProperties($Number, 5);
1496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 section 15.7.3.1.
1497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %SetProperty($Number,
1498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               "MAX_VALUE",
1499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               1.7976931348623157e+308,
1500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               DONT_ENUM | DONT_DELETE | READ_ONLY);
1501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 section 15.7.3.2.
15033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %SetProperty($Number, "MIN_VALUE", 5e-324,
15043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch               DONT_ENUM | DONT_DELETE | READ_ONLY);
1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 section 15.7.3.3.
1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
1508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 section 15.7.3.4.
1510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %SetProperty($Number,
1511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               "NEGATIVE_INFINITY",
1512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               -1/0,
1513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               DONT_ENUM | DONT_DELETE | READ_ONLY);
1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ECMA-262 section 15.7.3.5.
1516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  %SetProperty($Number,
1517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               "POSITIVE_INFINITY",
1518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               1/0,
1519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               DONT_ENUM | DONT_DELETE | READ_ONLY);
1520402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  %ToFastProperties($Number);
1521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1522589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Set up non-enumerable functions on the Number prototype object.
1523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions($Number.prototype, DONT_ENUM, $Array(
1524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toString", NumberToString,
1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toLocaleString", NumberToLocaleString,
1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "valueOf", NumberValueOf,
1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toFixed", NumberToFixed,
1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toExponential", NumberToExponential,
1529b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    "toPrecision", NumberToPrecision
1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
15313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  InstallFunctions($Number, DONT_ENUM, $Array(
15323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    "isFinite", NumberIsFinite,
15333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    "isNaN", NumberIsNaN
15343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ));
1535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpNumber();
1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Function
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block$Function.prototype.constructor = $Function;
1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FunctionSourceString(func) {
1546589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  while (%IsJSFunctionProxy(func)) {
1547589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    func = %GetCallTrap(func);
1548589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
1549589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_FUNCTION(func)) {
1551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    throw new $TypeError('Function.prototype.toString is not generic');
1552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var source = %FunctionGetSourceCode(func);
1555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_STRING(source) || %FunctionIsBuiltin(func)) {
1556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var name = %FunctionGetName(func);
1557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (name) {
1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Mimic what KJS does.
1559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return 'function ' + name + '() { [native code] }';
1560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return 'function () { [native code] }';
1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
15653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  var name = %FunctionNameShouldPrintAsAnonymous(func)
15663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      ? 'anonymous'
15673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      : %FunctionGetName(func);
1568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return 'function ' + name + source;
1569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FunctionToString() {
1573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return FunctionSourceString(this);
1574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen// ES5 15.3.4.5
157850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsenfunction FunctionBind(this_arg) { // Length is 1.
1579589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!IS_SPEC_FUNCTION(this)) {
15803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw new $TypeError('Bind must be called on a function');
15813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
15823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var boundFunction = function () {
15833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Poison .arguments and .caller, but is otherwise not detectable.
15843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    "use strict";
15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // This function must not use any object literals (Object, Array, RegExp),
15863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // since the literals-array is being used to store the bound data.
15873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (%_IsConstructCall()) {
15883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return %NewObjectFromBound(boundFunction);
1589f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    }
15903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var bindings = %BoundFunctionGetBindings(boundFunction);
15911e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
15923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var argc = %_ArgumentsLength();
15933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (argc == 0) {
15943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
15953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
15963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (bindings.length === 2) {
15973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return %Apply(bindings[0], bindings[1], arguments, 0, argc);
15983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
15993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var bound_argc = bindings.length - 2;
16003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var argv = new InternalArray(bound_argc + argc);
16013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var i = 0; i < bound_argc; i++) {
16023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      argv[i] = bindings[i + 2];
16033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
16043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (var j = 0; j < argc; j++) {
16053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      argv[i++] = %_Arguments(j);
16063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
16073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
16083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
16093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
16103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %FunctionRemovePrototype(boundFunction);
16113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var new_length = 0;
16123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (%_ClassOf(this) == "Function") {
16133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Function or FunctionProxy.
16143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var old_length = this.length;
16153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
16163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if ((typeof old_length === "number") &&
16173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        ((old_length >>> 0) === old_length)) {
16181e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      var argc = %_ArgumentsLength();
16193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (argc > 0) argc--;  // Don't count the thisArg as parameter.
16203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      new_length = old_length - argc;
16213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (new_length < 0) new_length = 0;
16223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
162350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  }
16243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // This runtime function finds any remaining arguments on the stack,
16253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // so we don't pass the arguments object.
16263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var result = %FunctionBindArguments(boundFunction, this,
16273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      this_arg, new_length);
162850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
162950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // We already have caller and arguments properties on functions,
163050ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // which are non-configurable. It therefore makes no sence to
163150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // try to redefine these as defined by the spec. The spec says
163250ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // that bind should make these throw a TypeError if get or set
163350ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  // is called and make them non-enumerable and non-configurable.
1634f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // To be consistent with our normal functions we leave this as it is.
16353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // TODO(lrn): Do set these to be thrower.
163650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen  return result;
163750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen}
163850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
163950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen
1640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction NewFunction(arg1) {  // length == 1
1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var n = %_ArgumentsLength();
1642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var p = '';
1643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (n > 1) {
1644e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    p = new InternalArray(n - 1);
1645086aeeaae12517475c22695a200be45495516549Ben Murdoch    for (var i = 0; i < n - 1; i++) p[i] = %_Arguments(i);
1646086aeeaae12517475c22695a200be45495516549Ben Murdoch    p = Join(p, n - 1, ',', NonStringToString);
1647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the formal parameters string include ) - an illegal
1648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // character - it may make the combined function expression
1649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // compile. We avoid this problem by checking for this early on.
1650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
1651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
1653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var source = '(function(' + p + ') {\n' + body + '\n})';
1654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The call to SetNewFunctionAttributes will ensure the prototype
1656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
16573e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  var f = %CompileString(source)();
16583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  %FunctionMarkNameShouldPrintAsAnonymous(f);
1659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return %SetNewFunctionAttributes(f);
1660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode($Function, NewFunction);
1663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
1665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1666589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpFunction() {
1667589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  %CheckIsBootstrapping();
1668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InstallFunctions($Function.prototype, DONT_ENUM, $Array(
166950ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    "bind", FunctionBind,
1670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    "toString", FunctionToString
1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ));
1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1674589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpFunction();
1675