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 |