| 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 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This files contains runtime support implemented in JavaScript. | 5 // This files contains runtime support implemented in JavaScript. |
| 6 | 6 |
| 7 // CAUTION: Some of the functions specified in this file are called | 7 // CAUTION: Some of the functions specified in this file are called |
| 8 // directly from compiled code. These are the functions with names in | 8 // directly from compiled code. These are the functions with names in |
| 9 // ALL CAPS. The compiled code passes the first argument in 'this'. | 9 // ALL CAPS. The compiled code passes the first argument in 'this'. |
| 10 | 10 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 if (IS_STRING(a)) { | 153 if (IS_STRING(a)) { |
| 154 return %_StringAdd(a, %ToString(b)); | 154 return %_StringAdd(a, %ToString(b)); |
| 155 } else if (IS_STRING(b)) { | 155 } else if (IS_STRING(b)) { |
| 156 return %_StringAdd(%NonStringToString(a), b); | 156 return %_StringAdd(%NonStringToString(a), b); |
| 157 } else { | 157 } else { |
| 158 return %NumberAdd(%ToNumber(a), %ToNumber(b)); | 158 return %NumberAdd(%ToNumber(a), %ToNumber(b)); |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 | 162 |
| 163 // Strong mode ADD throws if an implicit conversion would be performed |
| 164 function ADD_STRONG(x) { |
| 165 if (IS_NUMBER(this) && IS_NUMBER(x)) return %NumberAdd(this, x); |
| 166 if (IS_STRING(this) && IS_STRING(x)) return %_StringAdd(this, x); |
| 167 |
| 168 throw %MakeTypeError('strong_implicit_cast'); |
| 169 } |
| 170 |
| 171 |
| 163 // Left operand (this) is already a string. | 172 // Left operand (this) is already a string. |
| 164 function STRING_ADD_LEFT(y) { | 173 function STRING_ADD_LEFT(y) { |
| 165 if (!IS_STRING(y)) { | 174 if (!IS_STRING(y)) { |
| 166 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { | 175 if (IS_STRING_WRAPPER(y) && %_IsStringWrapperSafeForDefaultValueOf(y)) { |
| 167 y = %_ValueOf(y); | 176 y = %_ValueOf(y); |
| 168 } else { | 177 } else { |
| 169 y = IS_NUMBER(y) | 178 y = IS_NUMBER(y) |
| 170 ? %_NumberToString(y) | 179 ? %_NumberToString(y) |
| 171 : %ToString(%ToPrimitive(y, NO_HINT)); | 180 : %ToString(%ToPrimitive(y, NO_HINT)); |
| 172 } | 181 } |
| 173 } | 182 } |
| 174 return %_StringAdd(this, y); | 183 return %_StringAdd(this, y); |
| 175 } | 184 } |
| 176 | 185 |
| 177 | 186 |
| 187 // Left operand (this) is already a string. |
| 188 function STRING_ADD_LEFT_STRONG(y) { |
| 189 if (IS_STRING(y)) { |
| 190 return %_StringAdd(this, y); |
| 191 } |
| 192 throw %MakeTypeError('strong_implicit_cast'); |
| 193 } |
| 194 |
| 195 |
| 178 // Right operand (y) is already a string. | 196 // Right operand (y) is already a string. |
| 179 function STRING_ADD_RIGHT(y) { | 197 function STRING_ADD_RIGHT(y) { |
| 180 var x = this; | 198 var x = this; |
| 181 if (!IS_STRING(x)) { | 199 if (!IS_STRING(x)) { |
| 182 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { | 200 if (IS_STRING_WRAPPER(x) && %_IsStringWrapperSafeForDefaultValueOf(x)) { |
| 183 x = %_ValueOf(x); | 201 x = %_ValueOf(x); |
| 184 } else { | 202 } else { |
| 185 x = IS_NUMBER(x) | 203 x = IS_NUMBER(x) |
| 186 ? %_NumberToString(x) | 204 ? %_NumberToString(x) |
| 187 : %ToString(%ToPrimitive(x, NO_HINT)); | 205 : %ToString(%ToPrimitive(x, NO_HINT)); |
| 188 } | 206 } |
| 189 } | 207 } |
| 190 return %_StringAdd(x, y); | 208 return %_StringAdd(x, y); |
| 191 } | 209 } |
| 192 | 210 |
| 193 | 211 |
| 212 // Right operand (y) is already a string. |
| 213 function STRING_ADD_RIGHT_STRONG(y) { |
| 214 if (IS_STRING(this)) { |
| 215 return %_StringAdd(this, y); |
| 216 } |
| 217 throw %MakeTypeError('strong_implicit_cast'); |
| 218 } |
| 219 |
| 220 |
| 194 // ECMA-262, section 11.6.2, page 50. | 221 // ECMA-262, section 11.6.2, page 50. |
| 195 function SUB(y) { | 222 function SUB(y) { |
| 196 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 223 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 197 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 224 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 198 return %NumberSub(x, y); | 225 return %NumberSub(x, y); |
| 199 } | 226 } |
| 200 | 227 |
| 201 | 228 |
| 202 // ECMA-262, section 11.6.2, page 50. | 229 // Strong mode SUB throws if an implicit conversion would be performed |
| 203 function SUB_STRONG(y) { | 230 function SUB_STRONG(y) { |
| 204 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 231 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 205 return %NumberSub(this, y); | 232 return %NumberSub(this, y); |
| 206 } | 233 } |
| 207 throw %MakeTypeError('strong_implicit_cast'); | 234 throw %MakeTypeError('strong_implicit_cast'); |
| 208 } | 235 } |
| 209 | 236 |
| 210 | 237 |
| 211 // ECMA-262, section 11.5.1, page 48. | 238 // ECMA-262, section 11.5.1, page 48. |
| 212 function MUL(y) { | 239 function MUL(y) { |
| 213 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 240 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 214 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 241 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 215 return %NumberMul(x, y); | 242 return %NumberMul(x, y); |
| 216 } | 243 } |
| 217 | 244 |
| 218 | 245 |
| 219 // ECMA-262, section 11.5.1, page 48. | 246 // Strong mode MUL throws if an implicit conversion would be performed |
| 220 function MUL_STRONG(y) { | 247 function MUL_STRONG(y) { |
| 221 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 248 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 222 return %NumberMul(this, y); | 249 return %NumberMul(this, y); |
| 223 } | 250 } |
| 224 throw %MakeTypeError('strong_implicit_cast'); | 251 throw %MakeTypeError('strong_implicit_cast'); |
| 225 } | 252 } |
| 226 | 253 |
| 227 | 254 |
| 228 // ECMA-262, section 11.5.2, page 49. | 255 // ECMA-262, section 11.5.2, page 49. |
| 229 function DIV(y) { | 256 function DIV(y) { |
| 230 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 257 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 231 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 258 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 232 return %NumberDiv(x, y); | 259 return %NumberDiv(x, y); |
| 233 } | 260 } |
| 234 | 261 |
| 235 | 262 |
| 236 // ECMA-262, section 11.5.2, page 49. | 263 // Strong mode DIV throws if an implicit conversion would be performed |
| 237 function DIV_STRONG(y) { | 264 function DIV_STRONG(y) { |
| 238 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 265 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 239 return %NumberDiv(this, y); | 266 return %NumberDiv(this, y); |
| 240 } | 267 } |
| 241 throw %MakeTypeError('strong_implicit_cast'); | 268 throw %MakeTypeError('strong_implicit_cast'); |
| 242 } | 269 } |
| 243 | 270 |
| 244 | 271 |
| 245 // ECMA-262, section 11.5.3, page 49. | 272 // ECMA-262, section 11.5.3, page 49. |
| 246 function MOD(y) { | 273 function MOD(y) { |
| 247 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 274 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 248 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 275 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 249 return %NumberMod(x, y); | 276 return %NumberMod(x, y); |
| 250 } | 277 } |
| 251 | 278 |
| 252 | 279 |
| 253 // ECMA-262, section 11.5.3, page 49. | 280 // Strong mode MOD throws if an implicit conversion would be performed |
| 254 function MOD_STRONG(y) { | 281 function MOD_STRONG(y) { |
| 255 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 282 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 256 return %NumberMod(this, y); | 283 return %NumberMod(this, y); |
| 257 } | 284 } |
| 258 throw %MakeTypeError('strong_implicit_cast'); | 285 throw %MakeTypeError('strong_implicit_cast'); |
| 259 } | 286 } |
| 260 | 287 |
| 261 | 288 |
| 262 /* ------------------------------------------- | 289 /* ------------------------------------------- |
| 263 - - - B i t o p e r a t i o n s - - - | 290 - - - B i t o p e r a t i o n s - - - |
| 264 ------------------------------------------- | 291 ------------------------------------------- |
| 265 */ | 292 */ |
| 266 | 293 |
| 267 // ECMA-262, section 11.10, page 57. | 294 // ECMA-262, section 11.10, page 57. |
| 268 function BIT_OR(y) { | 295 function BIT_OR(y) { |
| 269 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 296 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 270 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 297 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 271 return %NumberOr(x, y); | 298 return %NumberOr(x, y); |
| 272 } | 299 } |
| 273 | 300 |
| 274 | 301 |
| 275 //ECMA-262, section 11.10, page 57. | 302 // Strong mode BIT_OR throws if an implicit conversion would be performed |
| 276 function BIT_OR_STRONG(y) { | 303 function BIT_OR_STRONG(y) { |
| 277 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 304 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 278 return %NumberOr(this, y); | 305 return %NumberOr(this, y); |
| 279 } | 306 } |
| 280 throw %MakeTypeError('strong_implicit_cast'); | 307 throw %MakeTypeError('strong_implicit_cast'); |
| 281 } | 308 } |
| 282 | 309 |
| 283 | 310 |
| 284 // ECMA-262, section 11.10, page 57. | 311 // ECMA-262, section 11.10, page 57. |
| 285 function BIT_AND(y) { | 312 function BIT_AND(y) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 296 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 323 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 297 // Optimize for the case where we end up AND'ing a value | 324 // Optimize for the case where we end up AND'ing a value |
| 298 // that doesn't convert to a number. This is common in | 325 // that doesn't convert to a number. This is common in |
| 299 // certain benchmarks. | 326 // certain benchmarks. |
| 300 if (NUMBER_IS_NAN(x)) return 0; | 327 if (NUMBER_IS_NAN(x)) return 0; |
| 301 } | 328 } |
| 302 return %NumberAnd(x, y); | 329 return %NumberAnd(x, y); |
| 303 } | 330 } |
| 304 | 331 |
| 305 | 332 |
| 306 //ECMA-262, section 11.10, page 57. | 333 // Strong mode BIT_AND throws if an implicit conversion would be performed |
| 307 function BIT_AND_STRONG(y) { | 334 function BIT_AND_STRONG(y) { |
| 308 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 335 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 309 return %NumberAnd(this, y); | 336 return %NumberAnd(this, y); |
| 310 } | 337 } |
| 311 throw %MakeTypeError('strong_implicit_cast'); | 338 throw %MakeTypeError('strong_implicit_cast'); |
| 312 } | 339 } |
| 313 | 340 |
| 314 | 341 |
| 315 // ECMA-262, section 11.10, page 57. | 342 // ECMA-262, section 11.10, page 57. |
| 316 function BIT_XOR(y) { | 343 function BIT_XOR(y) { |
| 317 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 344 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 318 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 345 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 319 return %NumberXor(x, y); | 346 return %NumberXor(x, y); |
| 320 } | 347 } |
| 321 | 348 |
| 322 | 349 |
| 323 //ECMA-262, section 11.10, page 57. | 350 // Strong mode BIT_XOR throws if an implicit conversion would be performed |
| 324 function BIT_XOR_STRONG(y) { | 351 function BIT_XOR_STRONG(y) { |
| 325 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 352 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 326 return %NumberXor(this, y); | 353 return %NumberXor(this, y); |
| 327 } | 354 } |
| 328 throw %MakeTypeError('strong_implicit_cast'); | 355 throw %MakeTypeError('strong_implicit_cast'); |
| 329 } | 356 } |
| 330 | 357 |
| 331 | 358 |
| 332 // ECMA-262, section 11.7.1, page 51. | 359 // ECMA-262, section 11.7.1, page 51. |
| 333 function SHL(y) { | 360 function SHL(y) { |
| 334 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 361 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 335 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 362 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 336 return %NumberShl(x, y); | 363 return %NumberShl(x, y); |
| 337 } | 364 } |
| 338 | 365 |
| 339 | 366 |
| 340 //ECMA-262, section 11.7.1, page 51. | 367 // Strong mode SHL throws if an implicit conversion would be performed |
| 341 function SHL_STRONG(y) { | 368 function SHL_STRONG(y) { |
| 342 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 369 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 343 return %NumberShl(this, y); | 370 return %NumberShl(this, y); |
| 344 } | 371 } |
| 345 throw %MakeTypeError('strong_implicit_cast'); | 372 throw %MakeTypeError('strong_implicit_cast'); |
| 346 } | 373 } |
| 347 | 374 |
| 348 | 375 |
| 349 // ECMA-262, section 11.7.2, page 51. | 376 // ECMA-262, section 11.7.2, page 51. |
| 350 function SAR(y) { | 377 function SAR(y) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 361 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 388 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 362 // Optimize for the case where we end up shifting a value | 389 // Optimize for the case where we end up shifting a value |
| 363 // that doesn't convert to a number. This is common in | 390 // that doesn't convert to a number. This is common in |
| 364 // certain benchmarks. | 391 // certain benchmarks. |
| 365 if (NUMBER_IS_NAN(x)) return 0; | 392 if (NUMBER_IS_NAN(x)) return 0; |
| 366 } | 393 } |
| 367 return %NumberSar(x, y); | 394 return %NumberSar(x, y); |
| 368 } | 395 } |
| 369 | 396 |
| 370 | 397 |
| 371 //ECMA-262, section 11.7.2, page 51. | 398 // Strong mode SAR throws if an implicit conversion would be performed |
| 372 function SAR_STRONG(y) { | 399 function SAR_STRONG(y) { |
| 373 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 400 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 374 return %NumberSar(this, y); | 401 return %NumberSar(this, y); |
| 375 } | 402 } |
| 376 throw %MakeTypeError('strong_implicit_cast'); | 403 throw %MakeTypeError('strong_implicit_cast'); |
| 377 } | 404 } |
| 378 | 405 |
| 379 | 406 |
| 380 // ECMA-262, section 11.7.3, page 52. | 407 // ECMA-262, section 11.7.3, page 52. |
| 381 function SHR(y) { | 408 function SHR(y) { |
| 382 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); | 409 var x = IS_NUMBER(this) ? this : %NonNumberToNumber(this); |
| 383 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); | 410 if (!IS_NUMBER(y)) y = %NonNumberToNumber(y); |
| 384 return %NumberShr(x, y); | 411 return %NumberShr(x, y); |
| 385 } | 412 } |
| 386 | 413 |
| 387 | 414 |
| 388 //ECMA-262, section 11.7.3, page 52. | 415 // Strong mode SHR throws if an implicit conversion would be performed |
| 389 function SHR_STRONG(y) { | 416 function SHR_STRONG(y) { |
| 390 if (IS_NUMBER(this) && IS_NUMBER(y)) { | 417 if (IS_NUMBER(this) && IS_NUMBER(y)) { |
| 391 return %NumberShr(this, y); | 418 return %NumberShr(this, y); |
| 392 } | 419 } |
| 393 throw %MakeTypeError('strong_implicit_cast'); | 420 throw %MakeTypeError('strong_implicit_cast'); |
| 394 } | 421 } |
| 395 | 422 |
| 396 | 423 |
| 397 /* ----------------------------- | 424 /* ----------------------------- |
| 398 - - - H e l p e r s - - - | 425 - - - H e l p e r s - - - |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 | 893 |
| 867 /* ----------------------------------------------- | 894 /* ----------------------------------------------- |
| 868 - - - J a v a S c r i p t S t u b s - - - | 895 - - - J a v a S c r i p t S t u b s - - - |
| 869 ----------------------------------------------- | 896 ----------------------------------------------- |
| 870 */ | 897 */ |
| 871 | 898 |
| 872 function STRING_LENGTH_STUB(name) { | 899 function STRING_LENGTH_STUB(name) { |
| 873 var receiver = this; // implicit first parameter | 900 var receiver = this; // implicit first parameter |
| 874 return %_StringGetLength(%_JSValueGetValue(receiver)); | 901 return %_StringGetLength(%_JSValueGetValue(receiver)); |
| 875 } | 902 } |
| OLD | NEW |