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

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: Eps: refined a comment. 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
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 19 matching lines...) Expand all
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)) { 407 if (!IS_FUNCTION(delegate)) {
408 throw %MakeTypeError('called_non_callable', [typeof this]); 408 if (%IsJSFunctionProxy(this)) {
Kevin Millikin (Chromium) 2011/09/08 17:30:40 Can we get into this case, where CALL_NON_FUNCTION
rossberg 2011/09/09 17:05:30 Done (subsuming part of change 7849021).
409 delegate = %GetCallTrap(this);
410 } else {
411 throw %MakeTypeError('called_non_callable', [typeof this]);
412 }
409 } 413 }
410 return delegate.apply(this, arguments); 414 return delegate.apply(this, arguments);
411 } 415 }
412 416
413 417
414 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() { 418 function CALL_NON_FUNCTION_AS_CONSTRUCTOR() {
415 var delegate = %GetConstructorDelegate(this); 419 var delegate = %GetConstructorDelegate(this);
416 if (!IS_FUNCTION(delegate)) { 420 if (!IS_FUNCTION(delegate)) {
417 throw %MakeTypeError('called_non_callable', [typeof this]); 421 if (%IsJSFunctionProxy(this)) {
422 delegate = %GetConstructTrap(this);
423 } else {
424 throw %MakeTypeError('called_non_callable', [typeof this]);
425 }
418 } 426 }
419 return delegate.apply(this, arguments); 427 return delegate.apply(this, arguments);
420 } 428 }
421 429
422 430
431 function CALL_FUNCTION_PROXY() {
432 var arity = %_ArgumentsLength() - 1;
433 var proxy = arguments[arity]; // The proxy comes in as an additional arg.
Kevin Millikin (Chromium) 2011/09/08 17:30:40 You can also use %_Arguments(arity) to get the arg
rossberg 2011/09/09 17:05:30 Done (although we have to materialize the argument
434 var trap = %GetCallTrap(proxy);
435 // TODO(rossberg): hm, shouldn't I be using $Function and friends?
436 // But how do I get it in a builtin?
437 return global.Function.prototype.apply.call(
Kevin Millikin (Chromium) 2011/09/08 17:30:40 You can't, the JS builtins are called with the con
rossberg 2011/09/09 17:05:30 I implemented an %Apply native.
438 trap, this, global.Array.prototype.slice.call(arguments, 0, arity));
439 }
440
441
442 function CALL_FUNCTION_PROXY_AS_CONSTRUCTOR(proxy) {
443 var trap = %GetConstructTrap(proxy);
444 var receiver = void 0;
445 if (!IS_UNDEFINED(trap)) {
446 trap = %GetCallTrap(proxy);
447 var proto = proxy.prototype;
448 if (!IS_SPEC_OBJECT(proto) && proto !== null) {
449 throw MakeTypeError("proto_object_or_null", [proto]);
450 }
451 receiver = new global.Object();
452 receiver.__proto__ = proto;
453 }
454 return global.Function.prototype.apply.call(
455 trap, this, global.Array.prototype.shift.call(arguments));
456 }
457
458
423 function APPLY_PREPARE(args) { 459 function APPLY_PREPARE(args) {
424 var length; 460 var length;
425 // First check whether length is a positive Smi and args is an 461 // 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 462 // array. This is the fast case. If this fails, we do the slow case
427 // that takes care of more eventualities. 463 // that takes care of more eventualities.
428 if (IS_ARRAY(args)) { 464 if (IS_ARRAY(args)) {
429 length = args.length; 465 length = args.length;
430 if (%_IsSmi(length) && length >= 0 && length < 0x800000 && IS_FUNCTION(this) ) { 466 if (%_IsSmi(length) && length >= 0 && length < 0x800000 &&
467 IS_SPEC_FUNCTION(this)) {
431 return length; 468 return length;
432 } 469 }
433 } 470 }
434 471
435 length = (args == null) ? 0 : %ToUint32(args.length); 472 length = (args == null) ? 0 : %ToUint32(args.length);
436 473
437 // We can handle any number of apply arguments if the stack is 474 // We can handle any number of apply arguments if the stack is
438 // big enough, but sanity check the value to avoid overflow when 475 // big enough, but sanity check the value to avoid overflow when
439 // multiplying with pointer size. 476 // multiplying with pointer size.
440 if (length > 0x800000) { 477 if (length > 0x800000) {
441 throw %MakeRangeError('stack_overflow', []); 478 throw %MakeRangeError('stack_overflow', []);
442 } 479 }
443 480
444 if (!IS_FUNCTION(this)) { 481 if (!IS_SPEC_FUNCTION(this)) {
445 throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ]) ; 482 throw %MakeTypeError('apply_non_function', [ %ToString(this), typeof this ]) ;
446 } 483 }
447 484
448 // Make sure the arguments list has the right type. 485 // Make sure the arguments list has the right type.
449 if (args != null && !IS_ARRAY(args) && !IS_ARGUMENTS(args)) { 486 if (args != null && !IS_ARRAY(args) && !IS_ARGUMENTS(args)) {
450 throw %MakeTypeError('apply_wrong_args', []); 487 throw %MakeTypeError('apply_wrong_args', []);
451 } 488 }
452 489
453 // Return the length which is the number of arguments to copy to the 490 // 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. 491 // 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 639 // Even though the type of null is "object", null is still
603 // considered a primitive value. IS_SPEC_OBJECT handles this correctly 640 // considered a primitive value. IS_SPEC_OBJECT handles this correctly
604 // (i.e., it will return false if x is null). 641 // (i.e., it will return false if x is null).
605 return !IS_SPEC_OBJECT(x); 642 return !IS_SPEC_OBJECT(x);
606 } 643 }
607 644
608 645
609 // ECMA-262, section 8.6.2.6, page 28. 646 // ECMA-262, section 8.6.2.6, page 28.
610 function DefaultNumber(x) { 647 function DefaultNumber(x) {
611 var valueOf = x.valueOf; 648 var valueOf = x.valueOf;
612 if (IS_FUNCTION(valueOf)) { 649 if (IS_SPEC_FUNCTION(valueOf)) {
613 var v = %_CallFunction(x, valueOf); 650 var v = %_CallFunction(x, valueOf);
614 if (%IsPrimitive(v)) return v; 651 if (%IsPrimitive(v)) return v;
615 } 652 }
616 653
617 var toString = x.toString; 654 var toString = x.toString;
618 if (IS_FUNCTION(toString)) { 655 if (IS_SPEC_FUNCTION(toString)) {
619 var s = %_CallFunction(x, toString); 656 var s = %_CallFunction(x, toString);
620 if (%IsPrimitive(s)) return s; 657 if (%IsPrimitive(s)) return s;
621 } 658 }
622 659
623 throw %MakeTypeError('cannot_convert_to_primitive', []); 660 throw %MakeTypeError('cannot_convert_to_primitive', []);
624 } 661 }
625 662
626 663
627 // ECMA-262, section 8.6.2.6, page 28. 664 // ECMA-262, section 8.6.2.6, page 28.
628 function DefaultString(x) { 665 function DefaultString(x) {
629 var toString = x.toString; 666 var toString = x.toString;
630 if (IS_FUNCTION(toString)) { 667 if (IS_SPEC_FUNCTION(toString)) {
631 var s = %_CallFunction(x, toString); 668 var s = %_CallFunction(x, toString);
632 if (%IsPrimitive(s)) return s; 669 if (%IsPrimitive(s)) return s;
633 } 670 }
634 671
635 var valueOf = x.valueOf; 672 var valueOf = x.valueOf;
636 if (IS_FUNCTION(valueOf)) { 673 if (IS_SPEC_FUNCTION(valueOf)) {
637 var v = %_CallFunction(x, valueOf); 674 var v = %_CallFunction(x, valueOf);
638 if (%IsPrimitive(v)) return v; 675 if (%IsPrimitive(v)) return v;
639 } 676 }
640 677
641 throw %MakeTypeError('cannot_convert_to_primitive', []); 678 throw %MakeTypeError('cannot_convert_to_primitive', []);
642 } 679 }
643 680
644 681
645 // NOTE: Setting the prototype for Array must take place as early as 682 // NOTE: Setting the prototype for Array must take place as early as
646 // possible due to code generation for array literals. When 683 // possible due to code generation for array literals. When
647 // generating code for a array literal a boilerplate array is created 684 // generating code for a array literal a boilerplate array is created
648 // that is cloned when running the code. It is essential that the 685 // that is cloned when running the code. It is essential that the
649 // boilerplate gets the right prototype. 686 // boilerplate gets the right prototype.
650 %FunctionSetPrototype($Array, new $Array(0)); 687 %FunctionSetPrototype($Array, new $Array(0));
OLDNEW
« src/runtime.cc ('K') | « src/runtime.cc ('k') | src/string.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698