OLD | NEW |
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 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 if (IS_OBJECT(y)) { | 86 if (IS_OBJECT(y)) { |
87 return %_ObjectEquals(x, y) ? 0 : 1; | 87 return %_ObjectEquals(x, y) ? 0 : 1; |
88 } | 88 } |
89 if (IS_FUNCTION(y)) { | 89 if (IS_FUNCTION(y)) { |
90 return %_ObjectEquals(x, y) ? 0 : 1; | 90 return %_ObjectEquals(x, y) ? 0 : 1; |
91 } | 91 } |
92 x = %ToPrimitive(x, NO_HINT); | 92 x = %ToPrimitive(x, NO_HINT); |
93 | 93 |
94 } | 94 } |
95 } | 95 } |
96 }; | 96 } |
97 | 97 |
98 | 98 |
99 // ECMA-262, section 11.9.4, page 56. | 99 // ECMA-262, section 11.9.4, page 56. |
100 function STRICT_EQUALS(x) { | 100 function STRICT_EQUALS(x) { |
101 if (IS_NUMBER(this)) { | 101 if (IS_NUMBER(this)) { |
102 if (!IS_NUMBER(x)) return 1; // not equal | 102 if (!IS_NUMBER(x)) return 1; // not equal |
103 return %NumberEquals(this, x); | 103 return %NumberEquals(this, x); |
104 } | 104 } |
105 | 105 |
106 if (IS_STRING(this)) { | 106 if (IS_STRING(this)) { |
107 if (!IS_STRING(x)) return 1; // not equal | 107 if (!IS_STRING(x)) return 1; // not equal |
108 return %StringEquals(this, x); | 108 return %StringEquals(this, x); |
109 } | 109 } |
110 | 110 |
111 if (IS_BOOLEAN(this)) { | 111 if (IS_BOOLEAN(this)) { |
112 if (!IS_BOOLEAN(x)) return 1; // not equal | 112 if (!IS_BOOLEAN(x)) return 1; // not equal |
113 if (this) return x ? 0 : 1; | 113 if (this) return x ? 0 : 1; |
114 else return x ? 1 : 0; | 114 else return x ? 1 : 0; |
115 } | 115 } |
116 | 116 |
117 if (IS_UNDEFINED(this)) { // both undefined and undetectable | 117 if (IS_UNDEFINED(this)) { // both undefined and undetectable |
118 return IS_UNDEFINED(x) ? 0 : 1; | 118 return IS_UNDEFINED(x) ? 0 : 1; |
119 } | 119 } |
120 | 120 |
121 return %_ObjectEquals(this, x) ? 0 : 1; | 121 return %_ObjectEquals(this, x) ? 0 : 1; |
122 }; | 122 } |
123 | 123 |
124 | 124 |
125 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as | 125 // ECMA-262, section 11.8.5, page 53. The 'ncr' parameter is used as |
126 // the result when either (or both) the operands are NaN. | 126 // the result when either (or both) the operands are NaN. |
127 function COMPARE(x, ncr) { | 127 function COMPARE(x, ncr) { |
128 // Improve performance for floating point compares | 128 // Improve performance for floating point compares |
129 if (IS_NUMBER(this) && IS_NUMBER(x)) { | 129 if (IS_NUMBER(this) && IS_NUMBER(x)) { |
130 return %NumberCompare(this, x, ncr); | 130 return %NumberCompare(this, x, ncr); |
131 } | 131 } |
132 | 132 |
133 var a = %ToPrimitive(this, NUMBER_HINT); | 133 var a = %ToPrimitive(this, NUMBER_HINT); |
134 var b = %ToPrimitive(x, NUMBER_HINT); | 134 var b = %ToPrimitive(x, NUMBER_HINT); |
135 if (IS_STRING(a) && IS_STRING(b)) { | 135 if (IS_STRING(a) && IS_STRING(b)) { |
136 return %StringCompare(a, b); | 136 return %StringCompare(a, b); |
137 } else { | 137 } else { |
138 return %NumberCompare(%ToNumber(a), %ToNumber(b), ncr); | 138 return %NumberCompare(%ToNumber(a), %ToNumber(b), ncr); |
139 } | 139 } |
140 }; | 140 } |
141 | 141 |
142 | 142 |
143 | 143 |
144 /* ----------------------------------- | 144 /* ----------------------------------- |
145 - - - A r i t h m e t i c - - - | 145 - - - A r i t h m e t i c - - - |
146 ----------------------------------- | 146 ----------------------------------- |
147 */ | 147 */ |
148 | 148 |
149 // ECMA-262, section 11.6.1, page 50. | 149 // ECMA-262, section 11.6.1, page 50. |
150 function ADD(x) { | 150 function ADD(x) { |
151 // Fast case: Check for number operands and do the addition. | 151 // Fast case: Check for number operands and do the addition. |
152 if (IS_NUMBER(this) && IS_NUMBER(x)) { | 152 if (IS_NUMBER(this) && IS_NUMBER(x)) { |
153 return %NumberAdd(this, x); | 153 return %NumberAdd(this, x); |
154 } | 154 } |
155 | 155 |
156 var a = %ToPrimitive(this, NO_HINT); | 156 var a = %ToPrimitive(this, NO_HINT); |
157 var b = %ToPrimitive(x, NO_HINT); | 157 var b = %ToPrimitive(x, NO_HINT); |
158 | 158 |
159 if (IS_STRING(a)) { | 159 if (IS_STRING(a)) { |
160 return %StringAdd(a, %ToString(b)); | 160 return %StringAdd(a, %ToString(b)); |
161 } else if (IS_STRING(b)) { | 161 } else if (IS_STRING(b)) { |
162 return %StringAdd(%ToString(a), b); | 162 return %StringAdd(%ToString(a), b); |
163 } else { | 163 } else { |
164 return %NumberAdd(%ToNumber(a), %ToNumber(b)); | 164 return %NumberAdd(%ToNumber(a), %ToNumber(b)); |
165 } | 165 } |
166 }; | 166 } |
167 | 167 |
168 | 168 |
169 // ECMA-262, section 11.6.2, page 50. | 169 // ECMA-262, section 11.6.2, page 50. |
170 function SUB(x) { | 170 function SUB(x) { |
171 return %NumberSub(%ToNumber(this), %ToNumber(x)); | 171 return %NumberSub(%ToNumber(this), %ToNumber(x)); |
172 }; | 172 } |
173 | 173 |
174 | 174 |
175 // ECMA-262, section 11.5.1, page 48. | 175 // ECMA-262, section 11.5.1, page 48. |
176 function MUL(x) { | 176 function MUL(x) { |
177 return %NumberMul(%ToNumber(this), %ToNumber(x)); | 177 return %NumberMul(%ToNumber(this), %ToNumber(x)); |
178 }; | 178 } |
179 | 179 |
180 | 180 |
181 // ECMA-262, section 11.5.2, page 49. | 181 // ECMA-262, section 11.5.2, page 49. |
182 function DIV(x) { | 182 function DIV(x) { |
183 return %NumberDiv(%ToNumber(this), %ToNumber(x)); | 183 return %NumberDiv(%ToNumber(this), %ToNumber(x)); |
184 }; | 184 } |
185 | 185 |
186 | 186 |
187 // ECMA-262, section 11.5.3, page 49. | 187 // ECMA-262, section 11.5.3, page 49. |
188 function MOD(x) { | 188 function MOD(x) { |
189 return %NumberMod(%ToNumber(this), %ToNumber(x)); | 189 return %NumberMod(%ToNumber(this), %ToNumber(x)); |
190 }; | 190 } |
191 | 191 |
192 | 192 |
193 // ECMA-262, section 11.4.4, page 47. | 193 // ECMA-262, section 11.4.4, page 47. |
194 function INC() { | 194 function INC() { |
195 return %NumberAdd(%ToNumber(this), 1); | 195 return %NumberAdd(%ToNumber(this), 1); |
196 }; | 196 } |
197 | 197 |
198 | 198 |
199 // ECMA-262, section 11.4.5, page 48. | 199 // ECMA-262, section 11.4.5, page 48. |
200 function DEC() { | 200 function DEC() { |
201 return %NumberSub(%ToNumber(this), 1); | 201 return %NumberSub(%ToNumber(this), 1); |
202 }; | 202 } |
203 | 203 |
204 | 204 |
205 | 205 |
206 /* ------------------------------------------- | 206 /* ------------------------------------------- |
207 - - - B i t o p e r a t i o n s - - - | 207 - - - B i t o p e r a t i o n s - - - |
208 ------------------------------------------- | 208 ------------------------------------------- |
209 */ | 209 */ |
210 | 210 |
211 // ECMA-262, section 11.10, page 57. | 211 // ECMA-262, section 11.10, page 57. |
212 function BIT_OR(x) { | 212 function BIT_OR(x) { |
213 return %NumberOr(%ToNumber(this), %ToNumber(x)); | 213 return %NumberOr(%ToNumber(this), %ToNumber(x)); |
214 }; | 214 } |
215 | 215 |
216 | 216 |
217 // ECMA-262, section 11.10, page 57. | 217 // ECMA-262, section 11.10, page 57. |
218 function BIT_AND(x) { | 218 function BIT_AND(x) { |
219 return %NumberAnd(%ToNumber(this), %ToNumber(x)); | 219 return %NumberAnd(%ToNumber(this), %ToNumber(x)); |
220 }; | 220 } |
221 | 221 |
222 | 222 |
223 // ECMA-262, section 11.10, page 57. | 223 // ECMA-262, section 11.10, page 57. |
224 function BIT_XOR(x) { | 224 function BIT_XOR(x) { |
225 return %NumberXor(%ToNumber(this), %ToNumber(x)); | 225 return %NumberXor(%ToNumber(this), %ToNumber(x)); |
226 }; | 226 } |
227 | 227 |
228 | 228 |
229 // ECMA-262, section 11.4.7, page 47. | 229 // ECMA-262, section 11.4.7, page 47. |
230 function UNARY_MINUS() { | 230 function UNARY_MINUS() { |
231 return %NumberUnaryMinus(%ToNumber(this)); | 231 return %NumberUnaryMinus(%ToNumber(this)); |
232 }; | 232 } |
233 | 233 |
234 | 234 |
235 // ECMA-262, section 11.4.8, page 48. | 235 // ECMA-262, section 11.4.8, page 48. |
236 function BIT_NOT() { | 236 function BIT_NOT() { |
237 return %NumberNot(%ToNumber(this)); | 237 return %NumberNot(%ToNumber(this)); |
238 }; | 238 } |
239 | 239 |
240 | 240 |
241 // ECMA-262, section 11.7.1, page 51. | 241 // ECMA-262, section 11.7.1, page 51. |
242 function SHL(x) { | 242 function SHL(x) { |
243 return %NumberShl(%ToNumber(this), %ToNumber(x)); | 243 return %NumberShl(%ToNumber(this), %ToNumber(x)); |
244 }; | 244 } |
245 | 245 |
246 | 246 |
247 // ECMA-262, section 11.7.2, page 51. | 247 // ECMA-262, section 11.7.2, page 51. |
248 function SAR(x) { | 248 function SAR(x) { |
249 return %NumberSar(%ToNumber(this), %ToNumber(x)); | 249 return %NumberSar(%ToNumber(this), %ToNumber(x)); |
250 }; | 250 } |
251 | 251 |
252 | 252 |
253 // ECMA-262, section 11.7.3, page 52. | 253 // ECMA-262, section 11.7.3, page 52. |
254 function SHR(x) { | 254 function SHR(x) { |
255 return %NumberShr(%ToNumber(this), %ToNumber(x)); | 255 return %NumberShr(%ToNumber(this), %ToNumber(x)); |
256 }; | 256 } |
257 | 257 |
258 | 258 |
259 | 259 |
260 /* ----------------------------- | 260 /* ----------------------------- |
261 - - - H e l p e r s - - - | 261 - - - H e l p e r s - - - |
262 ----------------------------- | 262 ----------------------------- |
263 */ | 263 */ |
264 | 264 |
265 // ECMA-262, section 11.4.1, page 46. | 265 // ECMA-262, section 11.4.1, page 46. |
266 function DELETE(key) { | 266 function DELETE(key) { |
267 return %DeleteProperty(%ToObject(this), %ToString(key)); | 267 return %DeleteProperty(%ToObject(this), %ToString(key)); |
268 }; | 268 } |
269 | 269 |
270 | 270 |
271 // ECMA-262, section 11.8.7, page 54. | 271 // ECMA-262, section 11.8.7, page 54. |
272 function IN(x) { | 272 function IN(x) { |
273 if (x == null || (!IS_OBJECT(x) && !IS_FUNCTION(x))) { | 273 if (x == null || (!IS_OBJECT(x) && !IS_FUNCTION(x))) { |
274 throw %MakeTypeError('invalid_in_operator_use', [this, x]); | 274 throw %MakeTypeError('invalid_in_operator_use', [this, x]); |
275 } | 275 } |
276 return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToSt
ring(this)); | 276 return %_IsNonNegativeSmi(this) ? %HasElement(x, this) : %HasProperty(x, %ToSt
ring(this)); |
277 }; | 277 } |
278 | 278 |
279 | 279 |
280 // ECMA-262, section 11.8.6, page 54. | 280 // ECMA-262, section 11.8.6, page 54. |
281 function INSTANCE_OF(F) { | 281 function INSTANCE_OF(F) { |
282 var V = this; | 282 var V = this; |
283 if (!IS_FUNCTION(F)) { | 283 if (!IS_FUNCTION(F)) { |
284 throw %MakeTypeError('instanceof_function_expected', [V]); | 284 throw %MakeTypeError('instanceof_function_expected', [V]); |
285 } | 285 } |
286 | 286 |
287 // If V is not an object, return false. | 287 // If V is not an object, return false. |
288 if (IS_NULL(V) || (!IS_OBJECT(V) && !IS_FUNCTION(V))) { | 288 if (IS_NULL(V) || (!IS_OBJECT(V) && !IS_FUNCTION(V))) { |
289 return false; | 289 return false; |
290 } | 290 } |
291 | 291 |
292 // Get the prototype of F; if it is not an object, throw an error. | 292 // Get the prototype of F; if it is not an object, throw an error. |
293 var O = F.prototype; | 293 var O = F.prototype; |
294 if (IS_NULL(O) || (!IS_OBJECT(O) && !IS_FUNCTION(O))) { | 294 if (IS_NULL(O) || (!IS_OBJECT(O) && !IS_FUNCTION(O))) { |
295 throw %MakeTypeError('instanceof_nonobject_proto', [O]); | 295 throw %MakeTypeError('instanceof_nonobject_proto', [O]); |
296 } | 296 } |
297 | 297 |
298 // Return whether or not O is in the prototype chain of V. | 298 // Return whether or not O is in the prototype chain of V. |
299 return %IsInPrototypeChain(O, V); | 299 return %IsInPrototypeChain(O, V); |
300 }; | 300 } |
301 | 301 |
302 | 302 |
303 // Get an array of property keys for the given object. Used in | 303 // Get an array of property keys for the given object. Used in |
304 // for-in statements. | 304 // for-in statements. |
305 function GET_KEYS() { | 305 function GET_KEYS() { |
306 return %GetPropertyNames(this); | 306 return %GetPropertyNames(this); |
307 }; | 307 } |
308 | 308 |
309 | 309 |
310 // Filter a given key against an object by checking if the object | 310 // Filter a given key against an object by checking if the object |
311 // has a property with the given key; return the key as a string if | 311 // has a property with the given key; return the key as a string if |
312 // it has. Otherwise returns null. Used in for-in statements. | 312 // it has. Otherwise returns null. Used in for-in statements. |
313 function FILTER_KEY(key) { | 313 function FILTER_KEY(key) { |
314 var string = %ToString(key); | 314 var string = %ToString(key); |
315 if (%HasProperty(this, string)) return string; | 315 if (%HasProperty(this, string)) return string; |
316 return null; | 316 return null; |
317 }; | 317 } |
318 | 318 |
319 | 319 |
320 function CALL_NON_FUNCTION() { | 320 function CALL_NON_FUNCTION() { |
321 var callee = %GetCalledFunction(); | 321 var callee = %GetCalledFunction(); |
322 var delegate = %GetFunctionDelegate(callee); | 322 var delegate = %GetFunctionDelegate(callee); |
323 if (!IS_FUNCTION(delegate)) { | 323 if (!IS_FUNCTION(delegate)) { |
324 throw %MakeTypeError('called_non_callable', [typeof callee]); | 324 throw %MakeTypeError('called_non_callable', [typeof callee]); |
325 } | 325 } |
326 | 326 |
327 var parameters = %NewArguments(delegate); | 327 var parameters = %NewArguments(delegate); |
328 return delegate.apply(callee, parameters); | 328 return delegate.apply(callee, parameters); |
329 }; | 329 } |
330 | 330 |
331 | 331 |
332 function APPLY_PREPARE(args) { | 332 function APPLY_PREPARE(args) { |
333 var length; | 333 var length; |
334 // First check whether length is a positive Smi and args is an array. This is
the | 334 // First check whether length is a positive Smi and args is an array. This is
the |
335 // fast case. If this fails, we do the slow case that takes care of more even
tualities | 335 // fast case. If this fails, we do the slow case that takes care of more even
tualities |
336 if (%_IsArray(args)) { | 336 if (%_IsArray(args)) { |
337 length = args.length; | 337 length = args.length; |
338 if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)
) { | 338 if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)
) { |
339 return length; | 339 return length; |
(...skipping 16 matching lines...) Expand all Loading... |
356 // Make sure the arguments list has the right type. | 356 // Make sure the arguments list has the right type. |
357 if (args != null && | 357 if (args != null && |
358 %ClassOf(args) != 'Array' && | 358 %ClassOf(args) != 'Array' && |
359 %ClassOf(args) != 'Arguments') { | 359 %ClassOf(args) != 'Arguments') { |
360 throw %MakeTypeError('apply_wrong_args', []); | 360 throw %MakeTypeError('apply_wrong_args', []); |
361 } | 361 } |
362 | 362 |
363 // Return the length which is the number of arguments to copy to the | 363 // Return the length which is the number of arguments to copy to the |
364 // stack. It is guaranteed to be a small integer at this point. | 364 // stack. It is guaranteed to be a small integer at this point. |
365 return length; | 365 return length; |
366 }; | 366 } |
367 | 367 |
368 | 368 |
369 function APPLY_OVERFLOW(length) { | 369 function APPLY_OVERFLOW(length) { |
370 throw %MakeRangeError('apply_overflow', [length]); | 370 throw %MakeRangeError('apply_overflow', [length]); |
371 }; | 371 } |
372 | 372 |
373 | 373 |
374 // Convert the receiver to an object - forward to ToObject. | 374 // Convert the receiver to an object - forward to ToObject. |
375 function TO_OBJECT() { | 375 function TO_OBJECT() { |
376 return %ToObject(this); | 376 return %ToObject(this); |
377 }; | 377 } |
378 | 378 |
379 | 379 |
380 // Convert the receiver to a number - forward to ToNumber. | 380 // Convert the receiver to a number - forward to ToNumber. |
381 function TO_NUMBER() { | 381 function TO_NUMBER() { |
382 return %ToNumber(this); | 382 return %ToNumber(this); |
383 }; | 383 } |
384 | 384 |
385 | 385 |
386 // Convert the receiver to a string - forward to ToString. | 386 // Convert the receiver to a string - forward to ToString. |
387 function TO_STRING() { | 387 function TO_STRING() { |
388 return %ToString(this); | 388 return %ToString(this); |
389 }; | 389 } |
390 | 390 |
391 | 391 |
392 /* ------------------------------------- | 392 /* ------------------------------------- |
393 - - - C o n v e r s i o n s - - - | 393 - - - C o n v e r s i o n s - - - |
394 ------------------------------------- | 394 ------------------------------------- |
395 */ | 395 */ |
396 | 396 |
397 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint, | 397 // ECMA-262, section 9.1, page 30. Use null/undefined for no hint, |
398 // (1) for number hint, and (2) for string hint. | 398 // (1) for number hint, and (2) for string hint. |
399 function ToPrimitive(x, hint) { | 399 function ToPrimitive(x, hint) { |
400 if (!IS_OBJECT(x) && !IS_FUNCTION(x)) return x; | 400 if (!IS_OBJECT(x) && !IS_FUNCTION(x)) return x; |
401 if (x == null) return x; // check for null, undefined | 401 if (x == null) return x; // check for null, undefined |
402 if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT; | 402 if (hint == NO_HINT) hint = (IS_DATE(x)) ? STRING_HINT : NUMBER_HINT; |
403 return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x); | 403 return (hint == NUMBER_HINT) ? %DefaultNumber(x) : %DefaultString(x); |
404 }; | 404 } |
405 | 405 |
406 | 406 |
407 // ECMA-262, section 9.3, page 31. | 407 // ECMA-262, section 9.3, page 31. |
408 function ToNumber(x) { | 408 function ToNumber(x) { |
409 if (IS_NUMBER(x)) return x; | 409 if (IS_NUMBER(x)) return x; |
410 if (IS_STRING(x)) return %StringToNumber(x); | 410 if (IS_STRING(x)) return %StringToNumber(x); |
411 if (IS_BOOLEAN(x)) return x ? 1 : 0; | 411 if (IS_BOOLEAN(x)) return x ? 1 : 0; |
412 if (IS_UNDEFINED(x)) return $NaN; | 412 if (IS_UNDEFINED(x)) return $NaN; |
413 return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); | 413 return (IS_NULL(x)) ? 0 : ToNumber(%DefaultNumber(x)); |
414 }; | 414 } |
415 | 415 |
416 | 416 |
417 // ECMA-262, section 9.8, page 35. | 417 // ECMA-262, section 9.8, page 35. |
418 function ToString(x) { | 418 function ToString(x) { |
419 if (IS_STRING(x)) return x; | 419 if (IS_STRING(x)) return x; |
420 if (IS_NUMBER(x)) return %NumberToString(x); | 420 if (IS_NUMBER(x)) return %NumberToString(x); |
421 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; | 421 if (IS_BOOLEAN(x)) return x ? 'true' : 'false'; |
422 if (IS_UNDEFINED(x)) return 'undefined'; | 422 if (IS_UNDEFINED(x)) return 'undefined'; |
423 return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); | 423 return (IS_NULL(x)) ? 'null' : %ToString(%DefaultString(x)); |
424 }; | 424 } |
425 | 425 |
426 | 426 |
427 // ... where did this come from? | 427 // ... where did this come from? |
428 function ToBoolean(x) { | 428 function ToBoolean(x) { |
429 if (IS_BOOLEAN(x)) return x; | 429 if (IS_BOOLEAN(x)) return x; |
430 if (IS_STRING(x)) return x.length != 0; | 430 if (IS_STRING(x)) return x.length != 0; |
431 if (x == null) return false; | 431 if (x == null) return false; |
432 if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x)); | 432 if (IS_NUMBER(x)) return !((x == 0) || NUMBER_IS_NAN(x)); |
433 return true; | 433 return true; |
434 }; | 434 } |
435 | 435 |
436 | 436 |
437 // ECMA-262, section 9.9, page 36. | 437 // ECMA-262, section 9.9, page 36. |
438 function ToObject(x) { | 438 function ToObject(x) { |
439 if (IS_STRING(x)) return new $String(x); | 439 if (IS_STRING(x)) return new $String(x); |
440 if (IS_NUMBER(x)) return new $Number(x); | 440 if (IS_NUMBER(x)) return new $Number(x); |
441 if (IS_BOOLEAN(x)) return new $Boolean(x); | 441 if (IS_BOOLEAN(x)) return new $Boolean(x); |
442 if (x == null) throw %MakeTypeError('null_to_object', []); | 442 if (x == null) throw %MakeTypeError('null_to_object', []); |
443 return x; | 443 return x; |
444 }; | 444 } |
445 | 445 |
446 | 446 |
447 // ECMA-262, section 9.4, page 34. | 447 // ECMA-262, section 9.4, page 34. |
448 function ToInteger(x) { | 448 function ToInteger(x) { |
449 if (%_IsSmi(x)) return x; | 449 if (%_IsSmi(x)) return x; |
450 return %NumberToInteger(ToNumber(x)); | 450 return %NumberToInteger(ToNumber(x)); |
451 }; | 451 } |
452 | 452 |
453 | 453 |
454 // ECMA-262, section 9.6, page 34. | 454 // ECMA-262, section 9.6, page 34. |
455 function ToUint32(x) { | 455 function ToUint32(x) { |
456 if (%_IsSmi(x) && x >= 0) return x; | 456 if (%_IsSmi(x) && x >= 0) return x; |
457 return %NumberToJSUint32(ToNumber(x)); | 457 return %NumberToJSUint32(ToNumber(x)); |
458 }; | 458 } |
459 | 459 |
460 | 460 |
461 // ECMA-262, section 9.5, page 34 | 461 // ECMA-262, section 9.5, page 34 |
462 function ToInt32(x) { | 462 function ToInt32(x) { |
463 if (%_IsSmi(x)) return x; | 463 if (%_IsSmi(x)) return x; |
464 return %NumberToJSInt32(ToNumber(x)); | 464 return %NumberToJSInt32(ToNumber(x)); |
465 }; | 465 } |
466 | 466 |
467 | 467 |
468 | 468 |
469 /* --------------------------------- | 469 /* --------------------------------- |
470 - - - U t i l i t i e s - - - | 470 - - - U t i l i t i e s - - - |
471 --------------------------------- | 471 --------------------------------- |
472 */ | 472 */ |
473 | 473 |
474 // Returns if the given x is a primitive value - not an object or a | 474 // Returns if the given x is a primitive value - not an object or a |
475 // function. | 475 // function. |
476 function IsPrimitive(x) { | 476 function IsPrimitive(x) { |
477 if (!IS_OBJECT(x) && !IS_FUNCTION(x)) { | 477 if (!IS_OBJECT(x) && !IS_FUNCTION(x)) { |
478 return true; | 478 return true; |
479 } else { | 479 } else { |
480 // Even though the type of null is "object", null is still | 480 // Even though the type of null is "object", null is still |
481 // considered a primitive value. | 481 // considered a primitive value. |
482 return IS_NULL(x); | 482 return IS_NULL(x); |
483 } | 483 } |
484 }; | 484 } |
485 | 485 |
486 | 486 |
487 // ECMA-262, section 8.6.2.6, page 28. | 487 // ECMA-262, section 8.6.2.6, page 28. |
488 function DefaultNumber(x) { | 488 function DefaultNumber(x) { |
489 if (IS_FUNCTION(x.valueOf)) { | 489 if (IS_FUNCTION(x.valueOf)) { |
490 var v = x.valueOf(); | 490 var v = x.valueOf(); |
491 if (%IsPrimitive(v)) return v; | 491 if (%IsPrimitive(v)) return v; |
492 } | 492 } |
493 | 493 |
494 if (IS_FUNCTION(x.toString)) { | 494 if (IS_FUNCTION(x.toString)) { |
495 var s = x.toString(); | 495 var s = x.toString(); |
496 if (%IsPrimitive(s)) return s; | 496 if (%IsPrimitive(s)) return s; |
497 } | 497 } |
498 | 498 |
499 throw %MakeTypeError('cannot_convert_to_primitive', []); | 499 throw %MakeTypeError('cannot_convert_to_primitive', []); |
500 }; | 500 } |
501 | 501 |
502 | 502 |
503 // ECMA-262, section 8.6.2.6, page 28. | 503 // ECMA-262, section 8.6.2.6, page 28. |
504 function DefaultString(x) { | 504 function DefaultString(x) { |
505 if (IS_FUNCTION(x.toString)) { | 505 if (IS_FUNCTION(x.toString)) { |
506 var s = x.toString(); | 506 var s = x.toString(); |
507 if (%IsPrimitive(s)) return s; | 507 if (%IsPrimitive(s)) return s; |
508 } | 508 } |
509 | 509 |
510 if (IS_FUNCTION(x.valueOf)) { | 510 if (IS_FUNCTION(x.valueOf)) { |
511 var v = x.valueOf(); | 511 var v = x.valueOf(); |
512 if (%IsPrimitive(v)) return v; | 512 if (%IsPrimitive(v)) return v; |
513 } | 513 } |
514 | 514 |
515 throw %MakeTypeError('cannot_convert_to_primitive', []); | 515 throw %MakeTypeError('cannot_convert_to_primitive', []); |
516 }; | 516 } |
517 | 517 |
518 | 518 |
519 // NOTE: Setting the prototype for Array must take place as early as | 519 // NOTE: Setting the prototype for Array must take place as early as |
520 // possible due to code generation for array literals. When | 520 // possible due to code generation for array literals. When |
521 // generating code for a array literal a boilerplate array is created | 521 // generating code for a array literal a boilerplate array is created |
522 // that is cloned when running the code. It is essiential that the | 522 // that is cloned when running the code. It is essiential that the |
523 // boilerplate gets the right prototype. | 523 // boilerplate gets the right prototype. |
524 %FunctionSetPrototype($Array, new $Array(0)); | 524 %FunctionSetPrototype($Array, new $Array(0)); |
OLD | NEW |