| 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 |