| 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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 %HasElement(x, this) : %HasProperty(x, %ToString(this)); | 358 %HasElement(x, this) : %HasProperty(x, %ToString(this)); |
| 359 } | 359 } |
| 360 | 360 |
| 361 | 361 |
| 362 // ECMA-262, section 11.8.6, page 54. To make the implementation more | 362 // ECMA-262, section 11.8.6, page 54. To make the implementation more |
| 363 // efficient, the return value should be zero if the 'this' is an | 363 // efficient, the return value should be zero if the 'this' is an |
| 364 // instance of F, and non-zero if not. This makes it possible to avoid | 364 // instance of F, and non-zero if not. This makes it possible to avoid |
| 365 // an expensive ToBoolean conversion in the generated code. | 365 // an expensive ToBoolean conversion in the generated code. |
| 366 function INSTANCE_OF(F) { | 366 function INSTANCE_OF(F) { |
| 367 var V = this; | 367 var V = this; |
| 368 if (!IS_FUNCTION(F)) { | 368 if (!IS_SPEC_FUNCTION(F)) { |
| 369 throw %MakeTypeError('instanceof_function_expected', [V]); | 369 throw %MakeTypeError('instanceof_function_expected', [V]); |
| 370 } | 370 } |
| 371 | 371 |
| 372 // If V is not an object, return false. | 372 // If V is not an object, return false. |
| 373 if (!IS_SPEC_OBJECT(V)) { | 373 if (!IS_SPEC_OBJECT(V)) { |
| 374 return 1; | 374 return 1; |
| 375 } | 375 } |
| 376 | 376 |
| 377 // Get the prototype of F; if it is not an object, throw an error. | 377 // Get the prototype of F; if it is not an object, throw an error. |
| 378 var O = F.prototype; | 378 var O = F.prototype; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 397 // it has. Otherwise returns 0 (smi). Used in for-in statements. | 397 // it has. Otherwise returns 0 (smi). Used in for-in statements. |
| 398 function FILTER_KEY(key) { | 398 function FILTER_KEY(key) { |
| 399 var string = %ToString(key); | 399 var string = %ToString(key); |
| 400 if (%HasProperty(this, string)) return string; | 400 if (%HasProperty(this, string)) return string; |
| 401 return 0; | 401 return 0; |
| 402 } | 402 } |
| 403 | 403 |
| 404 | 404 |
| 405 function CALL_NON_FUNCTION() { | 405 function CALL_NON_FUNCTION() { |
| 406 var delegate = %GetFunctionDelegate(this); | 406 var delegate = %GetFunctionDelegate(this); |
| 407 if (!IS_FUNCTION(delegate)) { | |
| 408 throw %MakeTypeError('called_non_callable', [typeof this]); | |
| 409 } | |
| 410 return delegate.apply(this, arguments); | 407 return delegate.apply(this, arguments); |
| 411 } | 408 } |
| 412 | 409 |
| 413 | 410 |
| 414 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { | 411 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { |
| 415 var delegate = %GetConstructorDelegate(this); | 412 var delegate = %GetConstructorDelegate(this); |
| 416 if (!IS_FUNCTION(delegate)) { | 413 return delegate.apply(this, arguments); |
| 417 throw %MakeTypeError('called_non_callable', [typeof this]); | 414 } |
| 415 |
| 416 |
| 417 function CALL_FUNCTION_PROXY() { |
| 418 var arity = %_ArgumentsLength() - 1; |
| 419 var proxy = %_Arguments(arity); // The proxy comes in as an additional arg. |
| 420 var trap = %GetCallTrap(proxy); |
| 421 return %Apply(trap, this, arguments, 0, arity); |
| 422 } |
| 423 |
| 424 |
| 425 function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR(proxy) { |
| 426 var arity = %_ArgumentsLength() - 1; |
| 427 var trap = %GetConstructTrap(proxy); |
| 428 var receiver = void 0; |
| 429 if (!IS_UNDEFINED(trap)) { |
| 430 trap = %GetCallTrap(proxy); |
| 431 var proto = proxy.prototype; |
| 432 if (!IS_SPEC_OBJECT(proto) && proto !== null) { |
| 433 throw MakeTypeError("proto_object_or_null", [proto]); |
| 434 } |
| 435 receiver = new global.Object(); |
| 436 receiver.__proto__ = proto; |
| 418 } | 437 } |
| 419 return delegate.apply(this, arguments); | 438 return %Apply(trap, this, arguments, 1, arity); |
| 420 } | 439 } |
| 421 | 440 |
| 422 | 441 |
| 423 function APPLY_PREPARE(args) { | 442 function APPLY_PREPARE(args) { |
| 424 var length; | 443 var length; |
| 425 // First check whether length is a positive Smi and args is an | 444 // First check whether length is a positive Smi and args is an |
| 426 // array. This is the fast case. If this fails, we do the slow case | 445 // array. This is the fast case. If this fails, we do the slow case |
| 427 // that takes care of more eventualities. | 446 // that takes care of more eventualities. |
| 428 if (IS_ARRAY(args)) { | 447 if (IS_ARRAY(args)) { |
| 429 length = args.length; | 448 length = args.length; |
| 430 if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this)
) { | 449 if (%_IsSmi(length) && length >= 0 && length < 0x800000 && |
| 450 IS_SPEC_FUNCTION(this)) { |
| 431 return length; | 451 return length; |
| 432 } | 452 } |
| 433 } | 453 } |
| 434 | 454 |
| 435 length = (args == null) ? 0 : %ToUint32(args.length); | 455 length = (args == null) ? 0 : %ToUint32(args.length); |
| 436 | 456 |
| 437 // We can handle any number of apply arguments if the stack is | 457 // We can handle any number of apply arguments if the stack is |
| 438 // big enough, but sanity check the value to avoid overflow when | 458 // big enough, but sanity check the value to avoid overflow when |
| 439 // multiplying with pointer size. | 459 // multiplying with pointer size. |
| 440 if (length > 0x800000) { | 460 if (length > 0x800000) { |
| 441 throw %MakeRangeError('stack_overflow', []); | 461 throw %MakeRangeError('stack_overflow', []); |
| 442 } | 462 } |
| 443 | 463 |
| 444 if (!IS_FUNCTION(this)) { | 464 if (!IS_SPEC_FUNCTION(this)) { |
| 445 throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ])
; | 465 throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ])
; |
| 446 } | 466 } |
| 447 | 467 |
| 448 // Make sure the arguments list has the right type. | 468 // Make sure the arguments list has the right type. |
| 449 if (args != null && !IS_ARRAY(args) && !IS_ARGUMENTS(args)) { | 469 if (args != null && !IS_ARRAY(args) && !IS_ARGUMENTS(args)) { |
| 450 throw %MakeTypeError('apply_wrong_args', []); | 470 throw %MakeTypeError('apply_wrong_args', []); |
| 451 } | 471 } |
| 452 | 472 |
| 453 // Return the length which is the number of arguments to copy to the | 473 // Return the length which is the number of arguments to copy to the |
| 454 // stack. It is guaranteed to be a small integer at this point. | 474 // stack. It is guaranteed to be a small integer at this point. |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 // Even though the type of null is "object", null is still | 622 // Even though the type of null is "object", null is still |
| 603 // considered a primitive value. IS_SPEC_OBJECT handles this correctly | 623 // considered a primitive value. IS_SPEC_OBJECT handles this correctly |
| 604 // (i.e., it will return false if x is null). | 624 // (i.e., it will return false if x is null). |
| 605 return !IS_SPEC_OBJECT(x); | 625 return !IS_SPEC_OBJECT(x); |
| 606 } | 626 } |
| 607 | 627 |
| 608 | 628 |
| 609 // ECMA-262, section 8.6.2.6, page 28. | 629 // ECMA-262, section 8.6.2.6, page 28. |
| 610 function DefaultNumber(x) { | 630 function DefaultNumber(x) { |
| 611 var valueOf = x.valueOf; | 631 var valueOf = x.valueOf; |
| 612 if (IS_FUNCTION(valueOf)) { | 632 if (IS_SPEC_FUNCTION(valueOf)) { |
| 613 var v = %_CallFunction(x, valueOf); | 633 var v = %_CallFunction(x, valueOf); |
| 614 if (%IsPrimitive(v)) return v; | 634 if (%IsPrimitive(v)) return v; |
| 615 } | 635 } |
| 616 | 636 |
| 617 var toString = x.toString; | 637 var toString = x.toString; |
| 618 if (IS_FUNCTION(toString)) { | 638 if (IS_SPEC_FUNCTION(toString)) { |
| 619 var s = %_CallFunction(x, toString); | 639 var s = %_CallFunction(x, toString); |
| 620 if (%IsPrimitive(s)) return s; | 640 if (%IsPrimitive(s)) return s; |
| 621 } | 641 } |
| 622 | 642 |
| 623 throw %MakeTypeError('cannot_convert_to_primitive', []); | 643 throw %MakeTypeError('cannot_convert_to_primitive', []); |
| 624 } | 644 } |
| 625 | 645 |
| 626 | 646 |
| 627 // ECMA-262, section 8.6.2.6, page 28. | 647 // ECMA-262, section 8.6.2.6, page 28. |
| 628 function DefaultString(x) { | 648 function DefaultString(x) { |
| 629 var toString = x.toString; | 649 var toString = x.toString; |
| 630 if (IS_FUNCTION(toString)) { | 650 if (IS_SPEC_FUNCTION(toString)) { |
| 631 var s = %_CallFunction(x, toString); | 651 var s = %_CallFunction(x, toString); |
| 632 if (%IsPrimitive(s)) return s; | 652 if (%IsPrimitive(s)) return s; |
| 633 } | 653 } |
| 634 | 654 |
| 635 var valueOf = x.valueOf; | 655 var valueOf = x.valueOf; |
| 636 if (IS_FUNCTION(valueOf)) { | 656 if (IS_SPEC_FUNCTION(valueOf)) { |
| 637 var v = %_CallFunction(x, valueOf); | 657 var v = %_CallFunction(x, valueOf); |
| 638 if (%IsPrimitive(v)) return v; | 658 if (%IsPrimitive(v)) return v; |
| 639 } | 659 } |
| 640 | 660 |
| 641 throw %MakeTypeError('cannot_convert_to_primitive', []); | 661 throw %MakeTypeError('cannot_convert_to_primitive', []); |
| 642 } | 662 } |
| 643 | 663 |
| 644 | 664 |
| 645 // NOTE: Setting the prototype for Array must take place as early as | 665 // NOTE: Setting the prototype for Array must take place as early as |
| 646 // possible due to code generation for array literals. When | 666 // possible due to code generation for array literals. When |
| 647 // generating code for a array literal a boilerplate array is created | 667 // generating code for a array literal a boilerplate array is created |
| 648 // that is cloned when running the code. It is essential that the | 668 // that is cloned when running the code. It is essential that the |
| 649 // boilerplate gets the right prototype. | 669 // boilerplate gets the right prototype. |
| 650 %FunctionSetPrototype($Array, new $Array(0)); | 670 %FunctionSetPrototype($Array, new $Array(0)); |
| OLD | NEW |