Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: src/v8natives.js

Issue 6447: Update v8natives to use InstallFunctions to get the correct function... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/date-delay.js ('k') | test/mjsunit/function-names.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28
29 // This file relies on the fact that the following declarations have been made 28 // This file relies on the fact that the following declarations have been made
30 // 29 //
31 // in runtime.js: 30 // in runtime.js:
32 // const $Object = global.Object; 31 // const $Object = global.Object;
33 // const $Boolean = global.Boolean; 32 // const $Boolean = global.Boolean;
34 // const $Number = global.Number; 33 // const $Number = global.Number;
35 // const $Function = global.Function; 34 // const $Function = global.Function;
36 // const $Array = global.Array; 35 // const $Array = global.Array;
37 // const $NaN = 0/0; 36 // const $NaN = 0/0;
38 // 37 //
39 // in math.js: 38 // in math.js:
40 // const $floor = MathFloor 39 // const $floor = MathFloor
41 40
41 const $isNaN = GlobalIsNaN;
42 const $isFinite = GlobalIsFinite;
42 43
43 // ECMA 262 - 15.1.1.1. 44 // ----------------------------------------------------------------------------
44 %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
45 45
46 46
47 // ECMA-262 - 15.1.1.2. 47 // Helper function used to install functions on objects.
48 %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE); 48 function 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 }
49 56
50 57
51 // ECMA-262 - 15.1.1.3. 58 // ----------------------------------------------------------------------------
52 %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
53 59
54 60
55 // ECMA 262 - 15.1.4 61 // ECMA 262 - 15.1.4
56 function $isNaN(number) { 62 function GlobalIsNaN(number) {
57 var n = ToNumber(number); 63 var n = ToNumber(number);
58 return NUMBER_IS_NAN(n); 64 return NUMBER_IS_NAN(n);
59 } 65 }
60 %SetProperty(global, "isNaN", $isNaN, DONT_ENUM);
61 66
62 67
63 // ECMA 262 - 15.1.5 68 // ECMA 262 - 15.1.5
64 function $isFinite(number) { 69 function GlobalIsFinite(number) {
65 return %NumberIsFinite(ToNumber(number)); 70 return %NumberIsFinite(ToNumber(number));
66 } 71 }
67 %SetProperty(global, "isFinite", $isFinite, DONT_ENUM);
68 72
69 73
70 // ECMA-262 - 15.1.2.2 74 // ECMA-262 - 15.1.2.2
71 %SetProperty(global, "parseInt", function(string, radix) { 75 function GlobalParseInt(string, radix) {
72 if (radix === void 0) { 76 if (radix === void 0) {
73 radix = 0; 77 radix = 0;
74 // Some people use parseInt instead of Math.floor. This 78 // Some people use parseInt instead of Math.floor. This
75 // optimization makes parseInt on a Smi 12 times faster (60ns 79 // optimization makes parseInt on a Smi 12 times faster (60ns
76 // vs 800ns). The following optimization makes parseInt on a 80 // vs 800ns). The following optimization makes parseInt on a
77 // non-Smi number 9 times faster (230ns vs 2070ns). Together 81 // non-Smi number 9 times faster (230ns vs 2070ns). Together
78 // they make parseInt on a string 1.4% slower (274ns vs 270ns). 82 // they make parseInt on a string 1.4% slower (274ns vs 270ns).
79 if (%_IsSmi(string)) return string; 83 if (%_IsSmi(string)) return string;
80 if (IS_NUMBER(string)) { 84 if (IS_NUMBER(string)) {
81 if (string >= 0.01 && string < 1e9) 85 if (string >= 0.01 && string < 1e9)
82 return $floor(string); 86 return $floor(string);
83 if (string <= -0.01 && string > -1e9) 87 if (string <= -0.01 && string > -1e9)
84 return - $floor(-string); 88 return - $floor(-string);
85 } 89 }
86 } else { 90 } else {
87 radix = TO_INT32(radix); 91 radix = TO_INT32(radix);
88 if (!(radix == 0 || (2 <= radix && radix <= 36))) 92 if (!(radix == 0 || (2 <= radix && radix <= 36)))
89 return $NaN; 93 return $NaN;
90 } 94 }
91 return %StringParseInt(ToString(string), radix); 95 return %StringParseInt(ToString(string), radix);
92 }, DONT_ENUM); 96 }
93 97
94 98
95 // ECMA-262 - 15.1.2.3 99 // ECMA-262 - 15.1.2.3
96 %SetProperty(global, "parseFloat", function(string) { 100 function GlobalParseFloat(string) {
97 return %StringParseFloat(ToString(string)); 101 return %StringParseFloat(ToString(string));
98 }, DONT_ENUM); 102 }
103
104
105 function GlobalEval(x) {
106 if (!IS_STRING(x)) return x;
107
108 var f = %CompileString(x, 0, true);
109 if (!IS_FUNCTION(f)) return f;
110
111 return f.call(%EvalReceiver(this));
112 }
113
114
115 // execScript for IE compatibility.
116 function GlobalExecScript(expr, lang) {
117 // NOTE: We don't care about the character casing.
118 if (!lang || /javascript/i.test(lang)) {
119 var f = %CompileString(ToString(expr), 0, false);
120 f.call(global);
121 }
122 return null;
123 }
124
125
126 // ----------------------------------------------------------------------------
127
128
129 function SetupGlobal() {
130 // ECMA 262 - 15.1.1.1.
131 %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
132
133 // ECMA-262 - 15.1.1.2.
134 %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
135
136 // ECMA-262 - 15.1.1.3.
137 %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
138
139 // Setup non-enumerable function on the global object.
140 InstallFunctions(global, DONT_ENUM, $Array(
141 "isNaN", GlobalIsNaN,
142 "isFinite", GlobalIsFinite,
143 "parseInt", GlobalParseInt,
144 "parseFloat", GlobalParseFloat,
145 "eval", GlobalEval,
146 "execScript", GlobalExecScript
147 ));
148 }
149
150 SetupGlobal();
99 151
100 152
101 // ---------------------------------------------------------------------------- 153 // ----------------------------------------------------------------------------
102 // Boolean (first part of definition) 154 // Boolean (first part of definition)
103 155
104 156
105 %SetCode($Boolean, function(x) { 157 %SetCode($Boolean, function(x) {
106 if (%IsConstructCall()) { 158 if (%IsConstructCall()) {
107 %_SetValueOf(this, ToBoolean(x)); 159 %_SetValueOf(this, ToBoolean(x));
108 } else { 160 } else {
109 return ToBoolean(x); 161 return ToBoolean(x);
110 } 162 }
111 }); 163 });
112 164
113 %FunctionSetPrototype($Boolean, new $Boolean(false)); 165 %FunctionSetPrototype($Boolean, new $Boolean(false));
114 166
115 %SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM); 167 %SetProperty($Boolean.prototype, "constructor", $Boolean, DONT_ENUM);
116 168
117 // ---------------------------------------------------------------------------- 169 // ----------------------------------------------------------------------------
118 // Object 170 // Object
119 171
120 $Object.prototype.constructor = $Object; 172 $Object.prototype.constructor = $Object;
121 173
122 %SetProperty($Object.prototype, "toString", function() { 174 // ECMA-262 - 15.2.4.2
175 function ObjectToString() {
123 var c = %ClassOf(this); 176 var c = %ClassOf(this);
124 // Hide Arguments from the outside. 177 // Hide Arguments from the outside.
125 if (c === 'Arguments') c = 'Object'; 178 if (c === 'Arguments') c = 'Object';
126 return "[object " + c + "]"; 179 return "[object " + c + "]";
127 }, DONT_ENUM); 180 }
128 181
129 182
130 // ECMA-262, section 15.2.4.3, page 84. 183 // ECMA-262 - 15.2.4.3
131 %SetProperty($Object.prototype, "toLocaleString", function() { 184 function ObjectToLocaleString() {
132 return this.toString(); 185 return this.toString();
133 }, DONT_ENUM); 186 }
134 187
135 188
136 // ECMA-262, section 15.2.4.4, page 85. 189 // ECMA-262 - 15.2.4.4
137 %SetProperty($Object.prototype, "valueOf", function() { 190 function ObjectValueOf() {
138 return this; 191 return this;
139 }, DONT_ENUM); 192 }
140 193
141 194
142 // ECMA-262, section 15.2.4.5, page 85. 195 // ECMA-262 - 15.2.4.5
143 %SetProperty($Object.prototype, "hasOwnProperty", function(V) { 196 function ObjectHasOwnProperty(V) {
144 return %HasLocalProperty(ToObject(this), ToString(V)); 197 return %HasLocalProperty(ToObject(this), ToString(V));
145 }, DONT_ENUM); 198 }
146 199
147 200
148 // ECMA-262, section 15.2.4.6, page 85. 201 // ECMA-262 - 15.2.4.6
149 %SetProperty($Object.prototype, "isPrototypeOf", function(V) { 202 function ObjectIsPrototypeOf(V) {
150 if (!IS_OBJECT(V) && !IS_FUNCTION(V)) return false; 203 if (!IS_OBJECT(V) && !IS_FUNCTION(V)) return false;
151 return %IsInPrototypeChain(this, V); 204 return %IsInPrototypeChain(this, V);
152 }, DONT_ENUM); 205 }
153 206
154 207
155 // ECMA-262, section 15.2.4.6, page 85. 208 // ECMA-262 - 15.2.4.6
156 %SetProperty($Object.prototype, "propertyIsEnumerable", function(V) { 209 function ObjectPropertyIsEnumerable(V) {
157 if (this == null) return false; 210 if (this == null) return false;
158 if (!IS_OBJECT(this) && !IS_FUNCTION(this)) return false; 211 if (!IS_OBJECT(this) && !IS_FUNCTION(this)) return false;
159 return %IsPropertyEnumerable(this, ToString(V)); 212 return %IsPropertyEnumerable(this, ToString(V));
160 }, DONT_ENUM); 213 }
161 214
162 215
163 // Extensions for providing property getters and setters. 216 // Extensions for providing property getters and setters.
164 %SetProperty($Object.prototype, "__defineGetter__", function(name, fun) { 217 function ObjectDefineGetter(name, fun) {
165 if (this == null) { 218 if (this == null) {
166 throw new $TypeError('Object.prototype.__defineGetter__: this is Null'); 219 throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
167 } 220 }
168 if (!IS_FUNCTION(fun)) { 221 if (!IS_FUNCTION(fun)) {
169 throw new $TypeError( 222 throw new $TypeError(
170 'Object.prototype.__defineGetter__: Expecting function'); 223 'Object.prototype.__defineGetter__: Expecting function');
171 } 224 }
172 return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun); 225 return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun);
173 }, DONT_ENUM); 226 }
174 227
175 228
176 229 function ObjectLookupGetter(name) {
177 %SetProperty($Object.prototype, "__lookupGetter__", function(name) {
178 if (this == null) { 230 if (this == null) {
179 throw new $TypeError('Object.prototype.__lookupGetter__: this is Null'); 231 throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
180 } 232 }
181 return %LookupAccessor(ToObject(this), ToString(name), GETTER); 233 return %LookupAccessor(ToObject(this), ToString(name), GETTER);
182 }, DONT_ENUM); 234 }
183 235
184 236
185 %SetProperty($Object.prototype, "__defineSetter__", function(name, fun) { 237 function ObjectDefineSetter(name, fun) {
186 if (this == null) { 238 if (this == null) {
187 throw new $TypeError('Object.prototype.__defineSetter__: this is Null'); 239 throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
188 } 240 }
189 if (!IS_FUNCTION(fun)) { 241 if (!IS_FUNCTION(fun)) {
190 throw new $TypeError( 242 throw new $TypeError(
191 'Object.prototype.__defineSetter__: Expecting function'); 243 'Object.prototype.__defineSetter__: Expecting function');
192 } 244 }
193 return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun); 245 return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun);
194 }, DONT_ENUM); 246 }
195 247
196 248
197 %SetProperty($Object.prototype, "__lookupSetter__", function(name) { 249 function ObjectLookupSetter(name) {
198 if (this == null) { 250 if (this == null) {
199 throw new $TypeError('Object.prototype.__lookupSetter__: this is Null'); 251 throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
200 } 252 }
201 return %LookupAccessor(ToObject(this), ToString(name), SETTER); 253 return %LookupAccessor(ToObject(this), ToString(name), SETTER);
202 }, DONT_ENUM); 254 }
203 255
204 256
205 %SetCode($Object, function(x) { 257 %SetCode($Object, function(x) {
206 if (%IsConstructCall()) { 258 if (%IsConstructCall()) {
207 if (x == null) return this; 259 if (x == null) return this;
208 return ToObject(x); 260 return ToObject(x);
209 } else { 261 } else {
210 if (x == null) return { }; 262 if (x == null) return { };
211 return ToObject(x); 263 return ToObject(x);
212 } 264 }
213 }); 265 });
214 266
215 267
216 // ---------------------------------------------------------------------------- 268 // ----------------------------------------------------------------------------
217 // Global stuff...
218
219 %SetProperty(global, "eval", function(x) {
220 if (!IS_STRING(x)) return x;
221
222 var f = %CompileString(x, 0, true);
223 if (!IS_FUNCTION(f)) return f;
224
225 return f.call(%EvalReceiver(this));
226 }, DONT_ENUM);
227 269
228 270
229 // execScript for IE compatibility. 271 function SetupObject() {
230 %SetProperty(global, "execScript", function(expr, lang) { 272 // Setup non-enumerable functions on the Object.prototype object.
231 // NOTE: We don't care about the character casing. 273 InstallFunctions($Object.prototype, DONT_ENUM, $Array(
232 if (!lang || /javascript/i.test(lang)) { 274 "toString", ObjectToString,
233 var f = %CompileString(ToString(expr), 0, false); 275 "toLocaleString", ObjectToLocaleString,
234 f.call(global); 276 "valueOf", ObjectValueOf,
235 } 277 "hasOwnProperty", ObjectHasOwnProperty,
236 return null; 278 "isPrototypeOf", ObjectIsPrototypeOf,
237 }, DONT_ENUM); 279 "propertyIsEnumerable", ObjectPropertyIsEnumerable,
280 "__defineGetter__", ObjectDefineGetter,
281 "__lookupGetter__", ObjectLookupGetter,
282 "__defineSetter__", ObjectDefineSetter,
283 "__lookupSetter__", ObjectLookupSetter
284 ));
285 }
286
287 SetupObject();
238 288
239 289
240 // ---------------------------------------------------------------------------- 290 // ----------------------------------------------------------------------------
241 // Boolean 291 // Boolean
242 292
243 %SetProperty($Boolean.prototype, "toString", function() { 293 function BooleanToString() {
244 // NOTE: Both Boolean objects and values can enter here as 294 // NOTE: Both Boolean objects and values can enter here as
245 // 'this'. This is not as dictated by ECMA-262. 295 // 'this'. This is not as dictated by ECMA-262.
246 if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean') 296 if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean')
247 throw new $TypeError('Boolean.prototype.toString is not generic'); 297 throw new $TypeError('Boolean.prototype.toString is not generic');
248 return ToString(%_ValueOf(this)); 298 return ToString(%_ValueOf(this));
249 }, DONT_ENUM); 299 }
250 300
251 301
252 %SetProperty($Boolean.prototype, "valueOf", function() { 302 function BooleanValueOf() {
253 // NOTE: Both Boolean objects and values can enter here as 303 // NOTE: Both Boolean objects and values can enter here as
254 // 'this'. This is not as dictated by ECMA-262. 304 // 'this'. This is not as dictated by ECMA-262.
255 if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean') 305 if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean')
256 throw new $TypeError('Boolean.prototype.valueOf is not generic'); 306 throw new $TypeError('Boolean.prototype.valueOf is not generic');
257 return %_ValueOf(this); 307 return %_ValueOf(this);
258 }, DONT_ENUM); 308 }
259 309
260 310
261 // ---------------------------------------------------------------------------- 311 // ----------------------------------------------------------------------------
312
313
314 function SetupBoolean() {
315 InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
316 "toString", BooleanToString,
317 "valueOf", BooleanValueOf
318 ));
319 }
320
321 SetupBoolean();
322
323 // ----------------------------------------------------------------------------
262 // Number 324 // Number
263 325
264 // Set the Number function and constructor. 326 // Set the Number function and constructor.
265 %SetCode($Number, function(x) { 327 %SetCode($Number, function(x) {
266 var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x); 328 var value = %_ArgumentsLength() == 0 ? 0 : ToNumber(x);
267 if (%IsConstructCall()) { 329 if (%IsConstructCall()) {
268 %_SetValueOf(this, value); 330 %_SetValueOf(this, value);
269 } else { 331 } else {
270 return value; 332 return value;
271 } 333 }
272 }); 334 });
273 335
274 %FunctionSetPrototype($Number, new $Number(0)); 336 %FunctionSetPrototype($Number, new $Number(0));
275 337
276 %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
277
278 // ECMA-262 section 15.7.3.1.
279 %SetProperty($Number,
280 "MAX_VALUE",
281 1.7976931348623157e+308,
282 DONT_ENUM | DONT_DELETE | READ_ONLY);
283
284 // ECMA-262 section 15.7.3.2.
285 %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
286
287 // ECMA-262 section 15.7.3.3.
288 %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
289
290 // ECMA-262 section 15.7.3.4.
291 %SetProperty($Number,
292 "NEGATIVE_INFINITY",
293 -1/0,
294 DONT_ENUM | DONT_DELETE | READ_ONLY);
295
296 // ECMA-262 section 15.7.3.5.
297 %SetProperty($Number,
298 "POSITIVE_INFINITY",
299 1/0,
300 DONT_ENUM | DONT_DELETE | READ_ONLY);
301
302 // ECMA-262 section 15.7.4.2. 338 // ECMA-262 section 15.7.4.2.
303 %SetProperty($Number.prototype, "toString", function(radix) { 339 function NumberToString(radix) {
304 // NOTE: Both Number objects and values can enter here as 340 // NOTE: Both Number objects and values can enter here as
305 // 'this'. This is not as dictated by ECMA-262. 341 // 'this'. This is not as dictated by ECMA-262.
306 var number = this; 342 var number = this;
307 if (!IS_NUMBER(this)) { 343 if (!IS_NUMBER(this)) {
308 if (%ClassOf(this) !== 'Number') 344 if (%ClassOf(this) !== 'Number')
309 throw new $TypeError('Number.prototype.toString is not generic'); 345 throw new $TypeError('Number.prototype.toString is not generic');
310 // Get the value of this number in case it's an object. 346 // Get the value of this number in case it's an object.
311 number = %_ValueOf(this); 347 number = %_ValueOf(this);
312 } 348 }
313 // Fast case: Convert number in radix 10. 349 // Fast case: Convert number in radix 10.
314 if (IS_UNDEFINED(radix) || radix === 10) { 350 if (IS_UNDEFINED(radix) || radix === 10) {
315 return ToString(number); 351 return ToString(number);
316 } 352 }
317 353
318 // Convert the radix to an integer and check the range. 354 // Convert the radix to an integer and check the range.
319 radix = TO_INTEGER(radix); 355 radix = TO_INTEGER(radix);
320 if (radix < 2 || radix > 36) { 356 if (radix < 2 || radix > 36) {
321 throw new $RangeError('toString() radix argument must be between 2 and 36'); 357 throw new $RangeError('toString() radix argument must be between 2 and 36');
322 } 358 }
323 // Convert the number to a string in the given radix. 359 // Convert the number to a string in the given radix.
324 return %NumberToRadixString(number, radix); 360 return %NumberToRadixString(number, radix);
325 }, DONT_ENUM); 361 }
326 362
327 363
328 // ECMA-262 section 15.7.4.3 364 // ECMA-262 section 15.7.4.3
329 %SetProperty($Number.prototype, "toLocaleString", function() { 365 function NumberToLocaleString() {
330 return this.toString(); 366 return this.toString();
331 }, DONT_ENUM); 367 }
332 368
333 369
334 // ECMA-262 section 15.7.4.4 370 // ECMA-262 section 15.7.4.4
335 %SetProperty($Number.prototype, "valueOf", function() { 371 function NumberValueOf() {
336 // NOTE: Both Number objects and values can enter here as 372 // NOTE: Both Number objects and values can enter here as
337 // 'this'. This is not as dictated by ECMA-262. 373 // 'this'. This is not as dictated by ECMA-262.
338 if (!IS_NUMBER(this) && %ClassOf(this) !== 'Number') 374 if (!IS_NUMBER(this) && %ClassOf(this) !== 'Number')
339 throw new $TypeError('Number.prototype.valueOf is not generic'); 375 throw new $TypeError('Number.prototype.valueOf is not generic');
340 return %_ValueOf(this); 376 return %_ValueOf(this);
341 }, DONT_ENUM); 377 }
342 378
343 379
344 // ECMA-262 section 15.7.4.5 380 // ECMA-262 section 15.7.4.5
345 %SetProperty($Number.prototype, "toFixed", function(fractionDigits) { 381 function NumberToFixed(fractionDigits) {
346 var f = TO_INTEGER(fractionDigits); 382 var f = TO_INTEGER(fractionDigits);
347 if (f < 0 || f > 20) { 383 if (f < 0 || f > 20) {
348 throw new $RangeError("toFixed() digits argument must be between 0 and 20"); 384 throw new $RangeError("toFixed() digits argument must be between 0 and 20");
349 } 385 }
350 var x = ToNumber(this); 386 var x = ToNumber(this);
351 return %NumberToFixed(x, f); 387 return %NumberToFixed(x, f);
352 }, DONT_ENUM); 388 }
353 389
354 390
355 // ECMA-262 section 15.7.4.6 391 // ECMA-262 section 15.7.4.6
356 %SetProperty($Number.prototype, "toExponential", function(fractionDigits) { 392 function NumberToExponential(fractionDigits) {
357 var f = -1; 393 var f = -1;
358 if (!IS_UNDEFINED(fractionDigits)) { 394 if (!IS_UNDEFINED(fractionDigits)) {
359 f = TO_INTEGER(fractionDigits); 395 f = TO_INTEGER(fractionDigits);
360 if (f < 0 || f > 20) { 396 if (f < 0 || f > 20) {
361 throw new $RangeError("toExponential() argument must be between 0 and 20") ; 397 throw new $RangeError("toExponential() argument must be between 0 and 20") ;
362 } 398 }
363 } 399 }
364 var x = ToNumber(this); 400 var x = ToNumber(this);
365 return %NumberToExponential(x, f); 401 return %NumberToExponential(x, f);
366 }, DONT_ENUM); 402 }
367 403
368 404
369 // ECMA-262 section 15.7.4.7 405 // ECMA-262 section 15.7.4.7
370 %SetProperty($Number.prototype, "toPrecision", function(precision) { 406 function NumberToPrecision(precision) {
371 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this)); 407 if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this));
372 var p = TO_INTEGER(precision); 408 var p = TO_INTEGER(precision);
373 if (p < 1 || p > 21) { 409 if (p < 1 || p > 21) {
374 throw new $RangeError("toPrecision() argument must be between 1 and 21"); 410 throw new $RangeError("toPrecision() argument must be between 1 and 21");
375 } 411 }
376 var x = ToNumber(this); 412 var x = ToNumber(this);
377 return %NumberToPrecision(x, p); 413 return %NumberToPrecision(x, p);
378 }, DONT_ENUM); 414 }
415
416
417 // ----------------------------------------------------------------------------
418
419 function SetupNumber() {
420 // Setup the constructor property on the Number prototype object.
421 %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
422
423 // ECMA-262 section 15.7.3.1.
424 %SetProperty($Number,
425 "MAX_VALUE",
426 1.7976931348623157e+308,
427 DONT_ENUM | DONT_DELETE | READ_ONLY);
428
429 // ECMA-262 section 15.7.3.2.
430 %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY );
431
432 // ECMA-262 section 15.7.3.3.
433 %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
434
435 // ECMA-262 section 15.7.3.4.
436 %SetProperty($Number,
437 "NEGATIVE_INFINITY",
438 -1/0,
439 DONT_ENUM | DONT_DELETE | READ_ONLY);
440
441 // ECMA-262 section 15.7.3.5.
442 %SetProperty($Number,
443 "POSITIVE_INFINITY",
444 1/0,
445 DONT_ENUM | DONT_DELETE | READ_ONLY);
446
447 // Setup non-enumerable functions on the Number prototype object.
448 InstallFunctions($Number.prototype, DONT_ENUM, $Array(
449 "toString", NumberToString,
450 "toLocaleString", NumberToLocaleString,
451 "valueOf", NumberValueOf,
452 "toFixed", NumberToFixed,
453 "toExponential", NumberToExponential,
454 "toPrecision", NumberToPrecision
455 ));
456 }
457
458 SetupNumber();
459
379 460
380 461
381 // ---------------------------------------------------------------------------- 462 // ----------------------------------------------------------------------------
382 // Function 463 // Function
383 464
384 $Function.prototype.constructor = $Function; 465 $Function.prototype.constructor = $Function;
385 466
386
387 function FunctionSourceString(func) { 467 function FunctionSourceString(func) {
388 // NOTE: Both Function objects and values can enter here as 468 // NOTE: Both Function objects and values can enter here as
389 // 'func'. This is not as dictated by ECMA-262. 469 // 'func'. This is not as dictated by ECMA-262.
390 if (!IS_FUNCTION(func) && %ClassOf(func) != 'Function') 470 if (!IS_FUNCTION(func) && %ClassOf(func) != 'Function')
391 throw new $TypeError('Function.prototype.toString is not generic'); 471 throw new $TypeError('Function.prototype.toString is not generic');
392 472
393 var source = %FunctionGetSourceCode(func); 473 var source = %FunctionGetSourceCode(func);
394 if (!IS_STRING(source)) { 474 if (!IS_STRING(source)) {
395 var name = %FunctionGetName(func); 475 var name = %FunctionGetName(func);
396 if (name) { 476 if (name) {
397 // Mimic what KJS does. 477 // Mimic what KJS does.
398 return 'function ' + name + '() { [native code] }'; 478 return 'function ' + name + '() { [native code] }';
399 } else { 479 } else {
400 return 'function () { [native code] }'; 480 return 'function () { [native code] }';
401 } 481 }
402 } 482 }
403 483
404 // Censor occurrences of internal calls. We do that for all 484 // Censor occurrences of internal calls. We do that for all
405 // functions and don't cache under the assumption that people rarly 485 // functions and don't cache under the assumption that people rarly
406 // convert functions to strings. Note that we (apparently) can't 486 // convert functions to strings. Note that we (apparently) can't
407 // use regular expression literals in natives files. 487 // use regular expression literals in natives files.
408 var regexp = ORIGINAL_REGEXP("%(\\w+\\()", "gm"); 488 var regexp = ORIGINAL_REGEXP("%(\\w+\\()", "gm");
409 if (source.match(regexp)) source = source.replace(regexp, "$1"); 489 if (source.match(regexp)) source = source.replace(regexp, "$1");
410 var name = %FunctionGetName(func); 490 var name = %FunctionGetName(func);
411 return 'function ' + name + source; 491 return 'function ' + name + source;
412 } 492 }
413 493
414 494
415 %SetProperty($Function.prototype, "toString", function() { 495 function FunctionToString() {
416 return FunctionSourceString(this); 496 return FunctionSourceString(this);
417 }, DONT_ENUM); 497 }
418 498
419 499
420 function NewFunction(arg1) { // length == 1 500 function NewFunction(arg1) { // length == 1
421 var n = %_ArgumentsLength(); 501 var n = %_ArgumentsLength();
422 var p = ''; 502 var p = '';
423 if (n > 1) { 503 if (n > 1) {
424 p = new $Array(n - 1); 504 p = new $Array(n - 1);
425 // Explicitly convert all parameters to strings. 505 // Explicitly convert all parameters to strings.
426 // Array.prototype.join replaces null with empty strings which is 506 // Array.prototype.join replaces null with empty strings which is
427 // not appropriate. 507 // not appropriate.
428 for (var i = 0; i < n - 1; i++) p[i] = ToString(%_Arguments(i)); 508 for (var i = 0; i < n - 1; i++) p[i] = ToString(%_Arguments(i));
429 p = p.join(','); 509 p = p.join(',');
430 // If the formal parameters string include ) - an illegal 510 // If the formal parameters string include ) - an illegal
431 // character - it may make the combined function expression 511 // character - it may make the combined function expression
432 // compile. We avoid this problem by checking for this early on. 512 // compile. We avoid this problem by checking for this early on.
433 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]); 513 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
434 } 514 }
435 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : ''; 515 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
436 var source = '(function(' + p + ') {\n' + body + '\n})'; 516 var source = '(function(' + p + ') {\n' + body + '\n})';
437 517
438 // The call to SetNewFunctionAttributes will ensure the prototype 518 // The call to SetNewFunctionAttributes will ensure the prototype
439 // property of the resulting function is enumerable (ECMA262, 15.3.5.2). 519 // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
440 var f = %CompileString(source, -1, false)(); 520 var f = %CompileString(source, -1, false)();
441 %FunctionSetName(f, "anonymous"); 521 %FunctionSetName(f, "anonymous");
442 return %SetNewFunctionAttributes(f); 522 return %SetNewFunctionAttributes(f);
443 } 523 }
444 524
445 %SetCode($Function, NewFunction); 525 %SetCode($Function, NewFunction);
526
527 // ----------------------------------------------------------------------------
528
529 function SetupFunction() {
530 InstallFunctions($Function.prototype, DONT_ENUM, $Array(
531 "toString", FunctionToString
532 ));
533 }
534
535 SetupFunction();
536
OLDNEW
« no previous file with comments | « src/date-delay.js ('k') | test/mjsunit/function-names.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698