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

Side by Side Diff: src/v8natives.js

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 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/v8globals.h ('k') | src/v8utils.h » ('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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 76
77 // ECMA 262 - 15.1.4 77 // ECMA 262 - 15.1.4
78 function GlobalIsNaN(number) { 78 function GlobalIsNaN(number) {
79 var n = ToNumber(number); 79 var n = ToNumber(number);
80 return NUMBER_IS_NAN(n); 80 return NUMBER_IS_NAN(n);
81 } 81 }
82 82
83 83
84 // ECMA 262 - 15.1.5 84 // ECMA 262 - 15.1.5
85 function GlobalIsFinite(number) { 85 function GlobalIsFinite(number) {
86 if (!IS_NUMBER(number)) number = ToNumber(number); 86 if (!IS_NUMBER(number)) number = NonNumberToNumber(number);
87 87
88 // NaN - NaN == NaN, Infinity - Infinity == NaN, -Infinity - -Infinity == NaN. 88 // NaN - NaN == NaN, Infinity - Infinity == NaN, -Infinity - -Infinity == NaN.
89 return %_IsSmi(number) || number - number == 0; 89 return %_IsSmi(number) || number - number == 0;
90 } 90 }
91 91
92 92
93 // ECMA-262 - 15.1.2.2 93 // ECMA-262 - 15.1.2.2
94 function GlobalParseInt(string, radix) { 94 function GlobalParseInt(string, radix) {
95 if (IS_UNDEFINED(radix)) { 95 if (IS_UNDEFINED(radix)) {
96 // Some people use parseInt instead of Math.floor. This 96 // Some people use parseInt instead of Math.floor. This
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 PropertyDescriptor.prototype.getSet = function() { 484 PropertyDescriptor.prototype.getSet = function() {
485 return this.set_; 485 return this.set_;
486 } 486 }
487 487
488 488
489 PropertyDescriptor.prototype.hasSetter = function() { 489 PropertyDescriptor.prototype.hasSetter = function() {
490 return this.hasSetter_; 490 return this.hasSetter_;
491 } 491 }
492 492
493 493
494 // Converts an array returned from Runtime_GetOwnProperty to an actual
495 // property descriptor. For a description of the array layout please
496 // see the runtime.cc file.
497 function ConvertDescriptorArrayToDescriptor(desc_array) {
498 if (desc_array == false) {
499 throw 'Internal error: invalid desc_array';
500 }
494 501
495 // ES5 section 8.12.1. 502 if (IS_UNDEFINED(desc_array)) {
496 function GetOwnProperty(obj, p) { 503 return void 0;
504 }
505
497 var desc = new PropertyDescriptor(); 506 var desc = new PropertyDescriptor();
498 507 // This is an accessor.
499 // GetOwnProperty returns an array indexed by the constants 508 if (desc_array[IS_ACCESSOR_INDEX]) {
500 // defined in macros.py. 509 desc.setGet(desc_array[GETTER_INDEX]);
501 // If p is not a property on obj undefined is returned. 510 desc.setSet(desc_array[SETTER_INDEX]);
502 var props = %GetOwnProperty(ToObject(obj), ToString(p));
503
504 if (IS_UNDEFINED(props)) return void 0;
505
506 // This is an accessor
507 if (props[IS_ACCESSOR_INDEX]) {
508 desc.setGet(props[GETTER_INDEX]);
509 desc.setSet(props[SETTER_INDEX]);
510 } else { 511 } else {
511 desc.setValue(props[VALUE_INDEX]); 512 desc.setValue(desc_array[VALUE_INDEX]);
512 desc.setWritable(props[WRITABLE_INDEX]); 513 desc.setWritable(desc_array[WRITABLE_INDEX]);
513 } 514 }
514 desc.setEnumerable(props[ENUMERABLE_INDEX]); 515 desc.setEnumerable(desc_array[ENUMERABLE_INDEX]);
515 desc.setConfigurable(props[CONFIGURABLE_INDEX]); 516 desc.setConfigurable(desc_array[CONFIGURABLE_INDEX]);
516 517
517 return desc; 518 return desc;
518 } 519 }
519 520
520 521
521 // ES5 section 8.12.2. 522 // ES5 section 8.12.2.
522 function GetProperty(obj, p) { 523 function GetProperty(obj, p) {
523 var prop = GetOwnProperty(obj); 524 var prop = GetOwnProperty(obj);
524 if (!IS_UNDEFINED(prop)) return prop; 525 if (!IS_UNDEFINED(prop)) return prop;
525 var proto = obj.__proto__; 526 var proto = obj.__proto__;
526 if (IS_NULL(proto)) return void 0; 527 if (IS_NULL(proto)) return void 0;
527 return GetProperty(proto, p); 528 return GetProperty(proto, p);
528 } 529 }
529 530
530 531
531 // ES5 section 8.12.6 532 // ES5 section 8.12.6
532 function HasProperty(obj, p) { 533 function HasProperty(obj, p) {
533 var desc = GetProperty(obj, p); 534 var desc = GetProperty(obj, p);
534 return IS_UNDEFINED(desc) ? false : true; 535 return IS_UNDEFINED(desc) ? false : true;
535 } 536 }
536 537
537 538
539 // ES5 section 8.12.1.
540 function GetOwnProperty(obj, p) {
541 // GetOwnProperty returns an array indexed by the constants
542 // defined in macros.py.
543 // If p is not a property on obj undefined is returned.
544 var props = %GetOwnProperty(ToObject(obj), ToString(p));
545
546 // A false value here means that access checks failed.
547 if (props == false) return void 0;
548
549 return ConvertDescriptorArrayToDescriptor(props);
550 }
551
552
538 // ES5 8.12.9. 553 // ES5 8.12.9.
539 function DefineOwnProperty(obj, p, desc, should_throw) { 554 function DefineOwnProperty(obj, p, desc, should_throw) {
540 var current = GetOwnProperty(obj, p); 555 var current_or_access = %GetOwnProperty(ToObject(obj), ToString(p));
556 // A false value here means that access checks failed.
557 if (current_or_access == false) return void 0;
558
559 var current = ConvertDescriptorArrayToDescriptor(current_or_access);
541 var extensible = %IsExtensible(ToObject(obj)); 560 var extensible = %IsExtensible(ToObject(obj));
542 561
543 // Error handling according to spec. 562 // Error handling according to spec.
544 // Step 3 563 // Step 3
545 if (IS_UNDEFINED(current) && !extensible) 564 if (IS_UNDEFINED(current) && !extensible)
546 throw MakeTypeError("define_disallowed", ["defineProperty"]); 565 throw MakeTypeError("define_disallowed", ["defineProperty"]);
547 566
548 if (!IS_UNDEFINED(current) && !current.isConfigurable()) { 567 if (!IS_UNDEFINED(current)) {
549 // Step 5 and 6 568 // Step 5 and 6
550 if ((!desc.hasEnumerable() || 569 if ((IsGenericDescriptor(desc) ||
551 SameValue(desc.isEnumerable() && current.isEnumerable())) && 570 IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
571 (!desc.hasEnumerable() ||
572 SameValue(desc.isEnumerable(), current.isEnumerable())) &&
552 (!desc.hasConfigurable() || 573 (!desc.hasConfigurable() ||
553 SameValue(desc.isConfigurable(), current.isConfigurable())) && 574 SameValue(desc.isConfigurable(), current.isConfigurable())) &&
554 (!desc.hasWritable() || 575 (!desc.hasWritable() ||
555 SameValue(desc.isWritable(), current.isWritable())) && 576 SameValue(desc.isWritable(), current.isWritable())) &&
556 (!desc.hasValue() || 577 (!desc.hasValue() ||
557 SameValue(desc.getValue(), current.getValue())) && 578 SameValue(desc.getValue(), current.getValue())) &&
558 (!desc.hasGetter() || 579 (!desc.hasGetter() ||
559 SameValue(desc.getGet(), current.getGet())) && 580 SameValue(desc.getGet(), current.getGet())) &&
560 (!desc.hasSetter() || 581 (!desc.hasSetter() ||
561 SameValue(desc.getSet(), current.getSet()))) { 582 SameValue(desc.getSet(), current.getSet()))) {
562 return true; 583 return true;
563 } 584 }
564 585 if (!current.isConfigurable()) {
565 // Step 7 586 // Step 7
566 if (desc.isConfigurable() || desc.isEnumerable() != current.isEnumerable()) 587 if (desc.isConfigurable() ||
567 throw MakeTypeError("redefine_disallowed", ["defineProperty"]); 588 (desc.hasEnumerable() &&
568 // Step 9 589 desc.isEnumerable() != current.isEnumerable())) {
569 if (IsDataDescriptor(current) != IsDataDescriptor(desc))
570 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
571 // Step 10
572 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
573 if (!current.isWritable() && desc.isWritable())
574 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
575 if (!current.isWritable() && desc.hasValue() &&
576 !SameValue(desc.getValue(), current.getValue())) {
577 throw MakeTypeError("redefine_disallowed", ["defineProperty"]); 590 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
578 } 591 }
579 } 592 // Step 8
580 // Step 11 593 if (!IsGenericDescriptor(desc)) {
581 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { 594 // Step 9a
582 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){ 595 if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
583 throw MakeTypeError("redefine_disallowed", ["defineProperty"]); 596 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
597 }
598 // Step 10a
599 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
600 if (!current.isWritable() && desc.isWritable()) {
601 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
602 }
603 if (!current.isWritable() && desc.hasValue() &&
604 !SameValue(desc.getValue(), current.getValue())) {
605 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
606 }
607 }
608 // Step 11
609 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
610 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) {
611 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
612 }
613 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
614 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
615 }
616 }
584 } 617 }
585 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet()))
586 throw MakeTypeError("redefine_disallowed", ["defineProperty"]);
587 } 618 }
588 } 619 }
589 620
590 // Send flags - enumerable and configurable are common - writable is 621 // Send flags - enumerable and configurable are common - writable is
591 // only send to the data descriptor. 622 // only send to the data descriptor.
592 // Take special care if enumerable and configurable is not defined on 623 // Take special care if enumerable and configurable is not defined on
593 // desc (we need to preserve the existing values from current). 624 // desc (we need to preserve the existing values from current).
594 var flag = NONE; 625 var flag = NONE;
595 if (desc.hasEnumerable()) { 626 if (desc.hasEnumerable()) {
596 flag |= desc.isEnumerable() ? 0 : DONT_ENUM; 627 flag |= desc.isEnumerable() ? 0 : DONT_ENUM;
597 } else if (!IS_UNDEFINED(current)) { 628 } else if (!IS_UNDEFINED(current)) {
598 flag |= current.isEnumerable() ? 0 : DONT_ENUM; 629 flag |= current.isEnumerable() ? 0 : DONT_ENUM;
599 } else { 630 } else {
600 flag |= DONT_ENUM; 631 flag |= DONT_ENUM;
601 } 632 }
602 633
603 if (desc.hasConfigurable()) { 634 if (desc.hasConfigurable()) {
604 flag |= desc.isConfigurable() ? 0 : DONT_DELETE; 635 flag |= desc.isConfigurable() ? 0 : DONT_DELETE;
605 } else if (!IS_UNDEFINED(current)) { 636 } else if (!IS_UNDEFINED(current)) {
606 flag |= current.isConfigurable() ? 0 : DONT_DELETE; 637 flag |= current.isConfigurable() ? 0 : DONT_DELETE;
607 } else 638 } else
608 flag |= DONT_DELETE; 639 flag |= DONT_DELETE;
609 640
610 if (IsDataDescriptor(desc) || IsGenericDescriptor(desc)) { 641 if (IsDataDescriptor(desc) ||
642 (IsGenericDescriptor(desc) &&
643 (IS_UNDEFINED(current) || IsDataDescriptor(current)))) {
644 // There are 3 cases that lead here:
645 // Step 4a - defining a new data property.
646 // Steps 9b & 12 - replacing an existing accessor property with a data
647 // property.
648 // Step 12 - updating an existing data property with a data or generic
649 // descriptor.
650
611 if (desc.hasWritable()) { 651 if (desc.hasWritable()) {
612 flag |= desc.isWritable() ? 0 : READ_ONLY; 652 flag |= desc.isWritable() ? 0 : READ_ONLY;
613 } else if (!IS_UNDEFINED(current)) { 653 } else if (!IS_UNDEFINED(current)) {
614 flag |= current.isWritable() ? 0 : READ_ONLY; 654 flag |= current.isWritable() ? 0 : READ_ONLY;
615 } else { 655 } else {
616 flag |= READ_ONLY; 656 flag |= READ_ONLY;
617 } 657 }
658
618 var value = void 0; // Default value is undefined. 659 var value = void 0; // Default value is undefined.
619 if (desc.hasValue()) { 660 if (desc.hasValue()) {
620 value = desc.getValue(); 661 value = desc.getValue();
621 } else if (!IS_UNDEFINED(current)) { 662 } else if (!IS_UNDEFINED(current) && IsDataDescriptor(current)) {
622 value = current.getValue(); 663 value = current.getValue();
623 } 664 }
665
624 %DefineOrRedefineDataProperty(obj, p, value, flag); 666 %DefineOrRedefineDataProperty(obj, p, value, flag);
667 } else if (IsGenericDescriptor(desc)) {
668 // Step 12 - updating an existing accessor property with generic
669 // descriptor. Changing flags only.
670 %DefineOrRedefineAccessorProperty(obj, p, GETTER, current.getGet(), flag);
625 } else { 671 } else {
626 if (desc.hasGetter() && 672 // There are 3 cases that lead here:
627 (IS_FUNCTION(desc.getGet()) || IS_UNDEFINED(desc.getGet()))) { 673 // Step 4b - defining a new accessor property.
628 %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag); 674 // Steps 9c & 12 - replacing an existing data property with an accessor
675 // property.
676 // Step 12 - updating an existing accessor property with an accessor
677 // descriptor.
678 if (desc.hasGetter()) {
679 %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
629 } 680 }
630 if (desc.hasSetter() && 681 if (desc.hasSetter()) {
631 (IS_FUNCTION(desc.getSet()) || IS_UNDEFINED(desc.getSet()))) {
632 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); 682 %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
633 } 683 }
634 } 684 }
635 return true; 685 return true;
636 } 686 }
637 687
638 688
639 // ES5 section 15.2.3.2. 689 // ES5 section 15.2.3.2.
640 function ObjectGetPrototypeOf(obj) { 690 function ObjectGetPrototypeOf(obj) {
641 if (!IS_SPEC_OBJECT(obj)) 691 if (!IS_SPEC_OBJECT(obj))
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 939
890 SetupObject(); 940 SetupObject();
891 941
892 942
893 // ---------------------------------------------------------------------------- 943 // ----------------------------------------------------------------------------
894 // Boolean 944 // Boolean
895 945
896 function BooleanToString() { 946 function BooleanToString() {
897 // NOTE: Both Boolean objects and values can enter here as 947 // NOTE: Both Boolean objects and values can enter here as
898 // 'this'. This is not as dictated by ECMA-262. 948 // 'this'. This is not as dictated by ECMA-262.
899 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) 949 var b = this;
900 throw new $TypeError('Boolean.prototype.toString is not generic'); 950 if (!IS_BOOLEAN(b)) {
901 return ToString(%_ValueOf(this)); 951 if (!IS_BOOLEAN_WRAPPER(b)) {
952 throw new $TypeError('Boolean.prototype.toString is not generic');
953 }
954 b = %_ValueOf(b);
955 }
956 return b ? 'true' : 'false';
902 } 957 }
903 958
904 959
905 function BooleanValueOf() { 960 function BooleanValueOf() {
906 // NOTE: Both Boolean objects and values can enter here as 961 // NOTE: Both Boolean objects and values can enter here as
907 // 'this'. This is not as dictated by ECMA-262. 962 // 'this'. This is not as dictated by ECMA-262.
908 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this)) 963 if (!IS_BOOLEAN(this) && !IS_BOOLEAN_WRAPPER(this))
909 throw new $TypeError('Boolean.prototype.valueOf is not generic'); 964 throw new $TypeError('Boolean.prototype.valueOf is not generic');
910 return %_ValueOf(this); 965 return %_ValueOf(this);
911 } 966 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 // 'this'. This is not as dictated by ECMA-262. 999 // 'this'. This is not as dictated by ECMA-262.
945 var number = this; 1000 var number = this;
946 if (!IS_NUMBER(this)) { 1001 if (!IS_NUMBER(this)) {
947 if (!IS_NUMBER_WRAPPER(this)) 1002 if (!IS_NUMBER_WRAPPER(this))
948 throw new $TypeError('Number.prototype.toString is not generic'); 1003 throw new $TypeError('Number.prototype.toString is not generic');
949 // Get the value of this number in case it's an object. 1004 // Get the value of this number in case it's an object.
950 number = %_ValueOf(this); 1005 number = %_ValueOf(this);
951 } 1006 }
952 // Fast case: Convert number in radix 10. 1007 // Fast case: Convert number in radix 10.
953 if (IS_UNDEFINED(radix) || radix === 10) { 1008 if (IS_UNDEFINED(radix) || radix === 10) {
954 return ToString(number); 1009 return %_NumberToString(number);
955 } 1010 }
956 1011
957 // Convert the radix to an integer and check the range. 1012 // Convert the radix to an integer and check the range.
958 radix = TO_INTEGER(radix); 1013 radix = TO_INTEGER(radix);
959 if (radix < 2 || radix > 36) { 1014 if (radix < 2 || radix > 36) {
960 throw new $RangeError('toString() radix argument must be between 2 and 36'); 1015 throw new $RangeError('toString() radix argument must be between 2 and 36');
961 } 1016 }
962 // Convert the number to a string in the given radix. 1017 // Convert the number to a string in the given radix.
963 return %NumberToRadixString(number, radix); 1018 return %NumberToRadixString(number, radix);
964 } 1019 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 } 1150 }
1096 1151
1097 1152
1098 // ES5 15.3.4.5 1153 // ES5 15.3.4.5
1099 function FunctionBind(this_arg) { // Length is 1. 1154 function FunctionBind(this_arg) { // Length is 1.
1100 if (!IS_FUNCTION(this)) { 1155 if (!IS_FUNCTION(this)) {
1101 throw new $TypeError('Bind must be called on a function'); 1156 throw new $TypeError('Bind must be called on a function');
1102 } 1157 }
1103 // this_arg is not an argument that should be bound. 1158 // this_arg is not an argument that should be bound.
1104 var argc_bound = (%_ArgumentsLength() || 1) - 1; 1159 var argc_bound = (%_ArgumentsLength() || 1) - 1;
1105 if (argc_bound > 0) { 1160 var fn = this;
1161 if (argc_bound == 0) {
1162 var result = function() {
1163 if (%_IsConstructCall()) {
1164 // %NewObjectFromBound implicitly uses arguments passed to this
1165 // function. We do not pass the arguments object explicitly to avoid
1166 // materializing it and guarantee that this function will be optimized.
1167 return %NewObjectFromBound(fn, null);
1168 }
1169
1170 return fn.apply(this_arg, arguments);
1171 };
1172 } else {
1106 var bound_args = new $Array(argc_bound); 1173 var bound_args = new $Array(argc_bound);
1107 for(var i = 0; i < argc_bound; i++) { 1174 for(var i = 0; i < argc_bound; i++) {
1108 bound_args[i] = %_Arguments(i+1); 1175 bound_args[i] = %_Arguments(i+1);
1109 } 1176 }
1177
1178 var result = function() {
1179 // If this is a construct call we use a special runtime method
1180 // to generate the actual object using the bound function.
1181 if (%_IsConstructCall()) {
1182 // %NewObjectFromBound implicitly uses arguments passed to this
1183 // function. We do not pass the arguments object explicitly to avoid
1184 // materializing it and guarantee that this function will be optimized.
1185 return %NewObjectFromBound(fn, bound_args);
1186 }
1187
1188 // Combine the args we got from the bind call with the args
1189 // given as argument to the invocation.
1190 var argc = %_ArgumentsLength();
1191 var args = new $Array(argc + argc_bound);
1192 // Add bound arguments.
1193 for (var i = 0; i < argc_bound; i++) {
1194 args[i] = bound_args[i];
1195 }
1196 // Add arguments from call.
1197 for (var i = 0; i < argc; i++) {
1198 args[argc_bound + i] = %_Arguments(i);
1199 }
1200 return fn.apply(this_arg, args);
1201 };
1110 } 1202 }
1111 var fn = this;
1112 var result = function() {
1113 // Combine the args we got from the bind call with the args
1114 // given as argument to the invocation.
1115 var argc = %_ArgumentsLength();
1116 var args = new $Array(argc + argc_bound);
1117 // Add bound arguments.
1118 for (var i = 0; i < argc_bound; i++) {
1119 args[i] = bound_args[i];
1120 }
1121 // Add arguments from call.
1122 for (var i = 0; i < argc; i++) {
1123 args[argc_bound + i] = %_Arguments(i);
1124 }
1125 // If this is a construct call we use a special runtime method
1126 // to generate the actual object using the bound function.
1127 if (%_IsConstructCall()) {
1128 return %NewObjectFromBound(fn, args);
1129 }
1130 return fn.apply(this_arg, args);
1131 };
1132 1203
1133 // We already have caller and arguments properties on functions, 1204 // We already have caller and arguments properties on functions,
1134 // which are non-configurable. It therefore makes no sence to 1205 // which are non-configurable. It therefore makes no sence to
1135 // try to redefine these as defined by the spec. The spec says 1206 // try to redefine these as defined by the spec. The spec says
1136 // that bind should make these throw a TypeError if get or set 1207 // that bind should make these throw a TypeError if get or set
1137 // is called and make them non-enumerable and non-configurable. 1208 // is called and make them non-enumerable and non-configurable.
1138 // To be consistent with our normal functions we leave this as it is. 1209 // To be consistent with our normal functions we leave this as it is.
1139 1210
1140 // Set the correct length. 1211 // Set the correct length.
1141 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0; 1212 var length = (this.length - argc_bound) > 0 ? this.length - argc_bound : 0;
1142 %FunctionSetLength(result, length); 1213 %FunctionSetLength(result, length);
1143 1214
1144 return result; 1215 return result;
1145 } 1216 }
1146 1217
1147 1218
1148 function NewFunction(arg1) { // length == 1 1219 function NewFunction(arg1) { // length == 1
1149 var n = %_ArgumentsLength(); 1220 var n = %_ArgumentsLength();
1150 var p = ''; 1221 var p = '';
1151 if (n > 1) { 1222 if (n > 1) {
1152 p = new $Array(n - 1); 1223 p = new $Array(n - 1);
1153 // Explicitly convert all parameters to strings. 1224 for (var i = 0; i < n - 1; i++) p[i] = %_Arguments(i);
1154 // Array.prototype.join replaces null with empty strings which is 1225 p = Join(p, n - 1, ',', NonStringToString);
1155 // not appropriate.
1156 for (var i = 0; i < n - 1; i++) p[i] = ToString(%_Arguments(i));
1157 p = p.join(',');
1158 // If the formal parameters string include ) - an illegal 1226 // If the formal parameters string include ) - an illegal
1159 // character - it may make the combined function expression 1227 // character - it may make the combined function expression
1160 // compile. We avoid this problem by checking for this early on. 1228 // compile. We avoid this problem by checking for this early on.
1161 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]); 1229 if (p.indexOf(')') != -1) throw MakeSyntaxError('unable_to_parse',[]);
1162 } 1230 }
1163 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : ''; 1231 var body = (n > 0) ? ToString(%_Arguments(n - 1)) : '';
1164 var source = '(function(' + p + ') {\n' + body + '\n})'; 1232 var source = '(function(' + p + ') {\n' + body + '\n})';
1165 1233
1166 // The call to SetNewFunctionAttributes will ensure the prototype 1234 // The call to SetNewFunctionAttributes will ensure the prototype
1167 // property of the resulting function is enumerable (ECMA262, 15.3.5.2). 1235 // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
1168 var f = %CompileString(source)(); 1236 var f = %CompileString(source)();
1169 %FunctionSetName(f, "anonymous"); 1237 %FunctionSetName(f, "anonymous");
1170 return %SetNewFunctionAttributes(f); 1238 return %SetNewFunctionAttributes(f);
1171 } 1239 }
1172 1240
1173 %SetCode($Function, NewFunction); 1241 %SetCode($Function, NewFunction);
1174 1242
1175 // ---------------------------------------------------------------------------- 1243 // ----------------------------------------------------------------------------
1176 1244
1177 function SetupFunction() { 1245 function SetupFunction() {
1178 InstallFunctions($Function.prototype, DONT_ENUM, $Array( 1246 InstallFunctions($Function.prototype, DONT_ENUM, $Array(
1179 "bind", FunctionBind, 1247 "bind", FunctionBind,
1180 "toString", FunctionToString 1248 "toString", FunctionToString
1181 )); 1249 ));
1182 } 1250 }
1183 1251
1184 SetupFunction(); 1252 SetupFunction();
OLDNEW
« no previous file with comments | « src/v8globals.h ('k') | src/v8utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698