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

Side by Side Diff: src/v8natives.js

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month 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/variables.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 355 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 366
367 // ES5 8.10.2. 367 // ES5 8.10.2.
368 function IsDataDescriptor(desc) { 368 function IsDataDescriptor(desc) {
369 if (IS_UNDEFINED(desc)) return false; 369 if (IS_UNDEFINED(desc)) return false;
370 return desc.hasValue() || desc.hasWritable(); 370 return desc.hasValue() || desc.hasWritable();
371 } 371 }
372 372
373 373
374 // ES5 8.10.3. 374 // ES5 8.10.3.
375 function IsGenericDescriptor(desc) { 375 function IsGenericDescriptor(desc) {
376 if (IS_UNDEFINED(desc)) return false;
376 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc)); 377 return !(IsAccessorDescriptor(desc) || IsDataDescriptor(desc));
377 } 378 }
378 379
379 380
380 function IsInconsistentDescriptor(desc) { 381 function IsInconsistentDescriptor(desc) {
381 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc); 382 return IsAccessorDescriptor(desc) && IsDataDescriptor(desc);
382 } 383 }
383 384
384 385
385 // ES5 8.10.4 386 // ES5 8.10.4
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 698
698 var current = ConvertDescriptorArrayToDescriptor(current_or_access); 699 var current = ConvertDescriptorArrayToDescriptor(current_or_access);
699 var extensible = %IsExtensible(ToObject(obj)); 700 var extensible = %IsExtensible(ToObject(obj));
700 701
701 // Error handling according to spec. 702 // Error handling according to spec.
702 // Step 3 703 // Step 3
703 if (IS_UNDEFINED(current) && !extensible) { 704 if (IS_UNDEFINED(current) && !extensible) {
704 if (should_throw) { 705 if (should_throw) {
705 throw MakeTypeError("define_disallowed", [p]); 706 throw MakeTypeError("define_disallowed", [p]);
706 } else { 707 } else {
707 return; 708 return false;
708 } 709 }
709 } 710 }
710 711
711 if (!IS_UNDEFINED(current)) { 712 if (!IS_UNDEFINED(current)) {
712 // Step 5 and 6 713 // Step 5 and 6
713 if ((IsGenericDescriptor(desc) || 714 if ((IsGenericDescriptor(desc) ||
714 IsDataDescriptor(desc) == IsDataDescriptor(current)) && 715 IsDataDescriptor(desc) == IsDataDescriptor(current)) &&
715 (!desc.hasEnumerable() || 716 (!desc.hasEnumerable() ||
716 SameValue(desc.isEnumerable(), current.isEnumerable())) && 717 SameValue(desc.isEnumerable(), current.isEnumerable())) &&
717 (!desc.hasConfigurable() || 718 (!desc.hasConfigurable() ||
718 SameValue(desc.isConfigurable(), current.isConfigurable())) && 719 SameValue(desc.isConfigurable(), current.isConfigurable())) &&
719 (!desc.hasWritable() || 720 (!desc.hasWritable() ||
720 SameValue(desc.isWritable(), current.isWritable())) && 721 SameValue(desc.isWritable(), current.isWritable())) &&
721 (!desc.hasValue() || 722 (!desc.hasValue() ||
722 SameValue(desc.getValue(), current.getValue())) && 723 SameValue(desc.getValue(), current.getValue())) &&
723 (!desc.hasGetter() || 724 (!desc.hasGetter() ||
724 SameValue(desc.getGet(), current.getGet())) && 725 SameValue(desc.getGet(), current.getGet())) &&
725 (!desc.hasSetter() || 726 (!desc.hasSetter() ||
726 SameValue(desc.getSet(), current.getSet()))) { 727 SameValue(desc.getSet(), current.getSet()))) {
727 return true; 728 return true;
728 } 729 }
729 if (!current.isConfigurable()) { 730 if (!current.isConfigurable()) {
730 // Step 7 731 // Step 7
731 if (desc.isConfigurable() || 732 if (desc.isConfigurable() ||
732 (desc.hasEnumerable() && 733 (desc.hasEnumerable() &&
733 desc.isEnumerable() != current.isEnumerable())) { 734 desc.isEnumerable() != current.isEnumerable())) {
734 if (should_throw) { 735 if (should_throw) {
735 throw MakeTypeError("redefine_disallowed", [p]); 736 throw MakeTypeError("redefine_disallowed", [p]);
736 } else { 737 } else {
737 return; 738 return false;
738 } 739 }
739 } 740 }
740 // Step 8 741 // Step 8
741 if (!IsGenericDescriptor(desc)) { 742 if (!IsGenericDescriptor(desc)) {
742 // Step 9a 743 // Step 9a
743 if (IsDataDescriptor(current) != IsDataDescriptor(desc)) { 744 if (IsDataDescriptor(current) != IsDataDescriptor(desc)) {
744 if (should_throw) { 745 if (should_throw) {
745 throw MakeTypeError("redefine_disallowed", [p]); 746 throw MakeTypeError("redefine_disallowed", [p]);
746 } else { 747 } else {
747 return; 748 return false;
748 } 749 }
749 } 750 }
750 // Step 10a 751 // Step 10a
751 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { 752 if (IsDataDescriptor(current) && IsDataDescriptor(desc)) {
752 if (!current.isWritable() && desc.isWritable()) { 753 if (!current.isWritable() && desc.isWritable()) {
753 if (should_throw) { 754 if (should_throw) {
754 throw MakeTypeError("redefine_disallowed", [p]); 755 throw MakeTypeError("redefine_disallowed", [p]);
755 } else { 756 } else {
756 return; 757 return false;
757 } 758 }
758 } 759 }
759 if (!current.isWritable() && desc.hasValue() && 760 if (!current.isWritable() && desc.hasValue() &&
760 !SameValue(desc.getValue(), current.getValue())) { 761 !SameValue(desc.getValue(), current.getValue())) {
761 if (should_throw) { 762 if (should_throw) {
762 throw MakeTypeError("redefine_disallowed", [p]); 763 throw MakeTypeError("redefine_disallowed", [p]);
763 } else { 764 } else {
764 return; 765 return false;
765 } 766 }
766 } 767 }
767 } 768 }
768 // Step 11 769 // Step 11
769 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { 770 if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) {
770 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) { 771 if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())) {
771 if (should_throw) { 772 if (should_throw) {
772 throw MakeTypeError("redefine_disallowed", [p]); 773 throw MakeTypeError("redefine_disallowed", [p]);
773 } else { 774 } else {
774 return; 775 return false;
775 } 776 }
776 } 777 }
777 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) { 778 if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) {
778 if (should_throw) { 779 if (should_throw) {
779 throw MakeTypeError("redefine_disallowed", [p]); 780 throw MakeTypeError("redefine_disallowed", [p]);
780 } else { 781 } else {
781 return; 782 return false;
782 } 783 }
783 } 784 }
784 } 785 }
785 } 786 }
786 } 787 }
787 } 788 }
788 789
789 // Send flags - enumerable and configurable are common - writable is 790 // Send flags - enumerable and configurable are common - writable is
790 // only send to the data descriptor. 791 // only send to the data descriptor.
791 // Take special care if enumerable and configurable is not defined on 792 // Take special care if enumerable and configurable is not defined on
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 } 875 }
875 876
876 // Step 4 - Special handling for array index. 877 // Step 4 - Special handling for array index.
877 var index = ToUint32(p); 878 var index = ToUint32(p);
878 if (index == ToNumber(p) && index != 4294967295) { 879 if (index == ToNumber(p) && index != 4294967295) {
879 if ((index >= length && !length_desc.isWritable()) || 880 if ((index >= length && !length_desc.isWritable()) ||
880 !DefineObjectProperty(obj, p, desc, true)) { 881 !DefineObjectProperty(obj, p, desc, true)) {
881 if (should_throw) { 882 if (should_throw) {
882 throw MakeTypeError("define_disallowed", [p]); 883 throw MakeTypeError("define_disallowed", [p]);
883 } else { 884 } else {
884 return; 885 return false;
885 } 886 }
886 } 887 }
887 if (index >= length) { 888 if (index >= length) {
888 // TODO(mstarzinger): We should actually set the value of the property 889 // TODO(mstarzinger): We should actually set the value of the property
889 // descriptor here and pass it to DefineObjectProperty(). Take a look at 890 // descriptor here and pass it to DefineObjectProperty(). Take a look at
890 // ES5 section 15.4.5.1, step 4.e.i and 4.e.ii for details. 891 // ES5 section 15.4.5.1, step 4.e.i and 4.e.ii for details.
891 obj.length = index + 1; 892 obj.length = index + 1;
892 } 893 }
893 return true; 894 return true;
894 } 895 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 } 930 }
930 931
931 932
932 // For Harmony proxies 933 // For Harmony proxies
933 function ToStringArray(obj, trap) { 934 function ToStringArray(obj, trap) {
934 if (!IS_SPEC_OBJECT(obj)) { 935 if (!IS_SPEC_OBJECT(obj)) {
935 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]); 936 throw MakeTypeError("proxy_non_object_prop_names", [obj, trap]);
936 } 937 }
937 var n = ToUint32(obj.length); 938 var n = ToUint32(obj.length);
938 var array = new $Array(n); 939 var array = new $Array(n);
939 var names = {} 940 var names = {} // TODO(rossberg): use sets once they are ready.
940 for (var index = 0; index < n; index++) { 941 for (var index = 0; index < n; index++) {
941 var s = ToString(obj[index]); 942 var s = ToString(obj[index]);
942 if (s in names) { 943 if (s in names) {
943 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s]) 944 throw MakeTypeError("proxy_repeated_prop_name", [obj, trap, s])
944 } 945 }
945 array[index] = s; 946 array[index] = s;
946 names.s = 0; 947 names[s] = 0;
947 } 948 }
948 return array; 949 return array;
949 } 950 }
950 951
951 952
952 // ES5 section 15.2.3.4. 953 // ES5 section 15.2.3.4.
953 function ObjectGetOwnPropertyNames(obj) { 954 function ObjectGetOwnPropertyNames(obj) {
954 if (!IS_SPEC_OBJECT(obj)) 955 if (!IS_SPEC_OBJECT(obj))
955 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]) ; 956 throw MakeTypeError("obj_ctor_property_non_object", ["getOwnPropertyNames"]) ;
956 957
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 return names; 1072 return names;
1072 } 1073 }
1073 1074
1074 1075
1075 // ES5 section 15.2.3.7. 1076 // ES5 section 15.2.3.7.
1076 function ObjectDefineProperties(obj, properties) { 1077 function ObjectDefineProperties(obj, properties) {
1077 if (!IS_SPEC_OBJECT(obj)) 1078 if (!IS_SPEC_OBJECT(obj))
1078 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); 1079 throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]);
1079 var props = ToObject(properties); 1080 var props = ToObject(properties);
1080 var names = GetOwnEnumerablePropertyNames(props); 1081 var names = GetOwnEnumerablePropertyNames(props);
1082 var descriptors = new InternalArray();
1081 for (var i = 0; i < names.length; i++) { 1083 for (var i = 0; i < names.length; i++) {
1082 var name = names[i]; 1084 descriptors.push(ToPropertyDescriptor(props[names[i]]));
1083 var desc = ToPropertyDescriptor(props[name]); 1085 }
1084 DefineOwnProperty(obj, name, desc, true); 1086 for (var i = 0; i < names.length; i++) {
1087 DefineOwnProperty(obj, names[i], descriptors[i], true);
1085 } 1088 }
1086 return obj; 1089 return obj;
1087 } 1090 }
1088 1091
1089 1092
1090 // Harmony proxies. 1093 // Harmony proxies.
1091 function ProxyFix(obj) { 1094 function ProxyFix(obj) {
1092 var handler = %GetHandler(obj); 1095 var handler = %GetHandler(obj);
1093 var props = CallTrap0(handler, "fix", void 0); 1096 var props = CallTrap0(handler, "fix", void 0);
1094 if (IS_UNDEFINED(props)) { 1097 if (IS_UNDEFINED(props)) {
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
1510 1513
1511 1514
1512 function FunctionToString() { 1515 function FunctionToString() {
1513 return FunctionSourceString(this); 1516 return FunctionSourceString(this);
1514 } 1517 }
1515 1518
1516 1519
1517 // ES5 15.3.4.5 1520 // ES5 15.3.4.5
1518 function FunctionBind(this_arg) { // Length is 1. 1521 function FunctionBind(this_arg) { // Length is 1.
1519 if (!IS_SPEC_FUNCTION(this)) { 1522 if (!IS_SPEC_FUNCTION(this)) {
1520 throw new $TypeError('Bind must be called on a function'); 1523 throw new $TypeError('Bind must be called on a function');
1521 } 1524 }
1522 // this_arg is not an argument that should be bound. 1525 var boundFunction = function () {
1523 var argc_bound = (%_ArgumentsLength() || 1) - 1; 1526 // Poison .arguments and .caller, but is otherwise not detectable.
1524 var fn = this; 1527 "use strict";
1528 // This function must not use any object literals (Object, Array, RegExp),
1529 // since the literals-array is being used to store the bound data.
1530 if (%_IsConstructCall()) {
1531 return %NewObjectFromBound(boundFunction);
1532 }
1533 var bindings = %BoundFunctionGetBindings(boundFunction);
1525 1534
1526 if (argc_bound == 0) { 1535 var argc = %_ArgumentsLength();
1527 var result = function() { 1536 if (argc == 0) {
1528 if (%_IsConstructCall()) { 1537 return %Apply(bindings[0], bindings[1], bindings, 2, bindings.length - 2);
1529 // %NewObjectFromBound implicitly uses arguments passed to this
1530 // function. We do not pass the arguments object explicitly to avoid
1531 // materializing it and guarantee that this function will be optimized.
1532 return %NewObjectFromBound(fn, null);
1533 }
1534 return %Apply(fn, this_arg, arguments, 0, %_ArgumentsLength());
1535 };
1536 } else {
1537 var bound_args = new InternalArray(argc_bound);
1538 for(var i = 0; i < argc_bound; i++) {
1539 bound_args[i] = %_Arguments(i+1);
1540 } 1538 }
1539 if (bindings.length === 2) {
1540 return %Apply(bindings[0], bindings[1], arguments, 0, argc);
1541 }
1542 var bound_argc = bindings.length - 2;
1543 var argv = new InternalArray(bound_argc + argc);
1544 for (var i = 0; i < bound_argc; i++) {
1545 argv[i] = bindings[i + 2];
1546 }
1547 for (var j = 0; j < argc; j++) {
1548 argv[i++] = %_Arguments(j);
1549 }
1550 return %Apply(bindings[0], bindings[1], argv, 0, bound_argc + argc);
1551 };
1541 1552
1542 var result = function() { 1553 %FunctionRemovePrototype(boundFunction);
1543 // If this is a construct call we use a special runtime method 1554 var new_length = 0;
1544 // to generate the actual object using the bound function. 1555 if (%_ClassOf(this) == "Function") {
1545 if (%_IsConstructCall()) { 1556 // Function or FunctionProxy.
1546 // %NewObjectFromBound implicitly uses arguments passed to this 1557 var old_length = this.length;
1547 // function. We do not pass the arguments object explicitly to avoid 1558 // FunctionProxies might provide a non-UInt32 value. If so, ignore it.
1548 // materializing it and guarantee that this function will be optimized. 1559 if ((typeof old_length === "number") &&
1549 return %NewObjectFromBound(fn, bound_args); 1560 ((old_length >>> 0) === old_length)) {
1550 }
1551
1552 // Combine the args we got from the bind call with the args
1553 // given as argument to the invocation.
1554 var argc = %_ArgumentsLength(); 1561 var argc = %_ArgumentsLength();
1555 var args = new InternalArray(argc + argc_bound); 1562 if (argc > 0) argc--; // Don't count the thisArg as parameter.
1556 // Add bound arguments. 1563 new_length = old_length - argc;
1557 for (var i = 0; i < argc_bound; i++) { 1564 if (new_length < 0) new_length = 0;
1558 args[i] = bound_args[i]; 1565 }
1559 }
1560 // Add arguments from call.
1561 for (var i = 0; i < argc; i++) {
1562 args[argc_bound + i] = %_Arguments(i);
1563 }
1564 return %Apply(fn, this_arg, args, 0, argc + argc_bound);
1565 };
1566 } 1566 }
1567 // This runtime function finds any remaining arguments on the stack,
1568 // so we don't pass the arguments object.
1569 var result = %FunctionBindArguments(boundFunction, this, this_arg, new_length) ;
1567 1570
1568 // We already have caller and arguments properties on functions, 1571 // We already have caller and arguments properties on functions,
1569 // which are non-configurable. It therefore makes no sence to 1572 // which are non-configurable. It therefore makes no sence to
1570 // try to redefine these as defined by the spec. The spec says 1573 // try to redefine these as defined by the spec. The spec says
1571 // that bind should make these throw a TypeError if get or set 1574 // that bind should make these throw a TypeError if get or set
1572 // is called and make them non-enumerable and non-configurable. 1575 // is called and make them non-enumerable and non-configurable.
1573 // To be consistent with our normal functions we leave this as it is. 1576 // To be consistent with our normal functions we leave this as it is.
1574 1577 // TODO(lrn): Do set these to be thrower.
1575 %FunctionRemovePrototype(result);
1576 %FunctionSetBound(result);
1577 // Set the correct length. If this is a function proxy, this.length might
1578 // throw, or return a bogus result. Leave length alone in that case.
1579 // TODO(rossberg): This is underspecified in the current proxy proposal.
1580 try {
1581 var old_length = ToInteger(this.length);
1582 var length = (old_length - argc_bound) > 0 ? old_length - argc_bound : 0;
1583 %BoundFunctionSetLength(result, length);
1584 } catch(x) {}
1585 return result; 1578 return result;
1586 } 1579 }
1587 1580
1588 1581
1589 function NewFunction(arg1) { // length == 1 1582 function NewFunction(arg1) { // length == 1
1590 var n = %_ArgumentsLength(); 1583 var n = %_ArgumentsLength();
1591 var p = ''; 1584 var p = '';
1592 if (n > 1) { 1585 if (n > 1) {
1593 p = new InternalArray(n - 1); 1586 p = new InternalArray(n - 1);
1594 for (var i = 0; i < n - 1; i++) p[i] = %_Arguments(i); 1587 for (var i = 0; i < n - 1; i++) p[i] = %_Arguments(i);
(...skipping 19 matching lines...) Expand all
1614 1607
1615 function SetUpFunction() { 1608 function SetUpFunction() {
1616 %CheckIsBootstrapping(); 1609 %CheckIsBootstrapping();
1617 InstallFunctions($Function.prototype, DONT_ENUM, $Array( 1610 InstallFunctions($Function.prototype, DONT_ENUM, $Array(
1618 "bind", FunctionBind, 1611 "bind", FunctionBind,
1619 "toString", FunctionToString 1612 "toString", FunctionToString
1620 )); 1613 ));
1621 } 1614 }
1622 1615
1623 SetUpFunction(); 1616 SetUpFunction();
OLDNEW
« no previous file with comments | « src/v8globals.h ('k') | src/variables.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698