blob: 9772e2f0c28d27bd433dffa03c2a663ed4ea4f09 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000028// This file relies on the fact that the following declarations have been made
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000029//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000030// 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;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +000036// const $NaN = 0/0;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000037//
38// in math.js:
39// const $floor = MathFloor
40
41const $isNaN = GlobalIsNaN;
42const $isFinite = GlobalIsFinite;
43
44// ----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000047// Helper function used to install functions on objects.
48function InstallFunctions(object, attributes, functions) {
49 for (var i = 0; i < functions.length; i += 2) {
50 var key = functions[i];
51 var f = functions[i + 1];
52 %FunctionSetName(f, key);
53 %SetProperty(object, key, f, attributes);
54 }
55}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056
57
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000058// ----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000059
60
61// ECMA 262 - 15.1.4
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000062function GlobalIsNaN(number) {
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +000063 var n = ToNumber(number);
64 return NUMBER_IS_NAN(n);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000065}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066
67
68// ECMA 262 - 15.1.5
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000069function GlobalIsFinite(number) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070 return %NumberIsFinite(ToNumber(number));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000071}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072
73
74// ECMA-262 - 15.1.2.2
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000075function GlobalParseInt(string, radix) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076 if (radix === void 0) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077 // Some people use parseInt instead of Math.floor. This
78 // optimization makes parseInt on a Smi 12 times faster (60ns
79 // vs 800ns). The following optimization makes parseInt on a
80 // non-Smi number 9 times faster (230ns vs 2070ns). Together
81 // they make parseInt on a string 1.4% slower (274ns vs 270ns).
82 if (%_IsSmi(string)) return string;
ager@chromium.org381abbb2009-02-25 13:23:22 +000083 if (IS_NUMBER(string) &&
84 ((string < -0.01 && -1e9 < string) ||
85 (0.01 < string && string < 1e9))) {
86 // Truncate number.
87 return string | 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000088 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000089 radix = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000090 } else {
91 radix = TO_INT32(radix);
92 if (!(radix == 0 || (2 <= radix && radix <= 36)))
93 return $NaN;
94 }
95 return %StringParseInt(ToString(string), radix);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000096}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000097
98
99// ECMA-262 - 15.1.2.3
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000100function GlobalParseFloat(string) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 return %StringParseFloat(ToString(string));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000102}
103
104
105function GlobalEval(x) {
106 if (!IS_STRING(x)) return x;
107
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000108 if (this !== global && this !== %GlobalReceiver(global)) {
ager@chromium.org3bf7b912008-11-17 09:09:45 +0000109 throw new $EvalError('The "this" object passed to eval must ' +
110 'be the global object from which eval originated');
111 }
112
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000113 var f = %CompileString(x, 0);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000114 if (!IS_FUNCTION(f)) return f;
115
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000116 return f.call(this);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000117}
118
119
120// execScript for IE compatibility.
121function GlobalExecScript(expr, lang) {
122 // NOTE: We don't care about the character casing.
123 if (!lang || /javascript/i.test(lang)) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000124 var f = %CompileString(ToString(expr), 0);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000125 f.call(%GlobalReceiver(global));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000126 }
127 return null;
128}
129
130
131// ----------------------------------------------------------------------------
132
133
134function SetupGlobal() {
135 // ECMA 262 - 15.1.1.1.
136 %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
137
138 // ECMA-262 - 15.1.1.2.
139 %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
140
141 // ECMA-262 - 15.1.1.3.
142 %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000143
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000144 // Setup non-enumerable function on the global object.
145 InstallFunctions(global, DONT_ENUM, $Array(
146 "isNaN", GlobalIsNaN,
147 "isFinite", GlobalIsFinite,
148 "parseInt", GlobalParseInt,
149 "parseFloat", GlobalParseFloat,
150 "eval", GlobalEval,
151 "execScript", GlobalExecScript
152 ));
153}
154
155SetupGlobal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000156
157
158// ----------------------------------------------------------------------------
159// Boolean (first part of definition)
160
161
162%SetCode($Boolean, function(x) {
mads.s.ager31e71382008-08-13 09:32:07 +0000163 if (%IsConstructCall()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000164 %_SetValueOf(this, ToBoolean(x));
165 } else {
166 return ToBoolean(x);
167 }
168});
169
170%FunctionSetPrototype($Boolean, new $Boolean(false));
171
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000172%SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000173
174// ----------------------------------------------------------------------------
175// Object
176
177$Object.prototype.constructor = $Object;
178
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000179// ECMA-262 - 15.2.4.2
180function ObjectToString() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181 var c = %ClassOf(this);
182 // Hide Arguments from the outside.
183 if (c === 'Arguments') c = 'Object';
184 return "[object " + c + "]";
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000185}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000186
187
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000188// ECMA-262 - 15.2.4.3
189function ObjectToLocaleString() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000190 return this.toString();
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000191}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192
193
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000194// ECMA-262 - 15.2.4.4
195function ObjectValueOf() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196 return this;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000197}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198
199
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000200// ECMA-262 - 15.2.4.5
201function ObjectHasOwnProperty(V) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202 return %HasLocalProperty(ToObject(this), ToString(V));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000203}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204
205
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000206// ECMA-262 - 15.2.4.6
207function ObjectIsPrototypeOf(V) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208 if (!IS_OBJECT(V) && !IS_FUNCTION(V)) return false;
209 return %IsInPrototypeChain(this, V);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000210}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211
212
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000213// ECMA-262 - 15.2.4.6
214function ObjectPropertyIsEnumerable(V) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000215 if (this == null) return false;
216 if (!IS_OBJECT(this) && !IS_FUNCTION(this)) return false;
217 return %IsPropertyEnumerable(this, ToString(V));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000218}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000219
220
221// Extensions for providing property getters and setters.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000222function ObjectDefineGetter(name, fun) {
223 if (this == null) {
224 throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
225 }
226 if (!IS_FUNCTION(fun)) {
227 throw new $TypeError('Object.prototype.__defineGetter__: Expecting function');
228 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229 return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000230}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231
232
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000233function ObjectLookupGetter(name) {
234 if (this == null) {
235 throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
236 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237 return %LookupAccessor(ToObject(this), ToString(name), GETTER);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000238}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000239
240
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000241function ObjectDefineSetter(name, fun) {
242 if (this == null) {
243 throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
244 }
245 if (!IS_FUNCTION(fun)) {
246 throw new $TypeError(
247 'Object.prototype.__defineSetter__: Expecting function');
248 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000249 return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000250}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000251
252
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000253function ObjectLookupSetter(name) {
254 if (this == null) {
255 throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
256 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257 return %LookupAccessor(ToObject(this), ToString(name), SETTER);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000258}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000259
260
261%SetCode($Object, function(x) {
mads.s.ager31e71382008-08-13 09:32:07 +0000262 if (%IsConstructCall()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263 if (x == null) return this;
264 return ToObject(x);
265 } else {
266 if (x == null) return { };
267 return ToObject(x);
268 }
269});
270
271
272// ----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000273
274
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000275function SetupObject() {
276 // Setup non-enumerable functions on the Object.prototype object.
277 InstallFunctions($Object.prototype, DONT_ENUM, $Array(
278 "toString", ObjectToString,
279 "toLocaleString", ObjectToLocaleString,
280 "valueOf", ObjectValueOf,
281 "hasOwnProperty", ObjectHasOwnProperty,
282 "isPrototypeOf", ObjectIsPrototypeOf,
283 "propertyIsEnumerable", ObjectPropertyIsEnumerable,
284 "__defineGetter__", ObjectDefineGetter,
285 "__lookupGetter__", ObjectLookupGetter,
286 "__defineSetter__", ObjectDefineSetter,
287 "__lookupSetter__", ObjectLookupSetter
288 ));
289}
290
291SetupObject();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000292
293
294// ----------------------------------------------------------------------------
295// Boolean
296
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000297function BooleanToString() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000298 // NOTE: Both Boolean objects and values can enter here as
299 // 'this'. This is not as dictated by ECMA-262.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000300 if (!IS_BOOLEAN(this) && !%HasBooleanClass(this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000301 throw new $TypeError('Boolean.prototype.toString is not generic');
302 return ToString(%_ValueOf(this));
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000303}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000304
305
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000306function BooleanValueOf() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000307 // NOTE: Both Boolean objects and values can enter here as
308 // 'this'. This is not as dictated by ECMA-262.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000309 if (!IS_BOOLEAN(this) && !%HasBooleanClass(this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000310 throw new $TypeError('Boolean.prototype.valueOf is not generic');
311 return %_ValueOf(this);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000312}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000313
314
315// ----------------------------------------------------------------------------
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000316
317
318function SetupBoolean() {
319 InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
320 "toString", BooleanToString,
321 "valueOf", BooleanValueOf
322 ));
323}
324
325SetupBoolean();
326
327// ----------------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000328// Number
329
330// Set the Number function and constructor.
331%SetCode($Number, function(x) {
332 var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
mads.s.ager31e71382008-08-13 09:32:07 +0000333 if (%IsConstructCall()) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000334 %_SetValueOf(this, value);
335 } else {
336 return value;
337 }
338});
339
340%FunctionSetPrototype($Number, new $Number(0));
341
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342// ECMA-262 section 15.7.4.2.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000343function NumberToString(radix) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000344 // NOTE: Both Number objects and values can enter here as
345 // 'this'. This is not as dictated by ECMA-262.
346 var number = this;
347 if (!IS_NUMBER(this)) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000348 if (!%HasNumberClass(this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000349 throw new $TypeError('Number.prototype.toString is not generic');
350 // Get the value of this number in case it's an object.
351 number = %_ValueOf(this);
352 }
353 // Fast case: Convert number in radix 10.
354 if (IS_UNDEFINED(radix) || radix === 10) {
355 return ToString(number);
356 }
357
358 // Convert the radix to an integer and check the range.
359 radix = TO_INTEGER(radix);
360 if (radix < 2 || radix > 36) {
361 throw new $RangeError('toString() radix argument must be between 2 and 36');
362 }
363 // Convert the number to a string in the given radix.
364 return %NumberToRadixString(number, radix);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000365}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000366
367
368// ECMA-262 section 15.7.4.3
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000369function NumberToLocaleString() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000370 return this.toString();
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000371}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000372
373
374// ECMA-262 section 15.7.4.4
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000375function NumberValueOf() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000376 // NOTE: Both Number objects and values can enter here as
377 // 'this'. This is not as dictated by ECMA-262.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000378 if (!IS_NUMBER(this) && !%HasNumberClass(this))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000379 throw new $TypeError('Number.prototype.valueOf is not generic');
380 return %_ValueOf(this);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000381}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000382
383
384// ECMA-262 section 15.7.4.5
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000385function NumberToFixed(fractionDigits) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000386 var f = TO_INTEGER(fractionDigits);
387 if (f < 0 || f > 20) {
388 throw new $RangeError("toFixed() digits argument must be between 0 and 20");
389 }
390 var x = ToNumber(this);
391 return %NumberToFixed(x, f);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000392}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000393
394
395// ECMA-262 section 15.7.4.6
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000396function NumberToExponential(fractionDigits) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000397 var f = -1;
398 if (!IS_UNDEFINED(fractionDigits)) {
399 f = TO_INTEGER(fractionDigits);
400 if (f < 0 || f > 20) {
401 throw new $RangeError("toExponential() argument must be between 0 and 20");
402 }
403 }
404 var x = ToNumber(this);
405 return %NumberToExponential(x, f);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000406}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000407
408
409// ECMA-262 section 15.7.4.7
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000410function NumberToPrecision(precision) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000411 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this));
412 var p = TO_INTEGER(precision);
413 if (p < 1 || p > 21) {
414 throw new $RangeError("toPrecision() argument must be between 1 and 21");
415 }
416 var x = ToNumber(this);
417 return %NumberToPrecision(x, p);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000418}
419
420
421// ----------------------------------------------------------------------------
422
423function SetupNumber() {
424 // Setup the constructor property on the Number prototype object.
425 %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
426
427 // ECMA-262 section 15.7.3.1.
428 %SetProperty($Number,
429 "MAX_VALUE",
430 1.7976931348623157e+308,
431 DONT_ENUM | DONT_DELETE | READ_ONLY);
432
433 // ECMA-262 section 15.7.3.2.
434 %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
435
436 // ECMA-262 section 15.7.3.3.
437 %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
438
439 // ECMA-262 section 15.7.3.4.
440 %SetProperty($Number,
441 "NEGATIVE_INFINITY",
442 -1/0,
443 DONT_ENUM | DONT_DELETE | READ_ONLY);
444
445 // ECMA-262 section 15.7.3.5.
446 %SetProperty($Number,
447 "POSITIVE_INFINITY",
448 1/0,
449 DONT_ENUM | DONT_DELETE | READ_ONLY);
450
451 // Setup non-enumerable functions on the Number prototype object.
452 InstallFunctions($Number.prototype, DONT_ENUM, $Array(
453 "toString", NumberToString,
454 "toLocaleString", NumberToLocaleString,
455 "valueOf", NumberValueOf,
456 "toFixed", NumberToFixed,
457 "toExponential", NumberToExponential,
458 "toPrecision", NumberToPrecision
459 ));
460}
461
462SetupNumber();
463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464
465
466// ----------------------------------------------------------------------------
467// Function
468
469$Function.prototype.constructor = $Function;
470
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471function FunctionSourceString(func) {
472 // NOTE: Both Function objects and values can enter here as
473 // 'func'. This is not as dictated by ECMA-262.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000474 if (!IS_FUNCTION(func) && !%HasFunctionClass(func))
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000475 throw new $TypeError('Function.prototype.toString is not generic');
476
477 var source = %FunctionGetSourceCode(func);
478 if (!IS_STRING(source)) {
479 var name = %FunctionGetName(func);
480 if (name) {
481 // Mimic what KJS does.
482 return 'function ' + name + '() { [native code] }';
483 } else {
484 return 'function () { [native code] }';
485 }
486 }
487
488 // Censor occurrences of internal calls. We do that for all
489 // functions and don't cache under the assumption that people rarly
490 // convert functions to strings. Note that we (apparently) can't
491 // use regular expression literals in natives files.
492 var regexp = ORIGINAL_REGEXP("%(\\w+\\()", "gm");
493 if (source.match(regexp)) source = source.replace(regexp, "$1");
494 var name = %FunctionGetName(func);
495 return 'function ' + name + source;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000496}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000497
498
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000499function FunctionToString() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000500 return FunctionSourceString(this);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000501}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000502
503
504function NewFunction(arg1) { // length == 1
505 var n = %_ArgumentsLength();
506 var p = '';
507 if (n > 1) {
508 p = new $Array(n - 1);
509 // Explicitly convert all parameters to strings.
510 // Array.prototype.join replaces null with empty strings which is
511 // not appropriate.
512 for (var i = 0; i < n - 1; i++) p[i] = ToString(%_Arguments(i));
513 p = p.join(',');
514 // If the formal parameters string include ) - an illegal
515 // character - it may make the combined function expression
516 // compile. We avoid this problem by checking for this early on.
517 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
518 }
519 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
ager@chromium.org236ad962008-09-25 09:45:57 +0000520 var source = '(function(' + p + ') {\n' + body + '\n})';
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000521
522 // The call to SetNewFunctionAttributes will ensure the prototype
523 // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000524 var f = %CompileString(source, -1)();
ager@chromium.org236ad962008-09-25 09:45:57 +0000525 %FunctionSetName(f, "anonymous");
526 return %SetNewFunctionAttributes(f);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000527}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528
529%SetCode($Function, NewFunction);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000530
531// ----------------------------------------------------------------------------
532
533function SetupFunction() {
534 InstallFunctions($Function.prototype, DONT_ENUM, $Array(
535 "toString", FunctionToString
536 ));
537}
538
539SetupFunction();
540