Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: src/runtime.js

Issue 7623011: Implement function proxies (except for their use as constructors). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed second round of comments. Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.cc ('k') | src/string.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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));
OLDNEW
« no previous file with comments | « src/runtime.cc ('k') | src/string.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698