blob: 85540e85df94ebe6b48f8dff1e8ff4804421747f [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// This file relies on the fact that the following declarations have been made
29//
30// in runtime.js:
31// const $Object = global.Object;
32// const $Boolean = global.Boolean;
33// const $Number = global.Number;
34// const $Function = global.Function;
35// const $Array = global.Array;
36// const $NaN = 0/0;
37//
38// in math.js:
39// const $floor = MathFloor
40
41const $isNaN = GlobalIsNaN;
42const $isFinite = GlobalIsFinite;
43
Leon Clarkee46be812010-01-19 14:06:41 +000044
Steve Blocka7e24c12009-10-30 11:49:00 +000045// ----------------------------------------------------------------------------
46
47
48// Helper function used to install functions on objects.
49function InstallFunctions(object, attributes, functions) {
50 if (functions.length >= 8) {
51 %OptimizeObjectForAddingMultipleProperties(object, functions.length >> 1);
52 }
53 for (var i = 0; i < functions.length; i += 2) {
54 var key = functions[i];
55 var f = functions[i + 1];
56 %FunctionSetName(f, key);
Steve Block6ded16b2010-05-10 14:33:55 +010057 %FunctionRemovePrototype(f);
Steve Blocka7e24c12009-10-30 11:49:00 +000058 %SetProperty(object, key, f, attributes);
59 }
Andrei Popescu402d9372010-02-26 13:31:12 +000060 %ToFastProperties(object);
Steve Blocka7e24c12009-10-30 11:49:00 +000061}
62
63// Emulates JSC by installing functions on a hidden prototype that
64// lies above the current object/prototype. This lets you override
65// functions on String.prototype etc. and then restore the old function
66// with delete. See http://code.google.com/p/chromium/issues/detail?id=1717
67function InstallFunctionsOnHiddenPrototype(object, attributes, functions) {
68 var hidden_prototype = new $Object();
69 %SetHiddenPrototype(object, hidden_prototype);
70 InstallFunctions(hidden_prototype, attributes, functions);
71}
72
73
74// ----------------------------------------------------------------------------
75
76
77// ECMA 262 - 15.1.4
78function GlobalIsNaN(number) {
79 var n = ToNumber(number);
80 return NUMBER_IS_NAN(n);
81}
82
83
84// ECMA 262 - 15.1.5
85function GlobalIsFinite(number) {
Steve Block6ded16b2010-05-10 14:33:55 +010086 if (!IS_NUMBER(number)) number = ToNumber(number);
87
88 // NaN - NaN == NaN, Infinity - Infinity == NaN, -Infinity - -Infinity == NaN.
89 return %_IsSmi(number) || number - number == 0;
Steve Blocka7e24c12009-10-30 11:49:00 +000090}
91
92
93// ECMA-262 - 15.1.2.2
94function GlobalParseInt(string, radix) {
Leon Clarkee46be812010-01-19 14:06:41 +000095 if (IS_UNDEFINED(radix)) {
Steve Blocka7e24c12009-10-30 11:49:00 +000096 // Some people use parseInt instead of Math.floor. This
97 // optimization makes parseInt on a Smi 12 times faster (60ns
98 // vs 800ns). The following optimization makes parseInt on a
99 // non-Smi number 9 times faster (230ns vs 2070ns). Together
100 // they make parseInt on a string 1.4% slower (274ns vs 270ns).
101 if (%_IsSmi(string)) return string;
102 if (IS_NUMBER(string) &&
Steve Blockd0582a62009-12-15 09:54:21 +0000103 ((0.01 < string && string < 1e9) ||
104 (-1e9 < string && string < -0.01))) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 // Truncate number.
106 return string | 0;
107 }
108 radix = 0;
109 } else {
110 radix = TO_INT32(radix);
111 if (!(radix == 0 || (2 <= radix && radix <= 36)))
112 return $NaN;
113 }
114 return %StringParseInt(ToString(string), radix);
115}
116
117
118// ECMA-262 - 15.1.2.3
119function GlobalParseFloat(string) {
120 return %StringParseFloat(ToString(string));
121}
122
123
124function GlobalEval(x) {
125 if (!IS_STRING(x)) return x;
126
127 var global_receiver = %GlobalReceiver(global);
128 var this_is_global_receiver = (this === global_receiver);
129 var global_is_detached = (global === global_receiver);
130
131 if (!this_is_global_receiver || global_is_detached) {
132 throw new $EvalError('The "this" object passed to eval must ' +
133 'be the global object from which eval originated');
134 }
135
136 var f = %CompileString(x, false);
137 if (!IS_FUNCTION(f)) return f;
138
139 return f.call(this);
140}
141
142
143// execScript for IE compatibility.
144function GlobalExecScript(expr, lang) {
145 // NOTE: We don't care about the character casing.
146 if (!lang || /javascript/i.test(lang)) {
147 var f = %CompileString(ToString(expr), false);
148 f.call(%GlobalReceiver(global));
149 }
150 return null;
151}
152
153
154// ----------------------------------------------------------------------------
155
156
157function SetupGlobal() {
158 // ECMA 262 - 15.1.1.1.
159 %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
160
161 // ECMA-262 - 15.1.1.2.
162 %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
163
164 // ECMA-262 - 15.1.1.3.
165 %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
166
167 // Setup non-enumerable function on the global object.
168 InstallFunctions(global, DONT_ENUM, $Array(
169 "isNaN", GlobalIsNaN,
170 "isFinite", GlobalIsFinite,
171 "parseInt", GlobalParseInt,
172 "parseFloat", GlobalParseFloat,
173 "eval", GlobalEval,
174 "execScript", GlobalExecScript
175 ));
176}
177
178SetupGlobal();
179
180
181// ----------------------------------------------------------------------------
182// Boolean (first part of definition)
183
184
185%SetCode($Boolean, function(x) {
186 if (%_IsConstructCall()) {
187 %_SetValueOf(this, ToBoolean(x));
188 } else {
189 return ToBoolean(x);
190 }
191});
192
193%FunctionSetPrototype($Boolean, new $Boolean(false));
194
195%SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
196
197// ----------------------------------------------------------------------------
198// Object
199
200$Object.prototype.constructor = $Object;
201
202// ECMA-262 - 15.2.4.2
203function ObjectToString() {
Leon Clarked91b9f72010-01-27 17:25:45 +0000204 return "[object " + %_ClassOf(ToObject(this)) + "]";
Steve Blocka7e24c12009-10-30 11:49:00 +0000205}
206
207
208// ECMA-262 - 15.2.4.3
209function ObjectToLocaleString() {
210 return this.toString();
211}
212
213
214// ECMA-262 - 15.2.4.4
215function ObjectValueOf() {
Leon Clarked91b9f72010-01-27 17:25:45 +0000216 return ToObject(this);
Steve Blocka7e24c12009-10-30 11:49:00 +0000217}
218
219
220// ECMA-262 - 15.2.4.5
221function ObjectHasOwnProperty(V) {
222 return %HasLocalProperty(ToObject(this), ToString(V));
223}
224
225
226// ECMA-262 - 15.2.4.6
227function ObjectIsPrototypeOf(V) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100228 if (!IS_SPEC_OBJECT(V)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +0000229 return %IsInPrototypeChain(this, V);
230}
231
232
233// ECMA-262 - 15.2.4.6
234function ObjectPropertyIsEnumerable(V) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100235 return %IsPropertyEnumerable(ToObject(this), ToString(V));
Steve Blocka7e24c12009-10-30 11:49:00 +0000236}
237
238
239// Extensions for providing property getters and setters.
240function ObjectDefineGetter(name, fun) {
Steve Block6ded16b2010-05-10 14:33:55 +0100241 if (this == null && !IS_UNDETECTABLE(this)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000242 throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
243 }
244 if (!IS_FUNCTION(fun)) {
245 throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
246 }
247 return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun);
248}
249
250
251function ObjectLookupGetter(name) {
Steve Block6ded16b2010-05-10 14:33:55 +0100252 if (this == null && !IS_UNDETECTABLE(this)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000253 throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
254 }
255 return %LookupAccessor(ToObject(this), ToString(name), GETTER);
256}
257
258
259function ObjectDefineSetter(name, fun) {
Steve Block6ded16b2010-05-10 14:33:55 +0100260 if (this == null && !IS_UNDETECTABLE(this)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000261 throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
262 }
263 if (!IS_FUNCTION(fun)) {
264 throw new $TypeError(
265 'Object.prototype.__defineSetter__: Expecting function');
266 }
267 return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun);
268}
269
270
271function ObjectLookupSetter(name) {
Steve Block6ded16b2010-05-10 14:33:55 +0100272 if (this == null && !IS_UNDETECTABLE(this)) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000273 throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
274 }
275 return %LookupAccessor(ToObject(this), ToString(name), SETTER);
276}
277
278
279function ObjectKeys(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100280 if (!IS_SPEC_OBJECT(obj))
Leon Clarkee46be812010-01-19 14:06:41 +0000281 throw MakeTypeError("obj_ctor_property_non_object", ["keys"]);
Steve Blocka7e24c12009-10-30 11:49:00 +0000282 return %LocalKeys(obj);
283}
284
285
Leon Clarkee46be812010-01-19 14:06:41 +0000286// ES5 8.10.1.
287function IsAccessorDescriptor(desc) {
288 if (IS_UNDEFINED(desc)) return false;
289 return desc.hasGetter_ || desc.hasSetter_;
290}
291
292
293// ES5 8.10.2.
294function IsDataDescriptor(desc) {
295 if (IS_UNDEFINED(desc)) return false;
296 return desc.hasValue_ || desc.hasWritable_;
297}
298
299
300// ES5 8.10.3.
301function IsGenericDescriptor(desc) {
302 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
303}
304
305
306function IsInconsistentDescriptor(desc) {
307 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
308}
309
310// ES5 8.10.4
311function FromPropertyDescriptor(desc) {
Andrei Popescu31002712010-02-23 13:46:05 +0000312 if (IS_UNDEFINED(desc)) return desc;
Leon Clarkee46be812010-01-19 14:06:41 +0000313 var obj = new $Object();
314 if (IsDataDescriptor(desc)) {
315 obj.value = desc.getValue();
316 obj.writable = desc.isWritable();
317 }
318 if (IsAccessorDescriptor(desc)) {
319 obj.get = desc.getGet();
320 obj.set = desc.getSet();
321 }
322 obj.enumerable = desc.isEnumerable();
323 obj.configurable = desc.isConfigurable();
324 return obj;
325}
326
327// ES5 8.10.5.
328function ToPropertyDescriptor(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100329 if (!IS_SPEC_OBJECT(obj)) {
Leon Clarkee46be812010-01-19 14:06:41 +0000330 throw MakeTypeError("property_desc_object", [obj]);
331 }
332 var desc = new PropertyDescriptor();
333
334 if ("enumerable" in obj) {
335 desc.setEnumerable(ToBoolean(obj.enumerable));
336 }
337
Leon Clarkee46be812010-01-19 14:06:41 +0000338 if ("configurable" in obj) {
339 desc.setConfigurable(ToBoolean(obj.configurable));
340 }
341
342 if ("value" in obj) {
343 desc.setValue(obj.value);
344 }
345
346 if ("writable" in obj) {
347 desc.setWritable(ToBoolean(obj.writable));
348 }
349
350 if ("get" in obj) {
351 var get = obj.get;
352 if (!IS_UNDEFINED(get) && !IS_FUNCTION(get)) {
353 throw MakeTypeError("getter_must_be_callable", [get]);
354 }
355 desc.setGet(get);
356 }
357
358 if ("set" in obj) {
359 var set = obj.set;
360 if (!IS_UNDEFINED(set) && !IS_FUNCTION(set)) {
361 throw MakeTypeError("setter_must_be_callable", [set]);
362 }
363 desc.setSet(set);
364 }
365
366 if (IsInconsistentDescriptor(desc)) {
367 throw MakeTypeError("value_and_accessor", [obj]);
368 }
369 return desc;
370}
371
372
373function PropertyDescriptor() {
374 // Initialize here so they are all in-object and have the same map.
375 // Default values from ES5 8.6.1.
376 this.value_ = void 0;
377 this.hasValue_ = false;
378 this.writable_ = false;
379 this.hasWritable_ = false;
380 this.enumerable_ = false;
Andrei Popescu31002712010-02-23 13:46:05 +0000381 this.hasEnumerable_ = false;
Leon Clarkee46be812010-01-19 14:06:41 +0000382 this.configurable_ = false;
Andrei Popescu31002712010-02-23 13:46:05 +0000383 this.hasConfigurable_ = false;
Leon Clarkee46be812010-01-19 14:06:41 +0000384 this.get_ = void 0;
385 this.hasGetter_ = false;
386 this.set_ = void 0;
387 this.hasSetter_ = false;
388}
389
390
391PropertyDescriptor.prototype.setValue = function(value) {
392 this.value_ = value;
393 this.hasValue_ = true;
394}
395
396
397PropertyDescriptor.prototype.getValue = function() {
398 return this.value_;
399}
400
401
Andrei Popescu31002712010-02-23 13:46:05 +0000402PropertyDescriptor.prototype.hasValue = function() {
403 return this.hasValue_;
404}
405
406
Leon Clarkee46be812010-01-19 14:06:41 +0000407PropertyDescriptor.prototype.setEnumerable = function(enumerable) {
408 this.enumerable_ = enumerable;
Andrei Popescu31002712010-02-23 13:46:05 +0000409 this.hasEnumerable_ = true;
Leon Clarkee46be812010-01-19 14:06:41 +0000410}
411
412
413PropertyDescriptor.prototype.isEnumerable = function () {
414 return this.enumerable_;
415}
416
417
Andrei Popescu31002712010-02-23 13:46:05 +0000418PropertyDescriptor.prototype.hasEnumerable = function() {
419 return this.hasEnumerable_;
420}
421
422
Leon Clarkee46be812010-01-19 14:06:41 +0000423PropertyDescriptor.prototype.setWritable = function(writable) {
424 this.writable_ = writable;
425 this.hasWritable_ = true;
426}
427
428
429PropertyDescriptor.prototype.isWritable = function() {
430 return this.writable_;
431}
432
433
Leon Clarkef7060e22010-06-03 12:02:55 +0100434PropertyDescriptor.prototype.hasWritable = function() {
435 return this.hasWritable_;
436}
437
438
Leon Clarkee46be812010-01-19 14:06:41 +0000439PropertyDescriptor.prototype.setConfigurable = function(configurable) {
440 this.configurable_ = configurable;
Andrei Popescu31002712010-02-23 13:46:05 +0000441 this.hasConfigurable_ = true;
442}
443
444
445PropertyDescriptor.prototype.hasConfigurable = function() {
446 return this.hasConfigurable_;
Leon Clarkee46be812010-01-19 14:06:41 +0000447}
448
449
450PropertyDescriptor.prototype.isConfigurable = function() {
451 return this.configurable_;
452}
453
454
455PropertyDescriptor.prototype.setGet = function(get) {
456 this.get_ = get;
457 this.hasGetter_ = true;
458}
459
460
461PropertyDescriptor.prototype.getGet = function() {
462 return this.get_;
463}
464
465
Andrei Popescu31002712010-02-23 13:46:05 +0000466PropertyDescriptor.prototype.hasGetter = function() {
467 return this.hasGetter_;
468}
469
470
Leon Clarkee46be812010-01-19 14:06:41 +0000471PropertyDescriptor.prototype.setSet = function(set) {
472 this.set_ = set;
473 this.hasSetter_ = true;
474}
475
476
477PropertyDescriptor.prototype.getSet = function() {
478 return this.set_;
479}
480
481
Andrei Popescu31002712010-02-23 13:46:05 +0000482PropertyDescriptor.prototype.hasSetter = function() {
483 return this.hasSetter_;
484}
485
486
487
Leon Clarkee46be812010-01-19 14:06:41 +0000488// ES5 section 8.12.1.
489function GetOwnProperty(obj, p) {
490 var desc = new PropertyDescriptor();
Steve Block6ded16b2010-05-10 14:33:55 +0100491
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100492 // GetOwnProperty returns an array indexed by the constants
493 // defined in macros.py.
494 // If p is not a property on obj undefined is returned.
Leon Clarkee46be812010-01-19 14:06:41 +0000495 var props = %GetOwnProperty(ToObject(obj), ToString(p));
496
Andrei Popescu31002712010-02-23 13:46:05 +0000497 if (IS_UNDEFINED(props)) return void 0;
Leon Clarkee46be812010-01-19 14:06:41 +0000498
499 // This is an accessor
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100500 if (props[IS_ACCESSOR_INDEX]) {
501 desc.setGet(props[GETTER_INDEX]);
502 desc.setSet(props[SETTER_INDEX]);
Leon Clarkee46be812010-01-19 14:06:41 +0000503 } else {
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100504 desc.setValue(props[VALUE_INDEX]);
505 desc.setWritable(props[WRITABLE_INDEX]);
Leon Clarkee46be812010-01-19 14:06:41 +0000506 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +0100507 desc.setEnumerable(props[ENUMERABLE_INDEX]);
508 desc.setConfigurable(props[CONFIGURABLE_INDEX]);
Leon Clarkee46be812010-01-19 14:06:41 +0000509
510 return desc;
511}
512
513
Andrei Popescu31002712010-02-23 13:46:05 +0000514// ES5 section 8.12.2.
515function GetProperty(obj, p) {
516 var prop = GetOwnProperty(obj);
517 if (!IS_UNDEFINED(prop)) return prop;
518 var proto = obj.__proto__;
519 if (IS_NULL(proto)) return void 0;
520 return GetProperty(proto, p);
521}
522
523
524// ES5 section 8.12.6
525function HasProperty(obj, p) {
526 var desc = GetProperty(obj, p);
527 return IS_UNDEFINED(desc) ? false : true;
528}
529
530
Steve Block6ded16b2010-05-10 14:33:55 +0100531// ES5 8.12.9.
Leon Clarkee46be812010-01-19 14:06:41 +0000532function DefineOwnProperty(obj, p, desc, should_throw) {
Andrei Popescu31002712010-02-23 13:46:05 +0000533 var current = GetOwnProperty(obj, p);
534 var extensible = %IsExtensible(ToObject(obj));
535
536 // Error handling according to spec.
537 // Step 3
538 if (IS_UNDEFINED(current) && !extensible)
539 throw MakeTypeError("define_disallowed", ["defineProperty"]);
540
541 if (!IS_UNDEFINED(current) && !current.isConfigurable()) {
Kristian Monsen50ef84f2010-07-29 15:18:00 +0100542 // Step 5 and 6
543 if ((!desc.hasEnumerable() ||
544 SameValue(desc.isEnumerable() && current.isEnumerable())) &&
545 (!desc.hasConfigurable() ||
546 SameValue(desc.isConfigurable(), current.isConfigurable())) &&
547 (!desc.hasWritable() ||
548 SameValue(desc.isWritable(), current.isWritable())) &&
549 (!desc.hasValue() ||
550 SameValue(desc.getValue(), current.getValue())) &&
551 (!desc.hasGetter() ||
552 SameValue(desc.getGet(), current.getGet())) &&
553 (!desc.hasSetter() ||
554 SameValue(desc.getSet(), current.getSet()))) {
555 return true;
556 }
Leon Clarkef7060e22010-06-03 12:02:55 +0100557
Andrei Popescu31002712010-02-23 13:46:05 +0000558 // Step 7
559 if (desc.isConfigurable() || desc.isEnumerable() != current.isEnumerable())
560 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
561 // Step 9
562 if (IsDataDescriptor(current) != IsDataDescriptor(desc))
563 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
564 // Step 10
565 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
566 if (!current.isWritable() && desc.isWritable())
567 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
568 if (!current.isWritable() && desc.hasValue() &&
569 !SameValue(desc.getValue(), current.getValue())) {
570 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
571 }
572 }
573 // Step 11
574 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
575 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){
576 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
577 }
578 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet()))
579 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
580 }
581 }
582
Steve Block6ded16b2010-05-10 14:33:55 +0100583 // Send flags - enumerable and configurable are common - writable is
Andrei Popescu31002712010-02-23 13:46:05 +0000584 // only send to the data descriptor.
585 // Take special care if enumerable and configurable is not defined on
586 // desc (we need to preserve the existing values from current).
587 var flag = NONE;
588 if (desc.hasEnumerable()) {
589 flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
590 } else if (!IS_UNDEFINED(current)) {
591 flag |= current.isEnumerable() ? 0 : DONT_ENUM;
Leon Clarkee46be812010-01-19 14:06:41 +0000592 } else {
Andrei Popescu31002712010-02-23 13:46:05 +0000593 flag |= DONT_ENUM;
594 }
595
596 if (desc.hasConfigurable()) {
597 flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
598 } else if (!IS_UNDEFINED(current)) {
599 flag |= current.isConfigurable() ? 0 : DONT_DELETE;
600 } else
601 flag |= DONT_DELETE;
602
603 if (IsDataDescriptor(desc) || IsGenericDescriptor(desc)) {
Leon Clarkef7060e22010-06-03 12:02:55 +0100604 if (desc.hasWritable()) {
605 flag |= desc.isWritable() ? 0 : READ_ONLY;
606 } else if (!IS_UNDEFINED(current)) {
607 flag |= current.isWritable() ? 0 : READ_ONLY;
608 } else {
609 flag |= READ_ONLY;
610 }
Andrei Popescu31002712010-02-23 13:46:05 +0000611 %DefineOrRedefineDataProperty(obj, p, desc.getValue(), flag);
612 } else {
613 if (desc.hasGetter() && IS_FUNCTION(desc.getGet())) {
614 %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
615 }
616 if (desc.hasSetter() && IS_FUNCTION(desc.getSet())) {
617 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
618 }
Leon Clarkee46be812010-01-19 14:06:41 +0000619 }
620 return true;
621}
622
623
624// ES5 section 15.2.3.2.
625function ObjectGetPrototypeOf(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100626 if (!IS_SPEC_OBJECT(obj))
Leon Clarkee46be812010-01-19 14:06:41 +0000627 throw MakeTypeError("obj_ctor_property_non_object", ["getPrototypeOf"]);
628 return obj.__proto__;
629}
630
631
Steve Block6ded16b2010-05-10 14:33:55 +0100632// ES5 section 15.2.3.3
Leon Clarkee46be812010-01-19 14:06:41 +0000633function ObjectGetOwnPropertyDescriptor(obj, p) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100634 if (!IS_SPEC_OBJECT(obj))
Leon Clarkee46be812010-01-19 14:06:41 +0000635 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyDescriptor"]);
636 var desc = GetOwnProperty(obj, p);
637 return FromPropertyDescriptor(desc);
638}
639
640
641// ES5 section 15.2.3.4.
642function ObjectGetOwnPropertyNames(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100643 if (!IS_SPEC_OBJECT(obj))
Leon Clarkee46be812010-01-19 14:06:41 +0000644 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]);
645
646 // Find all the indexed properties.
647
648 // Get the local element names.
649 var propertyNames = %GetLocalElementNames(obj);
650
651 // Get names for indexed interceptor properties.
652 if (%GetInterceptorInfo(obj) & 1) {
653 var indexedInterceptorNames =
654 %GetIndexedInterceptorElementNames(obj);
Andrei Popescu402d9372010-02-26 13:31:12 +0000655 if (indexedInterceptorNames)
Leon Clarkee46be812010-01-19 14:06:41 +0000656 propertyNames = propertyNames.concat(indexedInterceptorNames);
Leon Clarkee46be812010-01-19 14:06:41 +0000657 }
658
659 // Find all the named properties.
660
661 // Get the local property names.
662 propertyNames = propertyNames.concat(%GetLocalPropertyNames(obj));
663
664 // Get names for named interceptor properties if any.
665
666 if (%GetInterceptorInfo(obj) & 2) {
667 var namedInterceptorNames =
668 %GetNamedInterceptorPropertyNames(obj);
669 if (namedInterceptorNames) {
670 propertyNames = propertyNames.concat(namedInterceptorNames);
671 }
672 }
673
Steve Block8defd9f2010-07-08 12:39:36 +0100674 // Property names are expected to be unique strings.
675 var propertySet = {};
676 var j = 0;
677 for (var i = 0; i < propertyNames.length; ++i) {
678 var name = ToString(propertyNames[i]);
679 // We need to check for the exact property value since for intrinsic
680 // properties like toString if(propertySet["toString"]) will always
681 // succeed.
682 if (propertySet[name] === true)
683 continue;
684 propertySet[name] = true;
685 propertyNames[j++] = name;
686 }
687 propertyNames.length = j;
Andrei Popescu402d9372010-02-26 13:31:12 +0000688
Leon Clarkee46be812010-01-19 14:06:41 +0000689 return propertyNames;
690}
691
692
693// ES5 section 15.2.3.5.
694function ObjectCreate(proto, properties) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100695 if (!IS_SPEC_OBJECT(proto) && proto !== null) {
Leon Clarkee46be812010-01-19 14:06:41 +0000696 throw MakeTypeError("proto_object_or_null", [proto]);
697 }
698 var obj = new $Object();
699 obj.__proto__ = proto;
700 if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
701 return obj;
702}
703
704
Andrei Popescu31002712010-02-23 13:46:05 +0000705// ES5 section 15.2.3.6.
706function ObjectDefineProperty(obj, p, attributes) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100707 if (!IS_SPEC_OBJECT(obj)) {
Andrei Popescu31002712010-02-23 13:46:05 +0000708 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]);
Leon Clarkef7060e22010-06-03 12:02:55 +0100709 }
Andrei Popescu31002712010-02-23 13:46:05 +0000710 var name = ToString(p);
711 var desc = ToPropertyDescriptor(attributes);
712 DefineOwnProperty(obj, name, desc, true);
713 return obj;
714}
715
716
717// ES5 section 15.2.3.7.
Leon Clarkee46be812010-01-19 14:06:41 +0000718function ObjectDefineProperties(obj, properties) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100719 if (!IS_SPEC_OBJECT(obj))
Andrei Popescu31002712010-02-23 13:46:05 +0000720 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]);
Leon Clarkee46be812010-01-19 14:06:41 +0000721 var props = ToObject(properties);
722 var key_values = [];
723 for (var key in props) {
724 if (%HasLocalProperty(props, key)) {
725 key_values.push(key);
726 var value = props[key];
727 var desc = ToPropertyDescriptor(value);
728 key_values.push(desc);
729 }
730 }
731 for (var i = 0; i < key_values.length; i += 2) {
732 var key = key_values[i];
733 var desc = key_values[i + 1];
734 DefineOwnProperty(obj, key, desc, true);
735 }
Andrei Popescu31002712010-02-23 13:46:05 +0000736 return obj;
Leon Clarkee46be812010-01-19 14:06:41 +0000737}
738
739
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100740// ES5 section 15.2.3.8.
741function ObjectSeal(obj) {
742 if (!IS_SPEC_OBJECT(obj)) {
743 throw MakeTypeError("obj_ctor_property_non_object", ["seal"]);
744 }
745 var names = ObjectGetOwnPropertyNames(obj);
746 for (var key in names) {
747 var name = names[key];
748 var desc = GetOwnProperty(obj, name);
749 if (desc.isConfigurable()) desc.setConfigurable(false);
750 DefineOwnProperty(obj, name, desc, true);
751 }
Ben Murdochbb769b22010-08-11 14:56:33 +0100752 return ObjectPreventExtension(obj);
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100753}
754
755
756// ES5 section 15.2.3.9.
757function ObjectFreeze(obj) {
758 if (!IS_SPEC_OBJECT(obj)) {
759 throw MakeTypeError("obj_ctor_property_non_object", ["freeze"]);
760 }
761 var names = ObjectGetOwnPropertyNames(obj);
762 for (var key in names) {
763 var name = names[key];
764 var desc = GetOwnProperty(obj, name);
765 if (IsDataDescriptor(desc)) desc.setWritable(false);
766 if (desc.isConfigurable()) desc.setConfigurable(false);
767 DefineOwnProperty(obj, name, desc, true);
768 }
Ben Murdochbb769b22010-08-11 14:56:33 +0100769 return ObjectPreventExtension(obj);
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100770}
771
772
Steve Block8defd9f2010-07-08 12:39:36 +0100773// ES5 section 15.2.3.10
774function ObjectPreventExtension(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100775 if (!IS_SPEC_OBJECT(obj)) {
Steve Block8defd9f2010-07-08 12:39:36 +0100776 throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
777 }
778 %PreventExtensions(obj);
779 return obj;
780}
781
782
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100783// ES5 section 15.2.3.11
784function ObjectIsSealed(obj) {
785 if (!IS_SPEC_OBJECT(obj)) {
786 throw MakeTypeError("obj_ctor_property_non_object", ["isSealed"]);
787 }
788 var names = ObjectGetOwnPropertyNames(obj);
789 for (var key in names) {
790 var name = names[key];
791 var desc = GetOwnProperty(obj, name);
792 if (desc.isConfigurable()) return false;
793 }
794 if (!ObjectIsExtensible(obj)) {
795 return true;
796 }
797 return false;
798}
799
800
801// ES5 section 15.2.3.12
802function ObjectIsFrozen(obj) {
803 if (!IS_SPEC_OBJECT(obj)) {
804 throw MakeTypeError("obj_ctor_property_non_object", ["isFrozen"]);
805 }
806 var names = ObjectGetOwnPropertyNames(obj);
807 for (var key in names) {
808 var name = names[key];
809 var desc = GetOwnProperty(obj, name);
810 if (IsDataDescriptor(desc) && desc.isWritable()) return false;
811 if (desc.isConfigurable()) return false;
812 }
813 if (!ObjectIsExtensible(obj)) {
814 return true;
815 }
816 return false;
817}
818
819
Steve Block8defd9f2010-07-08 12:39:36 +0100820// ES5 section 15.2.3.13
821function ObjectIsExtensible(obj) {
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100822 if (!IS_SPEC_OBJECT(obj)) {
Steve Block8defd9f2010-07-08 12:39:36 +0100823 throw MakeTypeError("obj_ctor_property_non_object", ["preventExtension"]);
824 }
825 return %IsExtensible(obj);
826}
827
828
Steve Blocka7e24c12009-10-30 11:49:00 +0000829%SetCode($Object, function(x) {
830 if (%_IsConstructCall()) {
831 if (x == null) return this;
832 return ToObject(x);
833 } else {
834 if (x == null) return { };
835 return ToObject(x);
836 }
837});
838
839
840// ----------------------------------------------------------------------------
841
842
843function SetupObject() {
844 // Setup non-enumerable functions on the Object.prototype object.
845 InstallFunctions($Object.prototype, DONT_ENUM, $Array(
846 "toString", ObjectToString,
847 "toLocaleString", ObjectToLocaleString,
848 "valueOf", ObjectValueOf,
849 "hasOwnProperty", ObjectHasOwnProperty,
850 "isPrototypeOf", ObjectIsPrototypeOf,
851 "propertyIsEnumerable", ObjectPropertyIsEnumerable,
852 "__defineGetter__", ObjectDefineGetter,
853 "__lookupGetter__", ObjectLookupGetter,
854 "__defineSetter__", ObjectDefineSetter,
855 "__lookupSetter__", ObjectLookupSetter
856 ));
857 InstallFunctions($Object, DONT_ENUM, $Array(
Leon Clarkee46be812010-01-19 14:06:41 +0000858 "keys", ObjectKeys,
859 "create", ObjectCreate,
Andrei Popescu31002712010-02-23 13:46:05 +0000860 "defineProperty", ObjectDefineProperty,
861 "defineProperties", ObjectDefineProperties,
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100862 "freeze", ObjectFreeze,
Leon Clarkee46be812010-01-19 14:06:41 +0000863 "getPrototypeOf", ObjectGetPrototypeOf,
864 "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor,
Steve Block8defd9f2010-07-08 12:39:36 +0100865 "getOwnPropertyNames", ObjectGetOwnPropertyNames,
866 "isExtensible", ObjectIsExtensible,
Ben Murdoch3bec4d22010-07-22 14:51:16 +0100867 "isFrozen", ObjectIsFrozen,
868 "isSealed", ObjectIsSealed,
869 "preventExtensions", ObjectPreventExtension,
870 "seal", ObjectSeal
Steve Blocka7e24c12009-10-30 11:49:00 +0000871 ));
872}
873
874SetupObject();
875
876
877// ----------------------------------------------------------------------------
878// Boolean
879
880function BooleanToString() {
881 // NOTE: Both Boolean objects and values can enter here as
882 // 'this'. This is not as dictated by ECMA-262.
883 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this))
884 throw new $TypeError('Boolean.prototype.toString is not generic');
885 return ToString(%_ValueOf(this));
886}
887
888
889function BooleanValueOf() {
890 // NOTE: Both Boolean objects and values can enter here as
891 // 'this'. This is not as dictated by ECMA-262.
892 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this))
893 throw new $TypeError('Boolean.prototype.valueOf is not generic');
894 return %_ValueOf(this);
895}
896
897
898function BooleanToJSON(key) {
899 return CheckJSONPrimitive(this.valueOf());
900}
901
902
903// ----------------------------------------------------------------------------
904
905
906function SetupBoolean() {
907 InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
908 "toString", BooleanToString,
909 "valueOf", BooleanValueOf,
910 "toJSON", BooleanToJSON
911 ));
912}
913
914SetupBoolean();
915
916// ----------------------------------------------------------------------------
917// Number
918
919// Set the Number function and constructor.
920%SetCode($Number, function(x) {
921 var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
922 if (%_IsConstructCall()) {
923 %_SetValueOf(this, value);
924 } else {
925 return value;
926 }
927});
928
929%FunctionSetPrototype($Number, new $Number(0));
930
931// ECMA-262 section 15.7.4.2.
932function NumberToString(radix) {
933 // NOTE: Both Number objects and values can enter here as
934 // 'this'. This is not as dictated by ECMA-262.
935 var number = this;
936 if (!IS_NUMBER(this)) {
937 if (!IS_NUMBER_WRAPPER(this))
938 throw new $TypeError('Number.prototype.toString is not generic');
939 // Get the value of this number in case it's an object.
940 number = %_ValueOf(this);
941 }
942 // Fast case: Convert number in radix 10.
943 if (IS_UNDEFINED(radix) || radix === 10) {
944 return ToString(number);
945 }
946
947 // Convert the radix to an integer and check the range.
948 radix = TO_INTEGER(radix);
949 if (radix < 2 || radix > 36) {
950 throw new $RangeError('toString() radix argument must be between 2 and 36');
951 }
952 // Convert the number to a string in the given radix.
953 return %NumberToRadixString(number, radix);
954}
955
956
957// ECMA-262 section 15.7.4.3
958function NumberToLocaleString() {
959 return this.toString();
960}
961
962
963// ECMA-262 section 15.7.4.4
964function NumberValueOf() {
965 // NOTE: Both Number objects and values can enter here as
966 // 'this'. This is not as dictated by ECMA-262.
967 if (!IS_NUMBER(this) && !IS_NUMBER_WRAPPER(this))
968 throw new $TypeError('Number.prototype.valueOf is not generic');
969 return %_ValueOf(this);
970}
971
972
973// ECMA-262 section 15.7.4.5
974function NumberToFixed(fractionDigits) {
975 var f = TO_INTEGER(fractionDigits);
976 if (f < 0 || f > 20) {
977 throw new $RangeError("toFixed() digits argument must be between 0 and 20");
978 }
979 var x = ToNumber(this);
980 return %NumberToFixed(x, f);
981}
982
983
984// ECMA-262 section 15.7.4.6
985function NumberToExponential(fractionDigits) {
986 var f = -1;
987 if (!IS_UNDEFINED(fractionDigits)) {
988 f = TO_INTEGER(fractionDigits);
989 if (f < 0 || f > 20) {
990 throw new $RangeError("toExponential() argument must be between 0 and 20");
991 }
992 }
993 var x = ToNumber(this);
994 return %NumberToExponential(x, f);
995}
996
997
998// ECMA-262 section 15.7.4.7
999function NumberToPrecision(precision) {
1000 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this));
1001 var p = TO_INTEGER(precision);
1002 if (p < 1 || p > 21) {
1003 throw new $RangeError("toPrecision() argument must be between 1 and 21");
1004 }
1005 var x = ToNumber(this);
1006 return %NumberToPrecision(x, p);
1007}
1008
1009
1010function CheckJSONPrimitive(val) {
1011 if (!IsPrimitive(val))
1012 throw MakeTypeError('result_not_primitive', ['toJSON', val]);
1013 return val;
1014}
1015
1016
1017function NumberToJSON(key) {
1018 return CheckJSONPrimitive(this.valueOf());
1019}
1020
1021
1022// ----------------------------------------------------------------------------
1023
1024function SetupNumber() {
1025 %OptimizeObjectForAddingMultipleProperties($Number.prototype, 8);
1026 // Setup the constructor property on the Number prototype object.
1027 %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
1028
1029 %OptimizeObjectForAddingMultipleProperties($Number, 5);
1030 // ECMA-262 section 15.7.3.1.
1031 %SetProperty($Number,
1032 "MAX_VALUE",
1033 1.7976931348623157e+308,
1034 DONT_ENUM | DONT_DELETE | READ_ONLY);
1035
1036 // ECMA-262 section 15.7.3.2.
1037 %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
1038
1039 // ECMA-262 section 15.7.3.3.
1040 %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
1041
1042 // ECMA-262 section 15.7.3.4.
1043 %SetProperty($Number,
1044 "NEGATIVE_INFINITY",
1045 -1/0,
1046 DONT_ENUM | DONT_DELETE | READ_ONLY);
1047
1048 // ECMA-262 section 15.7.3.5.
1049 %SetProperty($Number,
1050 "POSITIVE_INFINITY",
1051 1/0,
1052 DONT_ENUM | DONT_DELETE | READ_ONLY);
Andrei Popescu402d9372010-02-26 13:31:12 +00001053 %ToFastProperties($Number);
Steve Blocka7e24c12009-10-30 11:49:00 +00001054
1055 // Setup non-enumerable functions on the Number prototype object.
1056 InstallFunctions($Number.prototype, DONT_ENUM, $Array(
1057 "toString", NumberToString,
1058 "toLocaleString", NumberToLocaleString,
1059 "valueOf", NumberValueOf,
1060 "toFixed", NumberToFixed,
1061 "toExponential", NumberToExponential,
1062 "toPrecision", NumberToPrecision,
1063 "toJSON", NumberToJSON
1064 ));
1065}
1066
1067SetupNumber();
1068
1069
1070
1071// ----------------------------------------------------------------------------
1072// Function
1073
1074$Function.prototype.constructor = $Function;
1075
1076function FunctionSourceString(func) {
1077 if (!IS_FUNCTION(func)) {
1078 throw new $TypeError('Function.prototype.toString is not generic');
1079 }
1080
1081 var source = %FunctionGetSourceCode(func);
1082 if (!IS_STRING(source) || %FunctionIsBuiltin(func)) {
1083 var name = %FunctionGetName(func);
1084 if (name) {
1085 // Mimic what KJS does.
1086 return 'function ' + name + '() { [native code] }';
1087 } else {
1088 return 'function () { [native code] }';
1089 }
1090 }
1091
1092 var name = %FunctionGetName(func);
1093 return 'function ' + name + source;
1094}
1095
1096
1097function FunctionToString() {
1098 return FunctionSourceString(this);
1099}
1100
1101
Kristian Monsen50ef84f2010-07-29 15:18:00 +01001102// ES5 15.3.4.5
1103function FunctionBind(this_arg) { // Length is 1.
1104 if (!IS_FUNCTION(this)) {
1105 throw new $TypeError('Bind must be called on a function');
1106 }
1107 // this_arg is not an argument that should be bound.
Ben Murdochbb769b22010-08-11 14:56:33 +01001108 var argc_bound = (%_ArgumentsLength() || 1) - 1;
Kristian Monsen50ef84f2010-07-29 15:18:00 +01001109 if (argc_bound > 0) {
1110 var bound_args = new $Array(argc_bound);
1111 for(var i = 0; i < argc_bound; i++) {
1112 bound_args[i] = %_Arguments(i+1);
1113 }
1114 }
1115 var fn = this;
1116 var result = function() {
1117 // Combine the args we got from the bind call with the args
1118 // given as argument to the invocation.
1119 var argc = %_ArgumentsLength();
1120 var args = new $Array(argc + argc_bound);
1121 // Add bound arguments.
1122 for (var i = 0; i < argc_bound; i++) {
1123 args[i] = bound_args[i];
1124 }
1125 // Add arguments from call.
1126 for (var i = 0; i < argc; i++) {
1127 args[argc_bound + i] = %_Arguments(i);
1128 }
1129 // If this is a construct call we use a special runtime method
1130 // to generate the actual object using the bound function.
1131 if (%_IsConstructCall()) {
1132 return %NewObjectFromBound(fn, args);
1133 }
1134 return fn.apply(this_arg, args);
1135 };
1136
1137 // We already have caller and arguments properties on functions,
1138 // which are non-configurable. It therefore makes no sence to
1139 // try to redefine these as defined by the spec. The spec says
1140 // that bind should make these throw a TypeError if get or set
1141 // is called and make them non-enumerable and non-configurable.
1142 // To be consistent with our normal functions we leave this as it is.
1143
1144 // Set the correct length.
1145 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
1146 %FunctionSetLength(result, length);
1147
1148 return result;
1149}
1150
1151
Steve Blocka7e24c12009-10-30 11:49:00 +00001152function NewFunction(arg1) { // length == 1
1153 var n = %_ArgumentsLength();
1154 var p = '';
1155 if (n > 1) {
1156 p = new $Array(n - 1);
1157 // Explicitly convert all parameters to strings.
1158 // Array.prototype.join replaces null with empty strings which is
1159 // not appropriate.
1160 for (var i = 0; i < n - 1; i++) p[i] = ToString(%_Arguments(i));
1161 p = p.join(',');
1162 // If the formal parameters string include ) - an illegal
1163 // character - it may make the combined function expression
1164 // compile. We avoid this problem by checking for this early on.
1165 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
1166 }
1167 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
1168 var source = '(function(' + p + ') {\n' + body + '\n})';
1169
1170 // The call to SetNewFunctionAttributes will ensure the prototype
1171 // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
1172 var f = %CompileString(source, false)();
1173 %FunctionSetName(f, "anonymous");
1174 return %SetNewFunctionAttributes(f);
1175}
1176
1177%SetCode($Function, NewFunction);
1178
1179// ----------------------------------------------------------------------------
1180
1181function SetupFunction() {
1182 InstallFunctions($Function.prototype, DONT_ENUM, $Array(
Kristian Monsen50ef84f2010-07-29 15:18:00 +01001183 "bind", FunctionBind,
Steve Blocka7e24c12009-10-30 11:49:00 +00001184 "toString", FunctionToString
1185 ));
1186}
1187
1188SetupFunction();