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

Side by Side Diff: src/runtime.cc

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/runtime.h ('k') | src/runtime.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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 if (value->IsFixedArray()) { 323 if (value->IsFixedArray()) {
324 // The value contains the constant_properties of a 324 // The value contains the constant_properties of a
325 // simple object literal. 325 // simple object literal.
326 Handle<FixedArray> array = Handle<FixedArray>::cast(value); 326 Handle<FixedArray> array = Handle<FixedArray>::cast(value);
327 value = CreateLiteralBoilerplate(literals, array); 327 value = CreateLiteralBoilerplate(literals, array);
328 if (value.is_null()) return value; 328 if (value.is_null()) return value;
329 } 329 }
330 Handle<Object> result; 330 Handle<Object> result;
331 uint32_t element_index = 0; 331 uint32_t element_index = 0;
332 if (key->IsSymbol()) { 332 if (key->IsSymbol()) {
333 // If key is a symbol it is not an array element. 333 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
334 Handle<String> name(String::cast(*key)); 334 // Array index as string (uint32).
335 ASSERT(!name->AsArrayIndex(&element_index)); 335 result = SetOwnElement(boilerplate, element_index, value);
336 result = SetProperty(boilerplate, name, value, NONE); 336 } else {
337 Handle<String> name(String::cast(*key));
338 ASSERT(!name->AsArrayIndex(&element_index));
339 result = SetLocalPropertyIgnoreAttributes(boilerplate, name,
340 value, NONE);
341 }
337 } else if (key->ToArrayIndex(&element_index)) { 342 } else if (key->ToArrayIndex(&element_index)) {
338 // Array index (uint32). 343 // Array index (uint32).
339 result = SetElement(boilerplate, element_index, value); 344 result = SetOwnElement(boilerplate, element_index, value);
340 } else { 345 } else {
341 // Non-uint32 number. 346 // Non-uint32 number.
342 ASSERT(key->IsNumber()); 347 ASSERT(key->IsNumber());
343 double num = key->Number(); 348 double num = key->Number();
344 char arr[100]; 349 char arr[100];
345 Vector<char> buffer(arr, ARRAY_SIZE(arr)); 350 Vector<char> buffer(arr, ARRAY_SIZE(arr));
346 const char* str = DoubleToCString(num, buffer); 351 const char* str = DoubleToCString(num, buffer);
347 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); 352 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str));
348 result = SetProperty(boilerplate, name, value, NONE); 353 result = SetLocalPropertyIgnoreAttributes(boilerplate, name,
354 value, NONE);
349 } 355 }
350 // If setting the property on the boilerplate throws an 356 // If setting the property on the boilerplate throws an
351 // exception, the exception is converted to an empty handle in 357 // exception, the exception is converted to an empty handle in
352 // the handle based operations. In that case, we need to 358 // the handle based operations. In that case, we need to
353 // convert back to an exception. 359 // convert back to an exception.
354 if (result.is_null()) return result; 360 if (result.is_null()) return result;
355 } 361 }
356 } 362 }
357 363
358 return boilerplate; 364 return boilerplate;
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 if (!result->IsProperty()) { 637 if (!result->IsProperty()) {
632 Object* proto = obj->GetPrototype(); 638 Object* proto = obj->GetPrototype();
633 if (proto->IsJSObject() && 639 if (proto->IsJSObject() &&
634 JSObject::cast(proto)->map()->is_hidden_prototype()) 640 JSObject::cast(proto)->map()->is_hidden_prototype())
635 GetOwnPropertyImplementation(JSObject::cast(proto), 641 GetOwnPropertyImplementation(JSObject::cast(proto),
636 name, result); 642 name, result);
637 } 643 }
638 } 644 }
639 645
640 646
647 static bool CheckAccessException(LookupResult* result,
648 v8::AccessType access_type) {
649 if (result->type() == CALLBACKS) {
650 Object* callback = result->GetCallbackObject();
651 if (callback->IsAccessorInfo()) {
652 AccessorInfo* info = AccessorInfo::cast(callback);
653 bool can_access =
654 (access_type == v8::ACCESS_HAS &&
655 (info->all_can_read() || info->all_can_write())) ||
656 (access_type == v8::ACCESS_GET && info->all_can_read()) ||
657 (access_type == v8::ACCESS_SET && info->all_can_write());
658 return can_access;
659 }
660 }
661
662 return false;
663 }
664
665
666 static bool CheckAccess(JSObject* obj,
667 String* name,
668 LookupResult* result,
669 v8::AccessType access_type) {
670 ASSERT(result->IsProperty());
671
672 JSObject* holder = result->holder();
673 JSObject* current = obj;
674 while (true) {
675 if (current->IsAccessCheckNeeded() &&
676 !Top::MayNamedAccess(current, name, access_type)) {
677 // Access check callback denied the access, but some properties
678 // can have a special permissions which override callbacks descision
679 // (currently see v8::AccessControl).
680 break;
681 }
682
683 if (current == holder) {
684 return true;
685 }
686
687 current = JSObject::cast(current->GetPrototype());
688 }
689
690 // API callbacks can have per callback access exceptions.
691 switch (result->type()) {
692 case CALLBACKS: {
693 if (CheckAccessException(result, access_type)) {
694 return true;
695 }
696 break;
697 }
698 case INTERCEPTOR: {
699 // If the object has an interceptor, try real named properties.
700 // Overwrite the result to fetch the correct property later.
701 holder->LookupRealNamedProperty(name, result);
702 if (result->IsProperty()) {
703 if (CheckAccessException(result, access_type)) {
704 return true;
705 }
706 }
707 break;
708 }
709 default:
710 break;
711 }
712
713 Top::ReportFailedAccessCheck(current, access_type);
714 return false;
715 }
716
717
718 // TODO(1095): we should traverse hidden prototype hierachy as well.
719 static bool CheckElementAccess(JSObject* obj,
720 uint32_t index,
721 v8::AccessType access_type) {
722 if (obj->IsAccessCheckNeeded() &&
723 !Top::MayIndexedAccess(obj, index, access_type)) {
724 return false;
725 }
726
727 return true;
728 }
729
730
641 // Enumerator used as indices into the array returned from GetOwnProperty 731 // Enumerator used as indices into the array returned from GetOwnProperty
642 enum PropertyDescriptorIndices { 732 enum PropertyDescriptorIndices {
643 IS_ACCESSOR_INDEX, 733 IS_ACCESSOR_INDEX,
644 VALUE_INDEX, 734 VALUE_INDEX,
645 GETTER_INDEX, 735 GETTER_INDEX,
646 SETTER_INDEX, 736 SETTER_INDEX,
647 WRITABLE_INDEX, 737 WRITABLE_INDEX,
648 ENUMERABLE_INDEX, 738 ENUMERABLE_INDEX,
649 CONFIGURABLE_INDEX, 739 CONFIGURABLE_INDEX,
650 DESCRIPTOR_SIZE 740 DESCRIPTOR_SIZE
(...skipping 22 matching lines...) Expand all
673 case JSObject::UNDEFINED_ELEMENT: 763 case JSObject::UNDEFINED_ELEMENT:
674 return Heap::undefined_value(); 764 return Heap::undefined_value();
675 765
676 case JSObject::STRING_CHARACTER_ELEMENT: { 766 case JSObject::STRING_CHARACTER_ELEMENT: {
677 // Special handling of string objects according to ECMAScript 5 767 // Special handling of string objects according to ECMAScript 5
678 // 15.5.5.2. Note that this might be a string object with elements 768 // 15.5.5.2. Note that this might be a string object with elements
679 // other than the actual string value. This is covered by the 769 // other than the actual string value. This is covered by the
680 // subsequent cases. 770 // subsequent cases.
681 Handle<JSValue> js_value = Handle<JSValue>::cast(obj); 771 Handle<JSValue> js_value = Handle<JSValue>::cast(obj);
682 Handle<String> str(String::cast(js_value->value())); 772 Handle<String> str(String::cast(js_value->value()));
683 Handle<String> substr = SubString(str, index, index+1, NOT_TENURED); 773 Handle<String> substr = SubString(str, index, index + 1, NOT_TENURED);
684 774
685 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 775 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
686 elms->set(VALUE_INDEX, *substr); 776 elms->set(VALUE_INDEX, *substr);
687 elms->set(WRITABLE_INDEX, Heap::false_value()); 777 elms->set(WRITABLE_INDEX, Heap::false_value());
688 elms->set(ENUMERABLE_INDEX, Heap::false_value()); 778 elms->set(ENUMERABLE_INDEX, Heap::false_value());
689 elms->set(CONFIGURABLE_INDEX, Heap::false_value()); 779 elms->set(CONFIGURABLE_INDEX, Heap::false_value());
690 return *desc; 780 return *desc;
691 } 781 }
692 782
693 case JSObject::INTERCEPTED_ELEMENT: 783 case JSObject::INTERCEPTED_ELEMENT:
694 case JSObject::FAST_ELEMENT: { 784 case JSObject::FAST_ELEMENT: {
695 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 785 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
696 Handle<Object> element = GetElement(Handle<Object>(obj), index); 786 elms->set(VALUE_INDEX, *GetElement(obj, index));
697 elms->set(VALUE_INDEX, *element);
698 elms->set(WRITABLE_INDEX, Heap::true_value()); 787 elms->set(WRITABLE_INDEX, Heap::true_value());
699 elms->set(ENUMERABLE_INDEX, Heap::true_value()); 788 elms->set(ENUMERABLE_INDEX, Heap::true_value());
700 elms->set(CONFIGURABLE_INDEX, Heap::true_value()); 789 elms->set(CONFIGURABLE_INDEX, Heap::true_value());
701 return *desc; 790 return *desc;
702 } 791 }
703 792
704 case JSObject::DICTIONARY_ELEMENT: { 793 case JSObject::DICTIONARY_ELEMENT: {
705 NumberDictionary* dictionary = obj->element_dictionary(); 794 Handle<JSObject> holder = obj;
795 if (obj->IsJSGlobalProxy()) {
796 Object* proto = obj->GetPrototype();
797 if (proto->IsNull()) return Heap::undefined_value();
798 ASSERT(proto->IsJSGlobalObject());
799 holder = Handle<JSObject>(JSObject::cast(proto));
800 }
801 NumberDictionary* dictionary = holder->element_dictionary();
706 int entry = dictionary->FindEntry(index); 802 int entry = dictionary->FindEntry(index);
707 ASSERT(entry != NumberDictionary::kNotFound); 803 ASSERT(entry != NumberDictionary::kNotFound);
708 PropertyDetails details = dictionary->DetailsAt(entry); 804 PropertyDetails details = dictionary->DetailsAt(entry);
709 switch (details.type()) { 805 switch (details.type()) {
710 case CALLBACKS: { 806 case CALLBACKS: {
711 // This is an accessor property with getter and/or setter. 807 // This is an accessor property with getter and/or setter.
712 FixedArray* callbacks = 808 FixedArray* callbacks =
713 FixedArray::cast(dictionary->ValueAt(entry)); 809 FixedArray::cast(dictionary->ValueAt(entry));
714 elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); 810 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
715 elms->set(GETTER_INDEX, callbacks->get(0)); 811 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
716 elms->set(SETTER_INDEX, callbacks->get(1)); 812 elms->set(GETTER_INDEX, callbacks->get(0));
813 }
814 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
815 elms->set(SETTER_INDEX, callbacks->get(1));
816 }
717 break; 817 break;
718 } 818 }
719 case NORMAL: 819 case NORMAL:
720 // This is a data property. 820 // This is a data property.
721 elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); 821 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
722 elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); 822 elms->set(VALUE_INDEX, *GetElement(obj, index));
723 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); 823 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly()));
724 break; 824 break;
725 default: 825 default:
726 UNREACHABLE(); 826 UNREACHABLE();
727 break; 827 break;
728 } 828 }
729 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); 829 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum()));
730 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); 830 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete()));
731 return *desc; 831 return *desc;
732 } 832 }
733 } 833 }
734 } 834 }
735 835
736 // Use recursive implementation to also traverse hidden prototypes 836 // Use recursive implementation to also traverse hidden prototypes
737 GetOwnPropertyImplementation(*obj, *name, &result); 837 GetOwnPropertyImplementation(*obj, *name, &result);
738 838
739 if (!result.IsProperty()) { 839 if (!result.IsProperty()) {
740 return Heap::undefined_value(); 840 return Heap::undefined_value();
741 } 841 }
742 if (result.type() == CALLBACKS) { 842
743 Object* structure = result.GetCallbackObject(); 843 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
744 if (structure->IsProxy() || structure->IsAccessorInfo()) { 844 return Heap::false_value();
745 // Property that is internally implemented as a callback or
746 // an API defined callback.
747 Object* value;
748 { MaybeObject* maybe_value = obj->GetPropertyWithCallback(
749 *obj, structure, *name, result.holder());
750 if (!maybe_value->ToObject(&value)) return maybe_value;
751 }
752 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
753 elms->set(VALUE_INDEX, value);
754 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
755 } else if (structure->IsFixedArray()) {
756 // __defineGetter__/__defineSetter__ callback.
757 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
758 elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0));
759 elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1));
760 } else {
761 return Heap::undefined_value();
762 }
763 } else {
764 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
765 elms->set(VALUE_INDEX, result.GetLazyValue());
766 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
767 } 845 }
768 846
769 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); 847 elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum()));
770 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); 848 elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete()));
849
850 bool is_js_accessor = (result.type() == CALLBACKS) &&
851 (result.GetCallbackObject()->IsFixedArray());
852
853 if (is_js_accessor) {
854 // __defineGetter__/__defineSetter__ callback.
855 elms->set(IS_ACCESSOR_INDEX, Heap::true_value());
856
857 FixedArray* structure = FixedArray::cast(result.GetCallbackObject());
858 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
859 elms->set(GETTER_INDEX, structure->get(0));
860 }
861 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
862 elms->set(SETTER_INDEX, structure->get(1));
863 }
864 } else {
865 elms->set(IS_ACCESSOR_INDEX, Heap::false_value());
866 elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly()));
867
868 PropertyAttributes attrs;
869 Object* value;
870 // GetProperty will check access and report any violations.
871 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
872 if (!maybe_value->ToObject(&value)) return maybe_value;
873 }
874 elms->set(VALUE_INDEX, value);
875 }
876
771 return *desc; 877 return *desc;
772 } 878 }
773 879
774 880
775 static MaybeObject* Runtime_PreventExtensions(Arguments args) { 881 static MaybeObject* Runtime_PreventExtensions(Arguments args) {
776 ASSERT(args.length() == 1); 882 ASSERT(args.length() == 1);
777 CONVERT_CHECKED(JSObject, obj, args[0]); 883 CONVERT_CHECKED(JSObject, obj, args[0]);
778 return obj->PreventExtensions(); 884 return obj->PreventExtensions();
779 } 885 }
780 886
887
781 static MaybeObject* Runtime_IsExtensible(Arguments args) { 888 static MaybeObject* Runtime_IsExtensible(Arguments args) {
782 ASSERT(args.length() == 1); 889 ASSERT(args.length() == 1);
783 CONVERT_CHECKED(JSObject, obj, args[0]); 890 CONVERT_CHECKED(JSObject, obj, args[0]);
784 return obj->map()->is_extensible() ? Heap::true_value() 891 if (obj->IsJSGlobalProxy()) {
892 Object* proto = obj->GetPrototype();
893 if (proto->IsNull()) return Heap::false_value();
894 ASSERT(proto->IsJSGlobalObject());
895 obj = JSObject::cast(proto);
896 }
897 return obj->map()->is_extensible() ? Heap::true_value()
785 : Heap::false_value(); 898 : Heap::false_value();
786 } 899 }
787 900
788 901
789 static MaybeObject* Runtime_RegExpCompile(Arguments args) { 902 static MaybeObject* Runtime_RegExpCompile(Arguments args) {
790 HandleScope scope; 903 HandleScope scope;
791 ASSERT(args.length() == 3); 904 ASSERT(args.length() == 3);
792 CONVERT_ARG_CHECKED(JSRegExp, re, 0); 905 CONVERT_ARG_CHECKED(JSRegExp, re, 0);
793 CONVERT_ARG_CHECKED(String, pattern, 1); 906 CONVERT_ARG_CHECKED(String, pattern, 1);
794 CONVERT_ARG_CHECKED(String, flags, 2); 907 CONVERT_ARG_CHECKED(String, flags, 2);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 // that claims the property is absent. 1082 // that claims the property is absent.
970 1083
971 // Check for conflicting re-declarations. We cannot have 1084 // Check for conflicting re-declarations. We cannot have
972 // conflicting types in case of intercepted properties because 1085 // conflicting types in case of intercepted properties because
973 // they are absent. 1086 // they are absent.
974 if (lookup.type() != INTERCEPTOR && 1087 if (lookup.type() != INTERCEPTOR &&
975 (lookup.IsReadOnly() || is_const_property)) { 1088 (lookup.IsReadOnly() || is_const_property)) {
976 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; 1089 const char* type = (lookup.IsReadOnly()) ? "const" : "var";
977 return ThrowRedeclarationError(type, name); 1090 return ThrowRedeclarationError(type, name);
978 } 1091 }
979 SetProperty(global, name, value, attributes); 1092 RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes));
980 } else { 1093 } else {
981 // If a property with this name does not already exist on the 1094 // If a property with this name does not already exist on the
982 // global object add the property locally. We take special 1095 // global object add the property locally. We take special
983 // precautions to always add it as a local property even in case 1096 // precautions to always add it as a local property even in case
984 // of callbacks in the prototype chain (this rules out using 1097 // of callbacks in the prototype chain (this rules out using
985 // SetProperty). Also, we must use the handle-based version to 1098 // SetProperty). Also, we must use the handle-based version to
986 // avoid GC issues. 1099 // avoid GC issues.
987 IgnoreAttributesAndSetLocalProperty(global, name, value, attributes); 1100 RETURN_IF_EMPTY_HANDLE(
1101 SetLocalPropertyIgnoreAttributes(global, name, value, attributes));
988 } 1102 }
989 } 1103 }
990 1104
1105 ASSERT(!Top::has_pending_exception());
991 return Heap::undefined_value(); 1106 return Heap::undefined_value();
992 } 1107 }
993 1108
994 1109
995 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) { 1110 static MaybeObject* Runtime_DeclareContextSlot(Arguments args) {
996 HandleScope scope; 1111 HandleScope scope;
997 ASSERT(args.length() == 4); 1112 ASSERT(args.length() == 4);
998 1113
999 CONVERT_ARG_CHECKED(Context, context, 0); 1114 CONVERT_ARG_CHECKED(Context, context, 0);
1000 Handle<String> name(String::cast(args[1])); 1115 Handle<String> name(String::cast(args[1]));
(...skipping 29 matching lines...) Expand all
1030 // the function context or the arguments object. 1145 // the function context or the arguments object.
1031 if (holder->IsContext()) { 1146 if (holder->IsContext()) {
1032 ASSERT(holder.is_identical_to(context)); 1147 ASSERT(holder.is_identical_to(context));
1033 if (((attributes & READ_ONLY) == 0) || 1148 if (((attributes & READ_ONLY) == 0) ||
1034 context->get(index)->IsTheHole()) { 1149 context->get(index)->IsTheHole()) {
1035 context->set(index, *initial_value); 1150 context->set(index, *initial_value);
1036 } 1151 }
1037 } else { 1152 } else {
1038 // The holder is an arguments object. 1153 // The holder is an arguments object.
1039 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); 1154 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1040 SetElement(arguments, index, initial_value); 1155 Handle<Object> result = SetElement(arguments, index, initial_value);
1156 if (result.is_null()) return Failure::Exception();
1041 } 1157 }
1042 } else { 1158 } else {
1043 // Slow case: The property is not in the FixedArray part of the context. 1159 // Slow case: The property is not in the FixedArray part of the context.
1044 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1160 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1045 SetProperty(context_ext, name, initial_value, mode); 1161 RETURN_IF_EMPTY_HANDLE(
1162 SetProperty(context_ext, name, initial_value, mode));
1046 } 1163 }
1047 } 1164 }
1048 1165
1049 } else { 1166 } else {
1050 // The property is not in the function context. It needs to be 1167 // The property is not in the function context. It needs to be
1051 // "declared" in the function context's extension context, or in the 1168 // "declared" in the function context's extension context, or in the
1052 // global context. 1169 // global context.
1053 Handle<JSObject> context_ext; 1170 Handle<JSObject> context_ext;
1054 if (context->has_extension()) { 1171 if (context->has_extension()) {
1055 // The function context's extension context exists - use it. 1172 // The function context's extension context exists - use it.
1056 context_ext = Handle<JSObject>(context->extension()); 1173 context_ext = Handle<JSObject>(context->extension());
1057 } else { 1174 } else {
1058 // The function context's extension context does not exists - allocate 1175 // The function context's extension context does not exists - allocate
1059 // it. 1176 // it.
1060 context_ext = Factory::NewJSObject(Top::context_extension_function()); 1177 context_ext = Factory::NewJSObject(Top::context_extension_function());
1061 // And store it in the extension slot. 1178 // And store it in the extension slot.
1062 context->set_extension(*context_ext); 1179 context->set_extension(*context_ext);
1063 } 1180 }
1064 ASSERT(*context_ext != NULL); 1181 ASSERT(*context_ext != NULL);
1065 1182
1066 // Declare the property by setting it to the initial value if provided, 1183 // Declare the property by setting it to the initial value if provided,
1067 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for 1184 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
1068 // constant declarations). 1185 // constant declarations).
1069 ASSERT(!context_ext->HasLocalProperty(*name)); 1186 ASSERT(!context_ext->HasLocalProperty(*name));
1070 Handle<Object> value(Heap::undefined_value()); 1187 Handle<Object> value(Heap::undefined_value());
1071 if (*initial_value != NULL) value = initial_value; 1188 if (*initial_value != NULL) value = initial_value;
1072 SetProperty(context_ext, name, value, mode); 1189 RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, mode));
1073 ASSERT(context_ext->GetLocalPropertyAttribute(*name) == mode);
1074 } 1190 }
1075 1191
1076 return Heap::undefined_value(); 1192 return Heap::undefined_value();
1077 } 1193 }
1078 1194
1079 1195
1080 static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) { 1196 static MaybeObject* Runtime_InitializeVarGlobal(Arguments args) {
1081 NoHandleAllocation nha; 1197 NoHandleAllocation nha;
1082 1198
1083 // Determine if we need to assign to the variable if it already 1199 // Determine if we need to assign to the variable if it already
1084 // exists (based on the number of arguments). 1200 // exists (based on the number of arguments).
1085 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); 1201 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
1086 bool assign = args.length() == 2; 1202 bool assign = args.length() == 2;
1087 1203
1088 CONVERT_ARG_CHECKED(String, name, 0); 1204 CONVERT_ARG_CHECKED(String, name, 0);
1089 GlobalObject* global = Top::context()->global(); 1205 GlobalObject* global = Top::context()->global();
1090 1206
1091 // According to ECMA-262, section 12.2, page 62, the property must 1207 // According to ECMA-262, section 12.2, page 62, the property must
1092 // not be deletable. 1208 // not be deletable.
1093 PropertyAttributes attributes = DONT_DELETE; 1209 PropertyAttributes attributes = DONT_DELETE;
1094 1210
1095 // Lookup the property locally in the global object. If it isn't 1211 // Lookup the property locally in the global object. If it isn't
1096 // there, there is a property with this name in the prototype chain. 1212 // there, there is a property with this name in the prototype chain.
1097 // We follow Safari and Firefox behavior and only set the property 1213 // We follow Safari and Firefox behavior and only set the property
1098 // locally if there is an explicit initialization value that we have 1214 // locally if there is an explicit initialization value that we have
1099 // to assign to the property. When adding the property we take 1215 // to assign to the property. When adding the property we take
1100 // special precautions to always add it as a local property even in 1216 // special precautions to always add it as a local property even in
1101 // case of callbacks in the prototype chain (this rules out using 1217 // case of callbacks in the prototype chain (this rules out using
1102 // SetProperty). We have IgnoreAttributesAndSetLocalProperty for 1218 // SetProperty). We have SetLocalPropertyIgnoreAttributes for
1103 // this. 1219 // this.
1104 // Note that objects can have hidden prototypes, so we need to traverse 1220 // Note that objects can have hidden prototypes, so we need to traverse
1105 // the whole chain of hidden prototypes to do a 'local' lookup. 1221 // the whole chain of hidden prototypes to do a 'local' lookup.
1106 JSObject* real_holder = global; 1222 JSObject* real_holder = global;
1107 LookupResult lookup; 1223 LookupResult lookup;
1108 while (true) { 1224 while (true) {
1109 real_holder->LocalLookup(*name, &lookup); 1225 real_holder->LocalLookup(*name, &lookup);
1110 if (lookup.IsProperty()) { 1226 if (lookup.IsProperty()) {
1111 // Determine if this is a redeclaration of something read-only. 1227 // Determine if this is a redeclaration of something read-only.
1112 if (lookup.IsReadOnly()) { 1228 if (lookup.IsReadOnly()) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1155 break; 1271 break;
1156 1272
1157 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) 1273 if (!JSObject::cast(proto)->map()->is_hidden_prototype())
1158 break; 1274 break;
1159 1275
1160 real_holder = JSObject::cast(proto); 1276 real_holder = JSObject::cast(proto);
1161 } 1277 }
1162 1278
1163 global = Top::context()->global(); 1279 global = Top::context()->global();
1164 if (assign) { 1280 if (assign) {
1165 return global->IgnoreAttributesAndSetLocalProperty(*name, 1281 return global->SetLocalPropertyIgnoreAttributes(*name,
1166 args[1], 1282 args[1],
1167 attributes); 1283 attributes);
1168 } 1284 }
1169 return Heap::undefined_value(); 1285 return Heap::undefined_value();
1170 } 1286 }
1171 1287
1172 1288
1173 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) { 1289 static MaybeObject* Runtime_InitializeConstGlobal(Arguments args) {
1174 // All constants are declared with an initial value. The name 1290 // All constants are declared with an initial value. The name
1175 // of the constant is the first argument and the initial value 1291 // of the constant is the first argument and the initial value
1176 // is the second. 1292 // is the second.
1177 RUNTIME_ASSERT(args.length() == 2); 1293 RUNTIME_ASSERT(args.length() == 2);
1178 CONVERT_ARG_CHECKED(String, name, 0); 1294 CONVERT_ARG_CHECKED(String, name, 0);
1179 Handle<Object> value = args.at<Object>(1); 1295 Handle<Object> value = args.at<Object>(1);
1180 1296
1181 // Get the current global object from top. 1297 // Get the current global object from top.
1182 GlobalObject* global = Top::context()->global(); 1298 GlobalObject* global = Top::context()->global();
1183 1299
1184 // According to ECMA-262, section 12.2, page 62, the property must 1300 // According to ECMA-262, section 12.2, page 62, the property must
1185 // not be deletable. Since it's a const, it must be READ_ONLY too. 1301 // not be deletable. Since it's a const, it must be READ_ONLY too.
1186 PropertyAttributes attributes = 1302 PropertyAttributes attributes =
1187 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); 1303 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
1188 1304
1189 // Lookup the property locally in the global object. If it isn't 1305 // Lookup the property locally in the global object. If it isn't
1190 // there, we add the property and take special precautions to always 1306 // there, we add the property and take special precautions to always
1191 // add it as a local property even in case of callbacks in the 1307 // add it as a local property even in case of callbacks in the
1192 // prototype chain (this rules out using SetProperty). 1308 // prototype chain (this rules out using SetProperty).
1193 // We use IgnoreAttributesAndSetLocalProperty instead 1309 // We use SetLocalPropertyIgnoreAttributes instead
1194 LookupResult lookup; 1310 LookupResult lookup;
1195 global->LocalLookup(*name, &lookup); 1311 global->LocalLookup(*name, &lookup);
1196 if (!lookup.IsProperty()) { 1312 if (!lookup.IsProperty()) {
1197 return global->IgnoreAttributesAndSetLocalProperty(*name, 1313 return global->SetLocalPropertyIgnoreAttributes(*name,
1198 *value, 1314 *value,
1199 attributes); 1315 attributes);
1200 } 1316 }
1201 1317
1202 // Determine if this is a redeclaration of something not 1318 // Determine if this is a redeclaration of something not
1203 // read-only. In case the result is hidden behind an interceptor we 1319 // read-only. In case the result is hidden behind an interceptor we
1204 // need to ask it for the property attributes. 1320 // need to ask it for the property attributes.
1205 if (!lookup.IsReadOnly()) { 1321 if (!lookup.IsReadOnly()) {
1206 if (lookup.type() != INTERCEPTOR) { 1322 if (lookup.type() != INTERCEPTOR) {
1207 return ThrowRedeclarationError("var", name); 1323 return ThrowRedeclarationError("var", name);
1208 } 1324 }
1209 1325
1210 PropertyAttributes intercepted = global->GetPropertyAttribute(*name); 1326 PropertyAttributes intercepted = global->GetPropertyAttribute(*name);
1211 1327
1212 // Throw re-declaration error if the intercepted property is present 1328 // Throw re-declaration error if the intercepted property is present
1213 // but not read-only. 1329 // but not read-only.
1214 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { 1330 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
1215 return ThrowRedeclarationError("var", name); 1331 return ThrowRedeclarationError("var", name);
1216 } 1332 }
1217 1333
1218 // Restore global object from context (in case of GC) and continue 1334 // Restore global object from context (in case of GC) and continue
1219 // with setting the value because the property is either absent or 1335 // with setting the value because the property is either absent or
1220 // read-only. We also have to do redo the lookup. 1336 // read-only. We also have to do redo the lookup.
1221 HandleScope handle_scope; 1337 HandleScope handle_scope;
1222 Handle<GlobalObject>global(Top::context()->global()); 1338 Handle<GlobalObject> global(Top::context()->global());
1223 1339
1224 // BUG 1213579: Handle the case where we have to set a read-only 1340 // BUG 1213575: Handle the case where we have to set a read-only
1225 // property through an interceptor and only do it if it's 1341 // property through an interceptor and only do it if it's
1226 // uninitialized, e.g. the hole. Nirk... 1342 // uninitialized, e.g. the hole. Nirk...
1227 SetProperty(global, name, value, attributes); 1343 RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes));
1228 return *value; 1344 return *value;
1229 } 1345 }
1230 1346
1231 // Set the value, but only we're assigning the initial value to a 1347 // Set the value, but only we're assigning the initial value to a
1232 // constant. For now, we determine this by checking if the 1348 // constant. For now, we determine this by checking if the
1233 // current value is the hole. 1349 // current value is the hole.
1234 PropertyType type = lookup.type(); 1350 PropertyType type = lookup.type();
1235 if (type == FIELD) { 1351 if (type == FIELD) {
1236 FixedArray* properties = global->properties(); 1352 FixedArray* properties = global->properties();
1237 int index = lookup.GetFieldIndex(); 1353 int index = lookup.GetFieldIndex();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); 1415 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1300 SetElement(arguments, index, value); 1416 SetElement(arguments, index, value);
1301 } 1417 }
1302 return *value; 1418 return *value;
1303 } 1419 }
1304 1420
1305 // The property could not be found, we introduce it in the global 1421 // The property could not be found, we introduce it in the global
1306 // context. 1422 // context.
1307 if (attributes == ABSENT) { 1423 if (attributes == ABSENT) {
1308 Handle<JSObject> global = Handle<JSObject>(Top::context()->global()); 1424 Handle<JSObject> global = Handle<JSObject>(Top::context()->global());
1309 SetProperty(global, name, value, NONE); 1425 RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, NONE));
1310 return *value; 1426 return *value;
1311 } 1427 }
1312 1428
1313 // The property was present in a context extension object. 1429 // The property was present in a context extension object.
1314 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1430 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1315 1431
1316 if (*context_ext == context->extension()) { 1432 if (*context_ext == context->extension()) {
1317 // This is the property that was introduced by the const 1433 // This is the property that was introduced by the const
1318 // declaration. Set it if it hasn't been set before. NOTE: We 1434 // declaration. Set it if it hasn't been set before. NOTE: We
1319 // cannot use GetProperty() to get the current value as it 1435 // cannot use GetProperty() to get the current value as it
(...skipping 16 matching lines...) Expand all
1336 } 1452 }
1337 } else { 1453 } else {
1338 // We should not reach here. Any real, named property should be 1454 // We should not reach here. Any real, named property should be
1339 // either a field or a dictionary slot. 1455 // either a field or a dictionary slot.
1340 UNREACHABLE(); 1456 UNREACHABLE();
1341 } 1457 }
1342 } else { 1458 } else {
1343 // The property was found in a different context extension object. 1459 // The property was found in a different context extension object.
1344 // Set it if it is not a read-only property. 1460 // Set it if it is not a read-only property.
1345 if ((attributes & READ_ONLY) == 0) { 1461 if ((attributes & READ_ONLY) == 0) {
1346 Handle<Object> set = SetProperty(context_ext, name, value, attributes); 1462 RETURN_IF_EMPTY_HANDLE(
1347 // Setting a property might throw an exception. Exceptions 1463 SetProperty(context_ext, name, value, attributes));
1348 // are converted to empty handles in handle operations. We
1349 // need to convert back to exceptions here.
1350 if (set.is_null()) {
1351 ASSERT(Top::has_pending_exception());
1352 return Failure::Exception();
1353 }
1354 } 1464 }
1355 } 1465 }
1356 1466
1357 return *value; 1467 return *value;
1358 } 1468 }
1359 1469
1360 1470
1361 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties( 1471 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties(
1362 Arguments args) { 1472 Arguments args) {
1363 HandleScope scope; 1473 HandleScope scope;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1460 } 1570 }
1461 1571
1462 // Map has changed, so use generic, but slower, method. Since these 1572 // Map has changed, so use generic, but slower, method. Since these
1463 // properties were all added as DONT_DELETE they must be present and 1573 // properties were all added as DONT_DELETE they must be present and
1464 // normal so no failures can be expected. 1574 // normal so no failures can be expected.
1465 PropertyAttributes final = 1575 PropertyAttributes final =
1466 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE); 1576 static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
1467 PropertyAttributes writable = 1577 PropertyAttributes writable =
1468 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE); 1578 static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
1469 MaybeObject* result; 1579 MaybeObject* result;
1470 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::source_symbol(), 1580 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::source_symbol(),
1471 source, 1581 source,
1472 final); 1582 final);
1473 ASSERT(!result->IsFailure()); 1583 ASSERT(!result->IsFailure());
1474 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::global_symbol(), 1584 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::global_symbol(),
1475 global, 1585 global,
1476 final); 1586 final);
1477 ASSERT(!result->IsFailure()); 1587 ASSERT(!result->IsFailure());
1478 result = 1588 result =
1479 regexp->IgnoreAttributesAndSetLocalProperty(Heap::ignore_case_symbol(), 1589 regexp->SetLocalPropertyIgnoreAttributes(Heap::ignore_case_symbol(),
1480 ignoreCase, 1590 ignoreCase,
1481 final); 1591 final);
1482 ASSERT(!result->IsFailure()); 1592 ASSERT(!result->IsFailure());
1483 result = regexp->IgnoreAttributesAndSetLocalProperty(Heap::multiline_symbol(), 1593 result = regexp->SetLocalPropertyIgnoreAttributes(Heap::multiline_symbol(),
1484 multiline, 1594 multiline,
1485 final); 1595 final);
1486 ASSERT(!result->IsFailure()); 1596 ASSERT(!result->IsFailure());
1487 result = 1597 result =
1488 regexp->IgnoreAttributesAndSetLocalProperty(Heap::last_index_symbol(), 1598 regexp->SetLocalPropertyIgnoreAttributes(Heap::last_index_symbol(),
1489 Smi::FromInt(0), 1599 Smi::FromInt(0),
1490 writable); 1600 writable);
1491 ASSERT(!result->IsFailure()); 1601 ASSERT(!result->IsFailure());
1492 USE(result); 1602 USE(result);
1493 return regexp; 1603 return regexp;
1494 } 1604 }
1495 1605
1496 1606
1497 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) { 1607 static MaybeObject* Runtime_FinishArrayPrototypeSetup(Arguments args) {
1498 HandleScope scope; 1608 HandleScope scope;
1499 ASSERT(args.length() == 1); 1609 ASSERT(args.length() == 1);
1500 CONVERT_ARG_CHECKED(JSArray, prototype, 0); 1610 CONVERT_ARG_CHECKED(JSArray, prototype, 0);
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 target->ReplaceCode(shared->code()); 1846 target->ReplaceCode(shared->code());
1737 target->shared()->set_scope_info(shared->scope_info()); 1847 target->shared()->set_scope_info(shared->scope_info());
1738 target->shared()->set_length(shared->length()); 1848 target->shared()->set_length(shared->length());
1739 target->shared()->set_formal_parameter_count( 1849 target->shared()->set_formal_parameter_count(
1740 shared->formal_parameter_count()); 1850 shared->formal_parameter_count());
1741 // Set the source code of the target function to undefined. 1851 // Set the source code of the target function to undefined.
1742 // SetCode is only used for built-in constructors like String, 1852 // SetCode is only used for built-in constructors like String,
1743 // Array, and Object, and some web code 1853 // Array, and Object, and some web code
1744 // doesn't like seeing source code for constructors. 1854 // doesn't like seeing source code for constructors.
1745 target->shared()->set_script(Heap::undefined_value()); 1855 target->shared()->set_script(Heap::undefined_value());
1856 target->shared()->code()->set_optimizable(false);
1746 // Clear the optimization hints related to the compiled code as these are no 1857 // Clear the optimization hints related to the compiled code as these are no
1747 // longer valid when the code is overwritten. 1858 // longer valid when the code is overwritten.
1748 target->shared()->ClearThisPropertyAssignmentsInfo(); 1859 target->shared()->ClearThisPropertyAssignmentsInfo();
1749 context = Handle<Context>(fun->context()); 1860 context = Handle<Context>(fun->context());
1750 1861
1751 // Make sure we get a fresh copy of the literal vector to avoid 1862 // Make sure we get a fresh copy of the literal vector to avoid
1752 // cross context contamination. 1863 // cross context contamination.
1753 int number_of_literals = fun->NumberOfLiterals(); 1864 int number_of_literals = fun->NumberOfLiterals();
1754 Handle<FixedArray> literals = 1865 Handle<FixedArray> literals =
1755 Factory::NewFixedArray(number_of_literals, TENURED); 1866 Factory::NewFixedArray(number_of_literals, TENURED);
(...skipping 1721 matching lines...) Expand 10 before | Expand all | Expand 10 after
3477 value = JSGlobalPropertyCell::cast(value)->value(); 3588 value = JSGlobalPropertyCell::cast(value)->value();
3478 if (!value->IsTheHole()) return value; 3589 if (!value->IsTheHole()) return value;
3479 // If value is the hole do the general lookup. 3590 // If value is the hole do the general lookup.
3480 } 3591 }
3481 } 3592 }
3482 } else if (args[0]->IsString() && args[1]->IsSmi()) { 3593 } else if (args[0]->IsString() && args[1]->IsSmi()) {
3483 // Fast case for string indexing using [] with a smi index. 3594 // Fast case for string indexing using [] with a smi index.
3484 HandleScope scope; 3595 HandleScope scope;
3485 Handle<String> str = args.at<String>(0); 3596 Handle<String> str = args.at<String>(0);
3486 int index = Smi::cast(args[1])->value(); 3597 int index = Smi::cast(args[1])->value();
3487 Handle<Object> result = GetCharAt(str, index); 3598 if (index >= 0 && index < str->length()) {
3488 return *result; 3599 Handle<Object> result = GetCharAt(str, index);
3600 return *result;
3601 }
3489 } 3602 }
3490 3603
3491 // Fall back to GetObjectProperty. 3604 // Fall back to GetObjectProperty.
3492 return Runtime::GetObjectProperty(args.at<Object>(0), 3605 return Runtime::GetObjectProperty(args.at<Object>(0),
3493 args.at<Object>(1)); 3606 args.at<Object>(1));
3494 } 3607 }
3495 3608
3496 3609 // Implements part of 8.12.9 DefineOwnProperty.
3610 // There are 3 cases that lead here:
3611 // Step 4b - define a new accessor property.
3612 // Steps 9c & 12 - replace an existing data property with an accessor property.
3613 // Step 12 - update an existing accessor property with an accessor or generic
3614 // descriptor.
3497 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { 3615 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) {
3498 ASSERT(args.length() == 5); 3616 ASSERT(args.length() == 5);
3499 HandleScope scope; 3617 HandleScope scope;
3500 CONVERT_ARG_CHECKED(JSObject, obj, 0); 3618 CONVERT_ARG_CHECKED(JSObject, obj, 0);
3501 CONVERT_CHECKED(String, name, args[1]); 3619 CONVERT_CHECKED(String, name, args[1]);
3502 CONVERT_CHECKED(Smi, flag_setter, args[2]); 3620 CONVERT_CHECKED(Smi, flag_setter, args[2]);
3503 Object* fun = args[3]; 3621 Object* fun = args[3];
3504 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); 3622 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined());
3505 CONVERT_CHECKED(Smi, flag_attr, args[4]); 3623 CONVERT_CHECKED(Smi, flag_attr, args[4]);
3506 int unchecked = flag_attr->value(); 3624 int unchecked = flag_attr->value();
(...skipping 11 matching lines...) Expand all
3518 || result.type() == CONSTANT_FUNCTION)) { 3636 || result.type() == CONSTANT_FUNCTION)) {
3519 Object* ok; 3637 Object* ok;
3520 { MaybeObject* maybe_ok = 3638 { MaybeObject* maybe_ok =
3521 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); 3639 obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
3522 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 3640 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3523 } 3641 }
3524 } 3642 }
3525 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); 3643 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr);
3526 } 3644 }
3527 3645
3646 // Implements part of 8.12.9 DefineOwnProperty.
3647 // There are 3 cases that lead here:
3648 // Step 4a - define a new data property.
3649 // Steps 9b & 12 - replace an existing accessor property with a data property.
3650 // Step 12 - update an existing data property with a data or generic
3651 // descriptor.
3528 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { 3652 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) {
3529 ASSERT(args.length() == 4); 3653 ASSERT(args.length() == 4);
3530 HandleScope scope; 3654 HandleScope scope;
3531 CONVERT_ARG_CHECKED(JSObject, js_object, 0); 3655 CONVERT_ARG_CHECKED(JSObject, js_object, 0);
3532 CONVERT_ARG_CHECKED(String, name, 1); 3656 CONVERT_ARG_CHECKED(String, name, 1);
3533 Handle<Object> obj_value = args.at<Object>(2); 3657 Handle<Object> obj_value = args.at<Object>(2);
3534 3658
3535 CONVERT_CHECKED(Smi, flag, args[3]); 3659 CONVERT_CHECKED(Smi, flag, args[3]);
3536 int unchecked = flag->value(); 3660 int unchecked = flag->value();
3537 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 3661 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
3538 3662
3539 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 3663 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
3540 3664
3541 // Check if this is an element. 3665 // Check if this is an element.
3542 uint32_t index; 3666 uint32_t index;
3543 bool is_element = name->AsArrayIndex(&index); 3667 bool is_element = name->AsArrayIndex(&index);
3544 3668
3545 // Special case for elements if any of the flags are true. 3669 // Special case for elements if any of the flags are true.
3546 // If elements are in fast case we always implicitly assume that: 3670 // If elements are in fast case we always implicitly assume that:
3547 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. 3671 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
3548 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && 3672 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) &&
3549 is_element) { 3673 is_element) {
3550 // Normalize the elements to enable attributes on the property. 3674 // Normalize the elements to enable attributes on the property.
3675 if (js_object->IsJSGlobalProxy()) {
3676 Handle<Object> proto(js_object->GetPrototype());
3677 // If proxy is detached, ignore the assignment. Alternatively,
3678 // we could throw an exception.
3679 if (proto->IsNull()) return *obj_value;
3680 js_object = Handle<JSObject>::cast(proto);
3681 }
3551 NormalizeElements(js_object); 3682 NormalizeElements(js_object);
3552 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); 3683 Handle<NumberDictionary> dictionary(js_object->element_dictionary());
3553 // Make sure that we never go back to fast case. 3684 // Make sure that we never go back to fast case.
3554 dictionary->set_requires_slow_elements(); 3685 dictionary->set_requires_slow_elements();
3555 PropertyDetails details = PropertyDetails(attr, NORMAL); 3686 PropertyDetails details = PropertyDetails(attr, NORMAL);
3556 NumberDictionarySet(dictionary, index, obj_value, details); 3687 NumberDictionarySet(dictionary, index, obj_value, details);
3688 return *obj_value;
3557 } 3689 }
3558 3690
3559 LookupResult result; 3691 LookupResult result;
3560 js_object->LookupRealNamedProperty(*name, &result); 3692 js_object->LookupRealNamedProperty(*name, &result);
3561 3693
3562 // Take special care when attributes are different and there is already 3694 // Take special care when attributes are different and there is already
3563 // a property. For simplicity we normalize the property which enables us 3695 // a property. For simplicity we normalize the property which enables us
3564 // to not worry about changing the instance_descriptor and creating a new 3696 // to not worry about changing the instance_descriptor and creating a new
3565 // map. The current version of SetObjectProperty does not handle attributes 3697 // map. The current version of SetObjectProperty does not handle attributes
3566 // correctly in the case where a property is a field and is reset with 3698 // correctly in the case where a property is a field and is reset with
3567 // new attributes. 3699 // new attributes.
3568 if (result.IsProperty() && 3700 if (result.IsProperty() &&
3569 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { 3701 (attr != result.GetAttributes() || result.type() == CALLBACKS)) {
3570 // New attributes - normalize to avoid writing to instance descriptor 3702 // New attributes - normalize to avoid writing to instance descriptor
3703 if (js_object->IsJSGlobalProxy()) {
3704 // Since the result is a property, the prototype will exist so
3705 // we don't have to check for null.
3706 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
3707 }
3571 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 3708 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
3572 // Use IgnoreAttributes version since a readonly property may be 3709 // Use IgnoreAttributes version since a readonly property may be
3573 // overridden and SetProperty does not allow this. 3710 // overridden and SetProperty does not allow this.
3574 return js_object->IgnoreAttributesAndSetLocalProperty(*name, 3711 return js_object->SetLocalPropertyIgnoreAttributes(*name,
3575 *obj_value, 3712 *obj_value,
3576 attr); 3713 attr);
3577 } 3714 }
3578 3715
3579 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); 3716 return Runtime::ForceSetObjectProperty(js_object, name, obj_value, attr);
3580 } 3717 }
3581 3718
3582 3719
3583 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object, 3720 MaybeObject* Runtime::SetObjectProperty(Handle<Object> object,
3584 Handle<Object> key, 3721 Handle<Object> key,
3585 Handle<Object> value, 3722 Handle<Object> value,
3586 PropertyAttributes attr) { 3723 PropertyAttributes attr) {
3587 HandleScope scope; 3724 HandleScope scope;
3588 3725
3589 if (object->IsUndefined() || object->IsNull()) { 3726 if (object->IsUndefined() || object->IsNull()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3667 3804
3668 return js_object->SetElement(index, *value); 3805 return js_object->SetElement(index, *value);
3669 } 3806 }
3670 3807
3671 if (key->IsString()) { 3808 if (key->IsString()) {
3672 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 3809 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
3673 return js_object->SetElement(index, *value); 3810 return js_object->SetElement(index, *value);
3674 } else { 3811 } else {
3675 Handle<String> key_string = Handle<String>::cast(key); 3812 Handle<String> key_string = Handle<String>::cast(key);
3676 key_string->TryFlatten(); 3813 key_string->TryFlatten();
3677 return js_object->IgnoreAttributesAndSetLocalProperty(*key_string, 3814 return js_object->SetLocalPropertyIgnoreAttributes(*key_string,
3678 *value, 3815 *value,
3679 attr); 3816 attr);
3680 } 3817 }
3681 } 3818 }
3682 3819
3683 // Call-back into JavaScript to convert the key to a string. 3820 // Call-back into JavaScript to convert the key to a string.
3684 bool has_pending_exception = false; 3821 bool has_pending_exception = false;
3685 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 3822 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
3686 if (has_pending_exception) return Failure::Exception(); 3823 if (has_pending_exception) return Failure::Exception();
3687 Handle<String> name = Handle<String>::cast(converted); 3824 Handle<String> name = Handle<String>::cast(converted);
3688 3825
3689 if (name->AsArrayIndex(&index)) { 3826 if (name->AsArrayIndex(&index)) {
3690 return js_object->SetElement(index, *value); 3827 return js_object->SetElement(index, *value);
3691 } else { 3828 } else {
3692 return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr); 3829 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
3693 } 3830 }
3694 } 3831 }
3695 3832
3696 3833
3697 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, 3834 MaybeObject* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object,
3698 Handle<Object> key) { 3835 Handle<Object> key) {
3699 HandleScope scope; 3836 HandleScope scope;
3700 3837
3701 // Check if the given key is an array index. 3838 // Check if the given key is an array index.
3702 uint32_t index; 3839 uint32_t index;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
3764 if (args.length() == 4) { 3901 if (args.length() == 4) {
3765 CONVERT_CHECKED(Smi, value_obj, args[3]); 3902 CONVERT_CHECKED(Smi, value_obj, args[3]);
3766 int unchecked_value = value_obj->value(); 3903 int unchecked_value = value_obj->value();
3767 // Only attribute bits should be set. 3904 // Only attribute bits should be set.
3768 RUNTIME_ASSERT( 3905 RUNTIME_ASSERT(
3769 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 3906 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
3770 attributes = static_cast<PropertyAttributes>(unchecked_value); 3907 attributes = static_cast<PropertyAttributes>(unchecked_value);
3771 } 3908 }
3772 3909
3773 return object-> 3910 return object->
3774 IgnoreAttributesAndSetLocalProperty(name, args[2], attributes); 3911 SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
3775 } 3912 }
3776 3913
3777 3914
3778 static MaybeObject* Runtime_DeleteProperty(Arguments args) { 3915 static MaybeObject* Runtime_DeleteProperty(Arguments args) {
3779 NoHandleAllocation ha; 3916 NoHandleAllocation ha;
3780 ASSERT(args.length() == 2); 3917 ASSERT(args.length() == 3);
3781 3918
3782 CONVERT_CHECKED(JSObject, object, args[0]); 3919 CONVERT_CHECKED(JSObject, object, args[0]);
3783 CONVERT_CHECKED(String, key, args[1]); 3920 CONVERT_CHECKED(String, key, args[1]);
3784 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); 3921 CONVERT_SMI_CHECKED(strict, args[2]);
3922 return object->DeleteProperty(key, strict == kStrictMode
3923 ? JSObject::STRICT_DELETION
3924 : JSObject::NORMAL_DELETION);
3785 } 3925 }
3786 3926
3787 3927
3788 static Object* HasLocalPropertyImplementation(Handle<JSObject> object, 3928 static Object* HasLocalPropertyImplementation(Handle<JSObject> object,
3789 Handle<String> key) { 3929 Handle<String> key) {
3790 if (object->HasLocalProperty(*key)) return Heap::true_value(); 3930 if (object->HasLocalProperty(*key)) return Heap::true_value();
3791 // Handle hidden prototypes. If there's a hidden prototype above this thing 3931 // Handle hidden prototypes. If there's a hidden prototype above this thing
3792 // then we have to check it for properties, because they are supposed to 3932 // then we have to check it for properties, because they are supposed to
3793 // look like they are on this object. 3933 // look like they are on this object.
3794 Handle<Object> proto(object->GetPrototype()); 3934 Handle<Object> proto(object->GetPrototype());
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
4068 } 4208 }
4069 return Heap::undefined_value(); 4209 return Heap::undefined_value();
4070 } 4210 }
4071 4211
4072 4212
4073 static MaybeObject* Runtime_LocalKeys(Arguments args) { 4213 static MaybeObject* Runtime_LocalKeys(Arguments args) {
4074 ASSERT_EQ(args.length(), 1); 4214 ASSERT_EQ(args.length(), 1);
4075 CONVERT_CHECKED(JSObject, raw_object, args[0]); 4215 CONVERT_CHECKED(JSObject, raw_object, args[0]);
4076 HandleScope scope; 4216 HandleScope scope;
4077 Handle<JSObject> object(raw_object); 4217 Handle<JSObject> object(raw_object);
4218
4219 if (object->IsJSGlobalProxy()) {
4220 // Do access checks before going to the global object.
4221 if (object->IsAccessCheckNeeded() &&
4222 !Top::MayNamedAccess(*object, Heap::undefined_value(),
4223 v8::ACCESS_KEYS)) {
4224 Top::ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
4225 return *Factory::NewJSArray(0);
4226 }
4227
4228 Handle<Object> proto(object->GetPrototype());
4229 // If proxy is detached we simply return an empty array.
4230 if (proto->IsNull()) return *Factory::NewJSArray(0);
4231 object = Handle<JSObject>::cast(proto);
4232 }
4233
4078 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, 4234 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object,
4079 LOCAL_ONLY); 4235 LOCAL_ONLY);
4080 // Some fast paths through GetKeysInFixedArrayFor reuse a cached 4236 // Some fast paths through GetKeysInFixedArrayFor reuse a cached
4081 // property array and since the result is mutable we have to create 4237 // property array and since the result is mutable we have to create
4082 // a fresh clone on each invocation. 4238 // a fresh clone on each invocation.
4083 int length = contents->length(); 4239 int length = contents->length();
4084 Handle<FixedArray> copy = Factory::NewFixedArray(length); 4240 Handle<FixedArray> copy = Factory::NewFixedArray(length);
4085 for (int i = 0; i < length; i++) { 4241 for (int i = 0; i < length; i++) {
4086 Object* entry = contents->get(i); 4242 Object* entry = contents->get(i);
4087 if (entry->IsString()) { 4243 if (entry->IsString()) {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4157 } 4313 }
4158 return *object; 4314 return *object;
4159 } 4315 }
4160 4316
4161 4317
4162 static MaybeObject* Runtime_ToSlowProperties(Arguments args) { 4318 static MaybeObject* Runtime_ToSlowProperties(Arguments args) {
4163 HandleScope scope; 4319 HandleScope scope;
4164 4320
4165 ASSERT(args.length() == 1); 4321 ASSERT(args.length() == 1);
4166 Handle<Object> object = args.at<Object>(0); 4322 Handle<Object> object = args.at<Object>(0);
4167 if (object->IsJSObject()) { 4323 if (object->IsJSObject() && !object->IsJSGlobalProxy()) {
4168 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 4324 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
4169 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 4325 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
4170 } 4326 }
4171 return *object; 4327 return *object;
4172 } 4328 }
4173 4329
4174 4330
4175 static MaybeObject* Runtime_ToBool(Arguments args) { 4331 static MaybeObject* Runtime_ToBool(Arguments args) {
4176 NoHandleAllocation ha; 4332 NoHandleAllocation ha;
4177 ASSERT(args.length() == 1); 4333 ASSERT(args.length() == 1);
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
4608 return Heap::AllocateRawTwoByteString(length); 4764 return Heap::AllocateRawTwoByteString(length);
4609 } 4765 }
4610 4766
4611 4767
4612 template <> 4768 template <>
4613 MaybeObject* AllocateRawString<SeqAsciiString>(int length) { 4769 MaybeObject* AllocateRawString<SeqAsciiString>(int length) {
4614 return Heap::AllocateRawAsciiString(length); 4770 return Heap::AllocateRawAsciiString(length);
4615 } 4771 }
4616 4772
4617 4773
4618 template <typename Char, typename StringType> 4774 template <typename Char, typename StringType, bool comma>
4619 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) { 4775 static MaybeObject* SlowQuoteJsonString(Vector<const Char> characters) {
4620 int length = characters.length(); 4776 int length = characters.length();
4621 const Char* read_cursor = characters.start(); 4777 const Char* read_cursor = characters.start();
4622 const Char* end = read_cursor + length; 4778 const Char* end = read_cursor + length;
4623 const int kSpaceForQuotes = 2; 4779 const int kSpaceForQuotes = 2 + (comma ? 1 :0);
4624 int quoted_length = kSpaceForQuotes; 4780 int quoted_length = kSpaceForQuotes;
4625 while (read_cursor < end) { 4781 while (read_cursor < end) {
4626 Char c = *(read_cursor++); 4782 Char c = *(read_cursor++);
4627 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4783 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4628 quoted_length++; 4784 quoted_length++;
4629 } else { 4785 } else {
4630 quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)]; 4786 quoted_length += JsonQuoteLengths[static_cast<unsigned>(c)];
4631 } 4787 }
4632 } 4788 }
4633 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length); 4789 MaybeObject* new_alloc = AllocateRawString<StringType>(quoted_length);
4634 Object* new_object; 4790 Object* new_object;
4635 if (!new_alloc->ToObject(&new_object)) { 4791 if (!new_alloc->ToObject(&new_object)) {
4636 return new_alloc; 4792 return new_alloc;
4637 } 4793 }
4638 StringType* new_string = StringType::cast(new_object); 4794 StringType* new_string = StringType::cast(new_object);
4639 4795
4640 Char* write_cursor = reinterpret_cast<Char*>( 4796 Char* write_cursor = reinterpret_cast<Char*>(
4641 new_string->address() + SeqAsciiString::kHeaderSize); 4797 new_string->address() + SeqAsciiString::kHeaderSize);
4798 if (comma) *(write_cursor++) = ',';
4642 *(write_cursor++) = '"'; 4799 *(write_cursor++) = '"';
4643 4800
4644 read_cursor = characters.start(); 4801 read_cursor = characters.start();
4645 while (read_cursor < end) { 4802 while (read_cursor < end) {
4646 Char c = *(read_cursor++); 4803 Char c = *(read_cursor++);
4647 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4804 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4648 *(write_cursor++) = c; 4805 *(write_cursor++) = c;
4649 } else { 4806 } else {
4650 int len = JsonQuoteLengths[static_cast<unsigned>(c)]; 4807 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
4651 const char* replacement = JsonQuotes + 4808 const char* replacement = JsonQuotes +
4652 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry; 4809 static_cast<unsigned>(c) * kJsonQuotesCharactersPerEntry;
4653 for (int i = 0; i < len; i++) { 4810 for (int i = 0; i < len; i++) {
4654 *write_cursor++ = *replacement++; 4811 *write_cursor++ = *replacement++;
4655 } 4812 }
4656 } 4813 }
4657 } 4814 }
4658 *(write_cursor++) = '"'; 4815 *(write_cursor++) = '"';
4659 return new_string; 4816 return new_string;
4660 } 4817 }
4661 4818
4662 4819
4663 template <typename Char, typename StringType> 4820 template <typename Char, typename StringType, bool comma>
4664 static MaybeObject* QuoteJsonString(Vector<const Char> characters) { 4821 static MaybeObject* QuoteJsonString(Vector<const Char> characters) {
4665 int length = characters.length(); 4822 int length = characters.length();
4666 Counters::quote_json_char_count.Increment(length); 4823 Counters::quote_json_char_count.Increment(length);
4667 const int kSpaceForQuotes = 2; 4824 const int kSpaceForQuotes = 2 + (comma ? 1 :0);
4668 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; 4825 int worst_case_length = length * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
4669 if (worst_case_length > kMaxGuaranteedNewSpaceString) { 4826 if (worst_case_length > kMaxGuaranteedNewSpaceString) {
4670 return SlowQuoteJsonString<Char, StringType>(characters); 4827 return SlowQuoteJsonString<Char, StringType, comma>(characters);
4671 } 4828 }
4672 4829
4673 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length); 4830 MaybeObject* new_alloc = AllocateRawString<StringType>(worst_case_length);
4674 Object* new_object; 4831 Object* new_object;
4675 if (!new_alloc->ToObject(&new_object)) { 4832 if (!new_alloc->ToObject(&new_object)) {
4676 return new_alloc; 4833 return new_alloc;
4677 } 4834 }
4678 if (!Heap::new_space()->Contains(new_object)) { 4835 if (!Heap::new_space()->Contains(new_object)) {
4679 // Even if our string is small enough to fit in new space we still have to 4836 // Even if our string is small enough to fit in new space we still have to
4680 // handle it being allocated in old space as may happen in the third 4837 // handle it being allocated in old space as may happen in the third
4681 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in 4838 // attempt. See CALL_AND_RETRY in heap-inl.h and similar code in
4682 // CEntryStub::GenerateCore. 4839 // CEntryStub::GenerateCore.
4683 return SlowQuoteJsonString<Char, StringType>(characters); 4840 return SlowQuoteJsonString<Char, StringType, comma>(characters);
4684 } 4841 }
4685 StringType* new_string = StringType::cast(new_object); 4842 StringType* new_string = StringType::cast(new_object);
4686 ASSERT(Heap::new_space()->Contains(new_string)); 4843 ASSERT(Heap::new_space()->Contains(new_string));
4687 4844
4688 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); 4845 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize);
4689 Char* write_cursor = reinterpret_cast<Char*>( 4846 Char* write_cursor = reinterpret_cast<Char*>(
4690 new_string->address() + SeqAsciiString::kHeaderSize); 4847 new_string->address() + SeqAsciiString::kHeaderSize);
4848 if (comma) *(write_cursor++) = ',';
4691 *(write_cursor++) = '"'; 4849 *(write_cursor++) = '"';
4692 4850
4693 const Char* read_cursor = characters.start(); 4851 const Char* read_cursor = characters.start();
4694 const Char* end = read_cursor + length; 4852 const Char* end = read_cursor + length;
4695 while (read_cursor < end) { 4853 while (read_cursor < end) {
4696 Char c = *(read_cursor++); 4854 Char c = *(read_cursor++);
4697 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) { 4855 if (sizeof(Char) > 1u && static_cast<unsigned>(c) >= kQuoteTableLength) {
4698 *(write_cursor++) = c; 4856 *(write_cursor++) = c;
4699 } else { 4857 } else {
4700 int len = JsonQuoteLengths[static_cast<unsigned>(c)]; 4858 int len = JsonQuoteLengths[static_cast<unsigned>(c)];
(...skipping 30 matching lines...) Expand all
4731 if (!str->IsFlat()) { 4889 if (!str->IsFlat()) {
4732 MaybeObject* try_flatten = str->TryFlatten(); 4890 MaybeObject* try_flatten = str->TryFlatten();
4733 Object* flat; 4891 Object* flat;
4734 if (!try_flatten->ToObject(&flat)) { 4892 if (!try_flatten->ToObject(&flat)) {
4735 return try_flatten; 4893 return try_flatten;
4736 } 4894 }
4737 str = String::cast(flat); 4895 str = String::cast(flat);
4738 ASSERT(str->IsFlat()); 4896 ASSERT(str->IsFlat());
4739 } 4897 }
4740 if (str->IsTwoByteRepresentation()) { 4898 if (str->IsTwoByteRepresentation()) {
4741 return QuoteJsonString<uc16, SeqTwoByteString>(str->ToUC16Vector()); 4899 return QuoteJsonString<uc16, SeqTwoByteString, false>(str->ToUC16Vector());
4742 } else { 4900 } else {
4743 return QuoteJsonString<char, SeqAsciiString>(str->ToAsciiVector()); 4901 return QuoteJsonString<char, SeqAsciiString, false>(str->ToAsciiVector());
4744 } 4902 }
4745 } 4903 }
4746 4904
4747 4905
4906 static MaybeObject* Runtime_QuoteJSONStringComma(Arguments args) {
4907 NoHandleAllocation ha;
4908 CONVERT_CHECKED(String, str, args[0]);
4909 if (!str->IsFlat()) {
4910 MaybeObject* try_flatten = str->TryFlatten();
4911 Object* flat;
4912 if (!try_flatten->ToObject(&flat)) {
4913 return try_flatten;
4914 }
4915 str = String::cast(flat);
4916 ASSERT(str->IsFlat());
4917 }
4918 if (str->IsTwoByteRepresentation()) {
4919 return QuoteJsonString<uc16, SeqTwoByteString, true>(str->ToUC16Vector());
4920 } else {
4921 return QuoteJsonString<char, SeqAsciiString, true>(str->ToAsciiVector());
4922 }
4923 }
4924
4748 4925
4749 static MaybeObject* Runtime_StringParseInt(Arguments args) { 4926 static MaybeObject* Runtime_StringParseInt(Arguments args) {
4750 NoHandleAllocation ha; 4927 NoHandleAllocation ha;
4751 4928
4752 CONVERT_CHECKED(String, s, args[0]); 4929 CONVERT_CHECKED(String, s, args[0]);
4753 CONVERT_SMI_CHECKED(radix, args[1]); 4930 CONVERT_SMI_CHECKED(radix, args[1]);
4754 4931
4755 s->TryFlatten(); 4932 s->TryFlatten();
4756 4933
4757 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36)); 4934 RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
5636 SeqTwoByteString* answer = SeqTwoByteString::cast(object); 5813 SeqTwoByteString* answer = SeqTwoByteString::cast(object);
5637 StringBuilderConcatHelper(special, 5814 StringBuilderConcatHelper(special,
5638 answer->GetChars(), 5815 answer->GetChars(),
5639 fixed_array, 5816 fixed_array,
5640 array_length); 5817 array_length);
5641 return answer; 5818 return answer;
5642 } 5819 }
5643 } 5820 }
5644 5821
5645 5822
5823 static MaybeObject* Runtime_StringBuilderJoin(Arguments args) {
5824 NoHandleAllocation ha;
5825 ASSERT(args.length() == 3);
5826 CONVERT_CHECKED(JSArray, array, args[0]);
5827 if (!args[1]->IsSmi()) {
5828 Top::context()->mark_out_of_memory();
5829 return Failure::OutOfMemoryException();
5830 }
5831 int array_length = Smi::cast(args[1])->value();
5832 CONVERT_CHECKED(String, separator, args[2]);
5833
5834 if (!array->HasFastElements()) {
5835 return Top::Throw(Heap::illegal_argument_symbol());
5836 }
5837 FixedArray* fixed_array = FixedArray::cast(array->elements());
5838 if (fixed_array->length() < array_length) {
5839 array_length = fixed_array->length();
5840 }
5841
5842 if (array_length == 0) {
5843 return Heap::empty_string();
5844 } else if (array_length == 1) {
5845 Object* first = fixed_array->get(0);
5846 if (first->IsString()) return first;
5847 }
5848
5849 int separator_length = separator->length();
5850 int max_nof_separators =
5851 (String::kMaxLength + separator_length - 1) / separator_length;
5852 if (max_nof_separators < (array_length - 1)) {
5853 Top::context()->mark_out_of_memory();
5854 return Failure::OutOfMemoryException();
5855 }
5856 int length = (array_length - 1) * separator_length;
5857 for (int i = 0; i < array_length; i++) {
5858 Object* element_obj = fixed_array->get(i);
5859 if (!element_obj->IsString()) {
5860 // TODO(1161): handle this case.
5861 return Top::Throw(Heap::illegal_argument_symbol());
5862 }
5863 String* element = String::cast(element_obj);
5864 int increment = element->length();
5865 if (increment > String::kMaxLength - length) {
5866 Top::context()->mark_out_of_memory();
5867 return Failure::OutOfMemoryException();
5868 }
5869 length += increment;
5870 }
5871
5872 Object* object;
5873 { MaybeObject* maybe_object = Heap::AllocateRawTwoByteString(length);
5874 if (!maybe_object->ToObject(&object)) return maybe_object;
5875 }
5876 SeqTwoByteString* answer = SeqTwoByteString::cast(object);
5877
5878 uc16* sink = answer->GetChars();
5879 #ifdef DEBUG
5880 uc16* end = sink + length;
5881 #endif
5882
5883 String* first = String::cast(fixed_array->get(0));
5884 int first_length = first->length();
5885 String::WriteToFlat(first, sink, 0, first_length);
5886 sink += first_length;
5887
5888 for (int i = 1; i < array_length; i++) {
5889 ASSERT(sink + separator_length <= end);
5890 String::WriteToFlat(separator, sink, 0, separator_length);
5891 sink += separator_length;
5892
5893 String* element = String::cast(fixed_array->get(i));
5894 int element_length = element->length();
5895 ASSERT(sink + element_length <= end);
5896 String::WriteToFlat(element, sink, 0, element_length);
5897 sink += element_length;
5898 }
5899 ASSERT(sink == end);
5900
5901 ASSERT(!answer->HasOnlyAsciiChars()); // Use %_FastAsciiArrayJoin instead.
5902 return answer;
5903 }
5904
5905
5646 static MaybeObject* Runtime_NumberOr(Arguments args) { 5906 static MaybeObject* Runtime_NumberOr(Arguments args) {
5647 NoHandleAllocation ha; 5907 NoHandleAllocation ha;
5648 ASSERT(args.length() == 2); 5908 ASSERT(args.length() == 2);
5649 5909
5650 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); 5910 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
5651 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); 5911 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
5652 return Heap::NumberFromInt32(x | y); 5912 return Heap::NumberFromInt32(x | y);
5653 } 5913 }
5654 5914
5655 5915
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
6535 // directly to properties. 6795 // directly to properties.
6536 pretenure = pretenure || (context->global_context() == *context); 6796 pretenure = pretenure || (context->global_context() == *context);
6537 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED; 6797 PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
6538 Handle<JSFunction> result = 6798 Handle<JSFunction> result =
6539 Factory::NewFunctionFromSharedFunctionInfo(shared, 6799 Factory::NewFunctionFromSharedFunctionInfo(shared,
6540 context, 6800 context,
6541 pretenure_flag); 6801 pretenure_flag);
6542 return *result; 6802 return *result;
6543 } 6803 }
6544 6804
6805
6545 static MaybeObject* Runtime_NewObjectFromBound(Arguments args) { 6806 static MaybeObject* Runtime_NewObjectFromBound(Arguments args) {
6546 HandleScope scope; 6807 HandleScope scope;
6547 ASSERT(args.length() == 2); 6808 ASSERT(args.length() == 2);
6809 // First argument is a function to use as a constructor.
6548 CONVERT_ARG_CHECKED(JSFunction, function, 0); 6810 CONVERT_ARG_CHECKED(JSFunction, function, 0);
6549 CONVERT_ARG_CHECKED(JSArray, params, 1);
6550 6811
6551 RUNTIME_ASSERT(params->HasFastElements()); 6812 // Second argument is either null or an array of bound arguments.
6552 FixedArray* fixed = FixedArray::cast(params->elements()); 6813 FixedArray* bound_args = NULL;
6814 int bound_argc = 0;
6815 if (!args[1]->IsNull()) {
6816 CONVERT_ARG_CHECKED(JSArray, params, 1);
6817 RUNTIME_ASSERT(params->HasFastElements());
6818 bound_args = FixedArray::cast(params->elements());
6819 bound_argc = Smi::cast(params->length())->value();
6820 }
6553 6821
6554 int fixed_length = Smi::cast(params->length())->value(); 6822 // Find frame containing arguments passed to the caller.
6555 SmartPointer<Object**> param_data(NewArray<Object**>(fixed_length)); 6823 JavaScriptFrameIterator it;
6556 for (int i = 0; i < fixed_length; i++) { 6824 JavaScriptFrame* frame = it.frame();
6557 Handle<Object> val = Handle<Object>(fixed->get(i)); 6825 ASSERT(!frame->is_optimized());
6826 it.AdvanceToArgumentsFrame();
6827 frame = it.frame();
6828 int argc = frame->GetProvidedParametersCount();
6829
6830 // Prepend bound arguments to caller's arguments.
6831 int total_argc = bound_argc + argc;
6832 SmartPointer<Object**> param_data(NewArray<Object**>(total_argc));
6833 for (int i = 0; i < bound_argc; i++) {
6834 Handle<Object> val = Handle<Object>(bound_args->get(i));
6558 param_data[i] = val.location(); 6835 param_data[i] = val.location();
6559 } 6836 }
6837 for (int i = 0; i < argc; i++) {
6838 Handle<Object> val = Handle<Object>(frame->GetParameter(i));
6839 param_data[bound_argc + i] = val.location();
6840 }
6560 6841
6561 bool exception = false; 6842 bool exception = false;
6562 Handle<Object> result = Execution::New( 6843 Handle<Object> result =
6563 function, fixed_length, *param_data, &exception); 6844 Execution::New(function, total_argc, *param_data, &exception);
6564 if (exception) { 6845 if (exception) {
6565 return Failure::Exception(); 6846 return Failure::Exception();
6566 } 6847 }
6848
6567 ASSERT(!result.is_null()); 6849 ASSERT(!result.is_null());
6568 return *result; 6850 return *result;
6569 } 6851 }
6570 6852
6571 6853
6572 static void TrySettingInlineConstructStub(Handle<JSFunction> function) { 6854 static void TrySettingInlineConstructStub(Handle<JSFunction> function) {
6573 Handle<Object> prototype = Factory::null_value(); 6855 Handle<Object> prototype = Factory::null_value();
6574 if (function->has_instance_prototype()) { 6856 if (function->has_instance_prototype()) {
6575 prototype = Handle<Object>(function->instance_prototype()); 6857 prototype = Handle<Object>(function->instance_prototype());
6576 } 6858 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
6707 6989
6708 6990
6709 static MaybeObject* Runtime_LazyRecompile(Arguments args) { 6991 static MaybeObject* Runtime_LazyRecompile(Arguments args) {
6710 HandleScope scope; 6992 HandleScope scope;
6711 ASSERT(args.length() == 1); 6993 ASSERT(args.length() == 1);
6712 Handle<JSFunction> function = args.at<JSFunction>(0); 6994 Handle<JSFunction> function = args.at<JSFunction>(0);
6713 // If the function is not optimizable or debugger is active continue using the 6995 // If the function is not optimizable or debugger is active continue using the
6714 // code from the full compiler. 6996 // code from the full compiler.
6715 if (!function->shared()->code()->optimizable() || 6997 if (!function->shared()->code()->optimizable() ||
6716 Debug::has_break_points()) { 6998 Debug::has_break_points()) {
6999 if (FLAG_trace_opt) {
7000 PrintF("[failed to optimize ");
7001 function->PrintName();
7002 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
7003 function->shared()->code()->optimizable() ? "T" : "F",
7004 Debug::has_break_points() ? "T" : "F");
7005 }
6717 function->ReplaceCode(function->shared()->code()); 7006 function->ReplaceCode(function->shared()->code());
6718 return function->code(); 7007 return function->code();
6719 } 7008 }
6720 if (CompileOptimized(function, AstNode::kNoNumber)) { 7009 if (CompileOptimized(function, AstNode::kNoNumber)) {
6721 return function->code(); 7010 return function->code();
6722 } 7011 }
7012 if (FLAG_trace_opt) {
7013 PrintF("[failed to optimize ");
7014 function->PrintName();
7015 PrintF(": optimized compilation failed]\n");
7016 }
6723 function->ReplaceCode(function->shared()->code()); 7017 function->ReplaceCode(function->shared()->code());
6724 return Failure::Exception(); 7018 return Failure::Exception();
6725 } 7019 }
6726 7020
6727 7021
6728 static MaybeObject* Runtime_NotifyDeoptimized(Arguments args) { 7022 static MaybeObject* Runtime_NotifyDeoptimized(Arguments args) {
6729 HandleScope scope; 7023 HandleScope scope;
6730 ASSERT(args.length() == 1); 7024 ASSERT(args.length() == 1);
6731 RUNTIME_ASSERT(args[0]->IsSmi()); 7025 RUNTIME_ASSERT(args[0]->IsSmi());
6732 Deoptimizer::BailoutType type = 7026 Deoptimizer::BailoutType type =
6733 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value()); 7027 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
6734 Deoptimizer* deoptimizer = Deoptimizer::Grab(); 7028 Deoptimizer* deoptimizer = Deoptimizer::Grab();
6735 ASSERT(Heap::IsAllocationAllowed()); 7029 ASSERT(Heap::IsAllocationAllowed());
6736 int frames = deoptimizer->output_count(); 7030 int frames = deoptimizer->output_count();
6737 7031
6738 JavaScriptFrameIterator it; 7032 JavaScriptFrameIterator it;
6739 JavaScriptFrame* frame = NULL; 7033 JavaScriptFrame* frame = NULL;
6740 for (int i = 0; i < frames; i++) { 7034 for (int i = 0; i < frames; i++) {
6741 if (i != 0) it.Advance(); 7035 if (i != 0) it.Advance();
6742 frame = it.frame(); 7036 frame = it.frame();
6743 deoptimizer->InsertHeapNumberValues(frames - i - 1, frame); 7037 deoptimizer->InsertHeapNumberValues(frames - i - 1, frame);
6744 } 7038 }
6745 delete deoptimizer; 7039 delete deoptimizer;
6746 7040
6747 RUNTIME_ASSERT(frame->function()->IsJSFunction()); 7041 RUNTIME_ASSERT(frame->function()->IsJSFunction());
6748 Handle<JSFunction> function(JSFunction::cast(frame->function())); 7042 Handle<JSFunction> function(JSFunction::cast(frame->function()));
6749 Handle<Object> arguments; 7043 Handle<Object> arguments;
6750 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) { 7044 for (int i = frame->ComputeExpressionsCount() - 1; i >= 0; --i) {
6751 if (frame->GetExpression(i) == Heap::the_hole_value()) { 7045 if (frame->GetExpression(i) == Heap::arguments_marker()) {
6752 if (arguments.is_null()) { 7046 if (arguments.is_null()) {
6753 // FunctionGetArguments can't throw an exception, so cast away the 7047 // FunctionGetArguments can't throw an exception, so cast away the
6754 // doubt with an assert. 7048 // doubt with an assert.
6755 arguments = Handle<Object>( 7049 arguments = Handle<Object>(
6756 Accessors::FunctionGetArguments(*function, 7050 Accessors::FunctionGetArguments(*function,
6757 NULL)->ToObjectUnchecked()); 7051 NULL)->ToObjectUnchecked());
6758 ASSERT(*arguments != Heap::null_value()); 7052 ASSERT(*arguments != Heap::null_value());
6759 ASSERT(*arguments != Heap::undefined_value()); 7053 ASSERT(*arguments != Heap::undefined_value());
6760 } 7054 }
6761 frame->SetExpression(i, *arguments); 7055 frame->SetExpression(i, *arguments);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
6852 JavaScriptFrameIterator it; 7146 JavaScriptFrameIterator it;
6853 JavaScriptFrame* frame = it.frame(); 7147 JavaScriptFrame* frame = it.frame();
6854 ASSERT(frame->function() == *function); 7148 ASSERT(frame->function() == *function);
6855 ASSERT(frame->code() == *unoptimized); 7149 ASSERT(frame->code() == *unoptimized);
6856 ASSERT(unoptimized->contains(frame->pc())); 7150 ASSERT(unoptimized->contains(frame->pc()));
6857 7151
6858 // Use linear search of the unoptimized code's stack check table to find 7152 // Use linear search of the unoptimized code's stack check table to find
6859 // the AST id matching the PC. 7153 // the AST id matching the PC.
6860 Address start = unoptimized->instruction_start(); 7154 Address start = unoptimized->instruction_start();
6861 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start); 7155 unsigned target_pc_offset = static_cast<unsigned>(frame->pc() - start);
6862 Address table_cursor = start + unoptimized->stack_check_table_start(); 7156 Address table_cursor = start + unoptimized->stack_check_table_offset();
6863 uint32_t table_length = Memory::uint32_at(table_cursor); 7157 uint32_t table_length = Memory::uint32_at(table_cursor);
6864 table_cursor += kIntSize; 7158 table_cursor += kIntSize;
6865 for (unsigned i = 0; i < table_length; ++i) { 7159 for (unsigned i = 0; i < table_length; ++i) {
6866 // Table entries are (AST id, pc offset) pairs. 7160 // Table entries are (AST id, pc offset) pairs.
6867 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize); 7161 uint32_t pc_offset = Memory::uint32_at(table_cursor + kIntSize);
6868 if (pc_offset == target_pc_offset) { 7162 if (pc_offset == target_pc_offset) {
6869 ast_id = static_cast<int>(Memory::uint32_at(table_cursor)); 7163 ast_id = static_cast<int>(Memory::uint32_at(table_cursor));
6870 break; 7164 break;
6871 } 7165 }
6872 table_cursor += 2 * kIntSize; 7166 table_cursor += 2 * kIntSize;
(...skipping 30 matching lines...) Expand all
6903 // Revert to the original stack checks in the original unoptimized code. 7197 // Revert to the original stack checks in the original unoptimized code.
6904 if (FLAG_trace_osr) { 7198 if (FLAG_trace_osr) {
6905 PrintF("[restoring original stack checks in "); 7199 PrintF("[restoring original stack checks in ");
6906 function->PrintName(); 7200 function->PrintName();
6907 PrintF("]\n"); 7201 PrintF("]\n");
6908 } 7202 }
6909 StackCheckStub check_stub; 7203 StackCheckStub check_stub;
6910 Handle<Code> check_code = check_stub.GetCode(); 7204 Handle<Code> check_code = check_stub.GetCode();
6911 Handle<Code> replacement_code( 7205 Handle<Code> replacement_code(
6912 Builtins::builtin(Builtins::OnStackReplacement)); 7206 Builtins::builtin(Builtins::OnStackReplacement));
6913 // Iterate the unoptimized code and revert all the patched stack checks. 7207 Deoptimizer::RevertStackCheckCode(*unoptimized,
6914 for (RelocIterator it(*unoptimized, RelocInfo::kCodeTargetMask); 7208 *check_code,
6915 !it.done(); 7209 *replacement_code);
6916 it.next()) {
6917 RelocInfo* rinfo = it.rinfo();
6918 if (rinfo->target_address() == replacement_code->entry()) {
6919 Deoptimizer::RevertStackCheckCode(rinfo, *check_code);
6920 }
6921 }
6922 7210
6923 // Allow OSR only at nesting level zero again. 7211 // Allow OSR only at nesting level zero again.
6924 unoptimized->set_allow_osr_at_loop_nesting_level(0); 7212 unoptimized->set_allow_osr_at_loop_nesting_level(0);
6925 7213
6926 // If the optimization attempt succeeded, return the AST id tagged as a 7214 // If the optimization attempt succeeded, return the AST id tagged as a
6927 // smi. This tells the builtin that we need to translate the unoptimized 7215 // smi. This tells the builtin that we need to translate the unoptimized
6928 // frame to an optimized one. 7216 // frame to an optimized one.
6929 if (succeeded) { 7217 if (succeeded) {
6930 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); 7218 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
6931 return Smi::FromInt(ast_id); 7219 return Smi::FromInt(ast_id);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
7008 } 7296 }
7009 7297
7010 7298
7011 static MaybeObject* Runtime_PushCatchContext(Arguments args) { 7299 static MaybeObject* Runtime_PushCatchContext(Arguments args) {
7012 NoHandleAllocation ha; 7300 NoHandleAllocation ha;
7013 ASSERT(args.length() == 1); 7301 ASSERT(args.length() == 1);
7014 return PushContextHelper(args[0], true); 7302 return PushContextHelper(args[0], true);
7015 } 7303 }
7016 7304
7017 7305
7018 static MaybeObject* Runtime_LookupContext(Arguments args) { 7306 static MaybeObject* Runtime_DeleteContextSlot(Arguments args) {
7019 HandleScope scope; 7307 HandleScope scope;
7020 ASSERT(args.length() == 2); 7308 ASSERT(args.length() == 2);
7021 7309
7022 CONVERT_ARG_CHECKED(Context, context, 0); 7310 CONVERT_ARG_CHECKED(Context, context, 0);
7023 CONVERT_ARG_CHECKED(String, name, 1); 7311 CONVERT_ARG_CHECKED(String, name, 1);
7024 7312
7025 int index; 7313 int index;
7026 PropertyAttributes attributes; 7314 PropertyAttributes attributes;
7027 ContextLookupFlags flags = FOLLOW_CHAINS; 7315 ContextLookupFlags flags = FOLLOW_CHAINS;
7028 Handle<Object> holder = 7316 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
7029 context->Lookup(name, flags, &index, &attributes);
7030 7317
7031 if (index < 0 && !holder.is_null()) { 7318 // If the slot was not found the result is true.
7032 ASSERT(holder->IsJSObject()); 7319 if (holder.is_null()) {
7033 return *holder; 7320 return Heap::true_value();
7034 } 7321 }
7035 7322
7036 // No intermediate context found. Use global object by default. 7323 // If the slot was found in a context, it should be DONT_DELETE.
7037 return Top::context()->global(); 7324 if (holder->IsContext()) {
7325 return Heap::false_value();
7326 }
7327
7328 // The slot was found in a JSObject, either a context extension object,
7329 // the global object, or an arguments object. Try to delete it
7330 // (respecting DONT_DELETE). For consistency with V8's usual behavior,
7331 // which allows deleting all parameters in functions that mention
7332 // 'arguments', we do this even for the case of slots found on an
7333 // arguments object. The slot was found on an arguments object if the
7334 // index is non-negative.
7335 Handle<JSObject> object = Handle<JSObject>::cast(holder);
7336 if (index >= 0) {
7337 return object->DeleteElement(index, JSObject::NORMAL_DELETION);
7338 } else {
7339 return object->DeleteProperty(*name, JSObject::NORMAL_DELETION);
7340 }
7038 } 7341 }
7039 7342
7040 7343
7041 // A mechanism to return a pair of Object pointers in registers (if possible). 7344 // A mechanism to return a pair of Object pointers in registers (if possible).
7042 // How this is achieved is calling convention-dependent. 7345 // How this is achieved is calling convention-dependent.
7043 // All currently supported x86 compiles uses calling conventions that are cdecl 7346 // All currently supported x86 compiles uses calling conventions that are cdecl
7044 // variants where a 64-bit value is returned in two 32-bit registers 7347 // variants where a 64-bit value is returned in two 32-bit registers
7045 // (edx:eax on ia32, r1:r0 on ARM). 7348 // (edx:eax on ia32, r1:r0 on ARM).
7046 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax. 7349 // In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
7047 // In Win64 calling convention, a struct of two pointers is returned in memory, 7350 // In Win64 calling convention, a struct of two pointers is returned in memory,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
7100 7403
7101 if (!args[0]->IsContext() || !args[1]->IsString()) { 7404 if (!args[0]->IsContext() || !args[1]->IsString()) {
7102 return MakePair(Top::ThrowIllegalOperation(), NULL); 7405 return MakePair(Top::ThrowIllegalOperation(), NULL);
7103 } 7406 }
7104 Handle<Context> context = args.at<Context>(0); 7407 Handle<Context> context = args.at<Context>(0);
7105 Handle<String> name = args.at<String>(1); 7408 Handle<String> name = args.at<String>(1);
7106 7409
7107 int index; 7410 int index;
7108 PropertyAttributes attributes; 7411 PropertyAttributes attributes;
7109 ContextLookupFlags flags = FOLLOW_CHAINS; 7412 ContextLookupFlags flags = FOLLOW_CHAINS;
7110 Handle<Object> holder = 7413 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
7111 context->Lookup(name, flags, &index, &attributes);
7112 7414
7113 // If the index is non-negative, the slot has been found in a local 7415 // If the index is non-negative, the slot has been found in a local
7114 // variable or a parameter. Read it from the context object or the 7416 // variable or a parameter. Read it from the context object or the
7115 // arguments object. 7417 // arguments object.
7116 if (index >= 0) { 7418 if (index >= 0) {
7117 // If the "property" we were looking for is a local variable or an 7419 // If the "property" we were looking for is a local variable or an
7118 // argument in a context, the receiver is the global object; see 7420 // argument in a context, the receiver is the global object; see
7119 // ECMA-262, 3rd., 10.1.6 and 10.2.3. 7421 // ECMA-262, 3rd., 10.1.6 and 10.2.3.
7120 JSObject* receiver = Top::context()->global()->global_receiver(); 7422 JSObject* receiver = Top::context()->global()->global_receiver();
7121 MaybeObject* value = (holder->IsContext()) 7423 MaybeObject* value = (holder->IsContext())
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
7168 HandleScope scope; 7470 HandleScope scope;
7169 ASSERT(args.length() == 3); 7471 ASSERT(args.length() == 3);
7170 7472
7171 Handle<Object> value(args[0]); 7473 Handle<Object> value(args[0]);
7172 CONVERT_ARG_CHECKED(Context, context, 1); 7474 CONVERT_ARG_CHECKED(Context, context, 1);
7173 CONVERT_ARG_CHECKED(String, name, 2); 7475 CONVERT_ARG_CHECKED(String, name, 2);
7174 7476
7175 int index; 7477 int index;
7176 PropertyAttributes attributes; 7478 PropertyAttributes attributes;
7177 ContextLookupFlags flags = FOLLOW_CHAINS; 7479 ContextLookupFlags flags = FOLLOW_CHAINS;
7178 Handle<Object> holder = 7480 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
7179 context->Lookup(name, flags, &index, &attributes);
7180 7481
7181 if (index >= 0) { 7482 if (index >= 0) {
7182 if (holder->IsContext()) { 7483 if (holder->IsContext()) {
7183 // Ignore if read_only variable. 7484 // Ignore if read_only variable.
7184 if ((attributes & READ_ONLY) == 0) { 7485 if ((attributes & READ_ONLY) == 0) {
7185 Handle<Context>::cast(holder)->set(index, *value); 7486 // Context is a fixed array and set cannot fail.
7487 Context::cast(*holder)->set(index, *value);
7186 } 7488 }
7187 } else { 7489 } else {
7188 ASSERT((attributes & READ_ONLY) == 0); 7490 ASSERT((attributes & READ_ONLY) == 0);
7189 Handle<JSObject>::cast(holder)->SetElement(index, *value)-> 7491 Handle<Object> result =
7190 ToObjectUnchecked(); 7492 SetElement(Handle<JSObject>::cast(holder), index, value);
7493 if (result.is_null()) {
7494 ASSERT(Top::has_pending_exception());
7495 return Failure::Exception();
7496 }
7191 } 7497 }
7192 return *value; 7498 return *value;
7193 } 7499 }
7194 7500
7195 // Slow case: The property is not in a FixedArray context. 7501 // Slow case: The property is not in a FixedArray context.
7196 // It is either in an JSObject extension context or it was not found. 7502 // It is either in an JSObject extension context or it was not found.
7197 Handle<JSObject> context_ext; 7503 Handle<JSObject> context_ext;
7198 7504
7199 if (!holder.is_null()) { 7505 if (!holder.is_null()) {
7200 // The property exists in the extension context. 7506 // The property exists in the extension context.
7201 context_ext = Handle<JSObject>::cast(holder); 7507 context_ext = Handle<JSObject>::cast(holder);
7202 } else { 7508 } else {
7203 // The property was not found. It needs to be stored in the global context. 7509 // The property was not found. It needs to be stored in the global context.
7204 ASSERT(attributes == ABSENT); 7510 ASSERT(attributes == ABSENT);
7205 attributes = NONE; 7511 attributes = NONE;
7206 context_ext = Handle<JSObject>(Top::context()->global()); 7512 context_ext = Handle<JSObject>(Top::context()->global());
7207 } 7513 }
7208 7514
7209 // Set the property, but ignore if read_only variable on the context 7515 // Set the property, but ignore if read_only variable on the context
7210 // extension object itself. 7516 // extension object itself.
7211 if ((attributes & READ_ONLY) == 0 || 7517 if ((attributes & READ_ONLY) == 0 ||
7212 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { 7518 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
7213 Handle<Object> set = SetProperty(context_ext, name, value, NONE); 7519 RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, NONE));
7214 if (set.is_null()) {
7215 // Failure::Exception is converted to a null handle in the
7216 // handle-based methods such as SetProperty. We therefore need
7217 // to convert null handles back to exceptions.
7218 ASSERT(Top::has_pending_exception());
7219 return Failure::Exception();
7220 }
7221 } 7520 }
7222 return *value; 7521 return *value;
7223 } 7522 }
7224 7523
7225 7524
7226 static MaybeObject* Runtime_Throw(Arguments args) { 7525 static MaybeObject* Runtime_Throw(Arguments args) {
7227 HandleScope scope; 7526 HandleScope scope;
7228 ASSERT(args.length() == 1); 7527 ASSERT(args.length() == 1);
7229 7528
7230 return Top::Throw(args[0]); 7529 return Top::Throw(args[0]);
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
7509 7808
7510 static MaybeObject* Runtime_CompileString(Arguments args) { 7809 static MaybeObject* Runtime_CompileString(Arguments args) {
7511 HandleScope scope; 7810 HandleScope scope;
7512 ASSERT_EQ(1, args.length()); 7811 ASSERT_EQ(1, args.length());
7513 CONVERT_ARG_CHECKED(String, source, 0); 7812 CONVERT_ARG_CHECKED(String, source, 0);
7514 7813
7515 // Compile source string in the global context. 7814 // Compile source string in the global context.
7516 Handle<Context> context(Top::context()->global_context()); 7815 Handle<Context> context(Top::context()->global_context());
7517 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, 7816 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
7518 context, 7817 context,
7519 true); 7818 true,
7819 kNonStrictMode);
7520 if (shared.is_null()) return Failure::Exception(); 7820 if (shared.is_null()) return Failure::Exception();
7521 Handle<JSFunction> fun = 7821 Handle<JSFunction> fun =
7522 Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED); 7822 Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED);
7523 return *fun; 7823 return *fun;
7524 } 7824 }
7525 7825
7526 7826
7527 static ObjectPair CompileGlobalEval(Handle<String> source, 7827 static ObjectPair CompileGlobalEval(Handle<String> source,
7528 Handle<Object> receiver) { 7828 Handle<Object> receiver,
7829 StrictModeFlag mode) {
7529 // Deal with a normal eval call with a string argument. Compile it 7830 // Deal with a normal eval call with a string argument. Compile it
7530 // and return the compiled function bound in the local context. 7831 // and return the compiled function bound in the local context.
7531 Handle<SharedFunctionInfo> shared = Compiler::CompileEval( 7832 Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
7532 source, 7833 source,
7533 Handle<Context>(Top::context()), 7834 Handle<Context>(Top::context()),
7534 Top::context()->IsGlobalContext()); 7835 Top::context()->IsGlobalContext(),
7836 mode);
7535 if (shared.is_null()) return MakePair(Failure::Exception(), NULL); 7837 if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
7536 Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo( 7838 Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo(
7537 shared, 7839 shared,
7538 Handle<Context>(Top::context()), 7840 Handle<Context>(Top::context()),
7539 NOT_TENURED); 7841 NOT_TENURED);
7540 return MakePair(*compiled, *receiver); 7842 return MakePair(*compiled, *receiver);
7541 } 7843 }
7542 7844
7543 7845
7544 static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) { 7846 static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) {
7545 ASSERT(args.length() == 3); 7847 ASSERT(args.length() == 4);
7546 if (!args[0]->IsJSFunction()) { 7848 if (!args[0]->IsJSFunction()) {
7547 return MakePair(Top::ThrowIllegalOperation(), NULL); 7849 return MakePair(Top::ThrowIllegalOperation(), NULL);
7548 } 7850 }
7549 7851
7550 HandleScope scope; 7852 HandleScope scope;
7551 Handle<JSFunction> callee = args.at<JSFunction>(0); 7853 Handle<JSFunction> callee = args.at<JSFunction>(0);
7552 Handle<Object> receiver; // Will be overwritten. 7854 Handle<Object> receiver; // Will be overwritten.
7553 7855
7554 // Compute the calling context. 7856 // Compute the calling context.
7555 Handle<Context> context = Handle<Context>(Top::context()); 7857 Handle<Context> context = Handle<Context>(Top::context());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7599 return MakePair(*callee, *receiver); 7901 return MakePair(*callee, *receiver);
7600 } 7902 }
7601 7903
7602 // 'eval' is bound in the global context, but it may have been overwritten. 7904 // 'eval' is bound in the global context, but it may have been overwritten.
7603 // Compare it to the builtin 'GlobalEval' function to make sure. 7905 // Compare it to the builtin 'GlobalEval' function to make sure.
7604 if (*callee != Top::global_context()->global_eval_fun() || 7906 if (*callee != Top::global_context()->global_eval_fun() ||
7605 !args[1]->IsString()) { 7907 !args[1]->IsString()) {
7606 return MakePair(*callee, Top::context()->global()->global_receiver()); 7908 return MakePair(*callee, Top::context()->global()->global_receiver());
7607 } 7909 }
7608 7910
7609 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); 7911 ASSERT(args[3]->IsSmi());
7912 return CompileGlobalEval(args.at<String>(1),
7913 args.at<Object>(2),
7914 static_cast<StrictModeFlag>(
7915 Smi::cast(args[3])->value()));
7610 } 7916 }
7611 7917
7612 7918
7613 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup(Arguments args) { 7919 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup(Arguments args) {
7614 ASSERT(args.length() == 3); 7920 ASSERT(args.length() == 4);
7615 if (!args[0]->IsJSFunction()) { 7921 if (!args[0]->IsJSFunction()) {
7616 return MakePair(Top::ThrowIllegalOperation(), NULL); 7922 return MakePair(Top::ThrowIllegalOperation(), NULL);
7617 } 7923 }
7618 7924
7619 HandleScope scope; 7925 HandleScope scope;
7620 Handle<JSFunction> callee = args.at<JSFunction>(0); 7926 Handle<JSFunction> callee = args.at<JSFunction>(0);
7621 7927
7622 // 'eval' is bound in the global context, but it may have been overwritten. 7928 // 'eval' is bound in the global context, but it may have been overwritten.
7623 // Compare it to the builtin 'GlobalEval' function to make sure. 7929 // Compare it to the builtin 'GlobalEval' function to make sure.
7624 if (*callee != Top::global_context()->global_eval_fun() || 7930 if (*callee != Top::global_context()->global_eval_fun() ||
7625 !args[1]->IsString()) { 7931 !args[1]->IsString()) {
7626 return MakePair(*callee, Top::context()->global()->global_receiver()); 7932 return MakePair(*callee, Top::context()->global()->global_receiver());
7627 } 7933 }
7628 7934
7629 return CompileGlobalEval(args.at<String>(1), args.at<Object>(2)); 7935 ASSERT(args[3]->IsSmi());
7936 return CompileGlobalEval(args.at<String>(1),
7937 args.at<Object>(2),
7938 static_cast<StrictModeFlag>(
7939 Smi::cast(args[3])->value()));
7630 } 7940 }
7631 7941
7632 7942
7633 static MaybeObject* Runtime_SetNewFunctionAttributes(Arguments args) { 7943 static MaybeObject* Runtime_SetNewFunctionAttributes(Arguments args) {
7634 // This utility adjusts the property attributes for newly created Function 7944 // This utility adjusts the property attributes for newly created Function
7635 // object ("new Function(...)") by changing the map. 7945 // object ("new Function(...)") by changing the map.
7636 // All it does is changing the prototype property to enumerable 7946 // All it does is changing the prototype property to enumerable
7637 // as specified in ECMA262, 15.3.5.2. 7947 // as specified in ECMA262, 15.3.5.2.
7638 HandleScope scope; 7948 HandleScope scope;
7639 ASSERT(args.length() == 1); 7949 ASSERT(args.length() == 1);
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
8050 } 8360 }
8051 if (JSObject::kMaxElementCount - result_length < length_estimate) { 8361 if (JSObject::kMaxElementCount - result_length < length_estimate) {
8052 result_length = JSObject::kMaxElementCount; 8362 result_length = JSObject::kMaxElementCount;
8053 break; 8363 break;
8054 } 8364 }
8055 result_length += length_estimate; 8365 result_length += length_estimate;
8056 } 8366 }
8057 } 8367 }
8058 } 8368 }
8059 8369
8060 // Allocate an empty array, will set length and content later. 8370 // Allocate an empty array, will set map, length, and content later.
8061 Handle<JSArray> result = Factory::NewJSArray(0); 8371 Handle<JSArray> result = Factory::NewJSArray(0);
8062 8372
8063 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL); 8373 uint32_t estimate_nof_elements = IterateArguments(arguments, NULL);
8064 // If estimated number of elements is more than half of length, a 8374 // If estimated number of elements is more than half of length, a
8065 // fixed array (fast case) is more time and space-efficient than a 8375 // fixed array (fast case) is more time and space-efficient than a
8066 // dictionary. 8376 // dictionary.
8067 bool fast_case = (estimate_nof_elements * 2) >= result_length; 8377 bool fast_case = (estimate_nof_elements * 2) >= result_length;
8068 8378
8379 Handle<Map> map;
8069 Handle<FixedArray> storage; 8380 Handle<FixedArray> storage;
8070 if (fast_case) { 8381 if (fast_case) {
8071 // The backing storage array must have non-existing elements to 8382 // The backing storage array must have non-existing elements to
8072 // preserve holes across concat operations. 8383 // preserve holes across concat operations.
8384 map = Factory::GetFastElementsMap(Handle<Map>(result->map()));
8073 storage = Factory::NewFixedArrayWithHoles(result_length); 8385 storage = Factory::NewFixedArrayWithHoles(result_length);
8074 Handle<Map> fast_map =
8075 Factory::GetFastElementsMap(Handle<Map>(result->map()));
8076 result->set_map(*fast_map);
8077 } else { 8386 } else {
8387 map = Factory::GetSlowElementsMap(Handle<Map>(result->map()));
8078 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate 8388 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
8079 uint32_t at_least_space_for = estimate_nof_elements + 8389 uint32_t at_least_space_for = estimate_nof_elements +
8080 (estimate_nof_elements >> 2); 8390 (estimate_nof_elements >> 2);
8081 storage = Handle<FixedArray>::cast( 8391 storage = Handle<FixedArray>::cast(
8082 Factory::NewNumberDictionary(at_least_space_for)); 8392 Factory::NewNumberDictionary(at_least_space_for));
8083 Handle<Map> slow_map =
8084 Factory::GetSlowElementsMap(Handle<Map>(result->map()));
8085 result->set_map(*slow_map);
8086 } 8393 }
8087 8394
8088 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length)); 8395 Handle<Object> len = Factory::NewNumber(static_cast<double>(result_length));
8089 8396
8090 ArrayConcatVisitor visitor(storage, result_length, fast_case); 8397 ArrayConcatVisitor visitor(storage, result_length, fast_case);
8091 8398
8092 IterateArguments(arguments, &visitor); 8399 IterateArguments(arguments, &visitor);
8093 8400
8401 // Please note:
8402 // - the storage might have been changed in the visitor;
8403 // - the map and the storage must be set together to avoid breaking
8404 // the invariant that the map describes the array's elements.
8405 result->set_map(*map);
8094 result->set_length(*len); 8406 result->set_length(*len);
8095 // Please note the storage might have changed in the visitor.
8096 result->set_elements(*visitor.storage()); 8407 result->set_elements(*visitor.storage());
8097 8408
8098 return *result; 8409 return *result;
8099 } 8410 }
8100 8411
8101 8412
8102 // This will not allocate (flatten the string), but it may run 8413 // This will not allocate (flatten the string), but it may run
8103 // very slowly for very deeply nested ConsStrings. For debugging use only. 8414 // very slowly for very deeply nested ConsStrings. For debugging use only.
8104 static MaybeObject* Runtime_GlobalPrint(Arguments args) { 8415 static MaybeObject* Runtime_GlobalPrint(Arguments args) {
8105 NoHandleAllocation ha; 8416 NoHandleAllocation ha;
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
8679 for (int i = 0; i < info.NumberOfLocals(); i++) { 8990 for (int i = 0; i < info.NumberOfLocals(); i++) {
8680 locals->set(i * 2, *info.LocalName(i)); 8991 locals->set(i * 2, *info.LocalName(i));
8681 } 8992 }
8682 8993
8683 // Fill in the values of the locals. 8994 // Fill in the values of the locals.
8684 for (int i = 0; i < info.NumberOfLocals(); i++) { 8995 for (int i = 0; i < info.NumberOfLocals(); i++) {
8685 if (is_optimized_frame) { 8996 if (is_optimized_frame) {
8686 // If we are inspecting an optimized frame use undefined as the 8997 // If we are inspecting an optimized frame use undefined as the
8687 // value for all locals. 8998 // value for all locals.
8688 // 8999 //
8689 // TODO(3141533): We should be able to get the correct values 9000 // TODO(1140): We should be able to get the correct values
8690 // for locals in optimized frames. 9001 // for locals in optimized frames.
8691 locals->set(i * 2 + 1, Heap::undefined_value()); 9002 locals->set(i * 2 + 1, Heap::undefined_value());
8692 } else if (i < info.number_of_stack_slots()) { 9003 } else if (i < info.number_of_stack_slots()) {
8693 // Get the value from the stack. 9004 // Get the value from the stack.
8694 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); 9005 locals->set(i * 2 + 1, it.frame()->GetExpression(i));
8695 } else { 9006 } else {
8696 // Traverse the context chain to the function context as all local 9007 // Traverse the context chain to the function context as all local
8697 // variables stored in the context will be on the function context. 9008 // variables stored in the context will be on the function context.
8698 Handle<String> name = info.LocalName(i); 9009 Handle<String> name = info.LocalName(i);
8699 while (!context->is_function_context()) { 9010 while (!context->is_function_context()) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
8843 receiver = Factory::ToObject(receiver, calling_frames_global_context); 9154 receiver = Factory::ToObject(receiver, calling_frames_global_context);
8844 } 9155 }
8845 details->set(kFrameDetailsReceiverIndex, *receiver); 9156 details->set(kFrameDetailsReceiverIndex, *receiver);
8846 9157
8847 ASSERT_EQ(details_size, details_index); 9158 ASSERT_EQ(details_size, details_index);
8848 return *Factory::NewJSArrayWithElements(details); 9159 return *Factory::NewJSArrayWithElements(details);
8849 } 9160 }
8850 9161
8851 9162
8852 // Copy all the context locals into an object used to materialize a scope. 9163 // Copy all the context locals into an object used to materialize a scope.
8853 static void CopyContextLocalsToScopeObject( 9164 static bool CopyContextLocalsToScopeObject(
8854 Handle<SerializedScopeInfo> serialized_scope_info, 9165 Handle<SerializedScopeInfo> serialized_scope_info,
8855 ScopeInfo<>& scope_info, 9166 ScopeInfo<>& scope_info,
8856 Handle<Context> context, 9167 Handle<Context> context,
8857 Handle<JSObject> scope_object) { 9168 Handle<JSObject> scope_object) {
8858 // Fill all context locals to the context extension. 9169 // Fill all context locals to the context extension.
8859 for (int i = Context::MIN_CONTEXT_SLOTS; 9170 for (int i = Context::MIN_CONTEXT_SLOTS;
8860 i < scope_info.number_of_context_slots(); 9171 i < scope_info.number_of_context_slots();
8861 i++) { 9172 i++) {
8862 int context_index = serialized_scope_info->ContextSlotIndex( 9173 int context_index = serialized_scope_info->ContextSlotIndex(
8863 *scope_info.context_slot_name(i), NULL); 9174 *scope_info.context_slot_name(i), NULL);
8864 9175
8865 // Don't include the arguments shadow (.arguments) context variable. 9176 // Don't include the arguments shadow (.arguments) context variable.
8866 if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) { 9177 if (*scope_info.context_slot_name(i) != Heap::arguments_shadow_symbol()) {
8867 SetProperty(scope_object, 9178 RETURN_IF_EMPTY_HANDLE_VALUE(
8868 scope_info.context_slot_name(i), 9179 SetProperty(scope_object,
8869 Handle<Object>(context->get(context_index)), NONE); 9180 scope_info.context_slot_name(i),
9181 Handle<Object>(context->get(context_index)), NONE),
9182 false);
8870 } 9183 }
8871 } 9184 }
9185
9186 return true;
8872 } 9187 }
8873 9188
8874 9189
8875 // Create a plain JSObject which materializes the local scope for the specified 9190 // Create a plain JSObject which materializes the local scope for the specified
8876 // frame. 9191 // frame.
8877 static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) { 9192 static Handle<JSObject> MaterializeLocalScope(JavaScriptFrame* frame) {
8878 Handle<JSFunction> function(JSFunction::cast(frame->function())); 9193 Handle<JSFunction> function(JSFunction::cast(frame->function()));
8879 Handle<SharedFunctionInfo> shared(function->shared()); 9194 Handle<SharedFunctionInfo> shared(function->shared());
8880 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); 9195 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
8881 ScopeInfo<> scope_info(*serialized_scope_info); 9196 ScopeInfo<> scope_info(*serialized_scope_info);
8882 9197
8883 // Allocate and initialize a JSObject with all the arguments, stack locals 9198 // Allocate and initialize a JSObject with all the arguments, stack locals
8884 // heap locals and extension properties of the debugged function. 9199 // heap locals and extension properties of the debugged function.
8885 Handle<JSObject> local_scope = Factory::NewJSObject(Top::object_function()); 9200 Handle<JSObject> local_scope = Factory::NewJSObject(Top::object_function());
8886 9201
8887 // First fill all parameters. 9202 // First fill all parameters.
8888 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { 9203 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
8889 SetProperty(local_scope, 9204 RETURN_IF_EMPTY_HANDLE_VALUE(
8890 scope_info.parameter_name(i), 9205 SetProperty(local_scope,
8891 Handle<Object>(frame->GetParameter(i)), NONE); 9206 scope_info.parameter_name(i),
9207 Handle<Object>(frame->GetParameter(i)), NONE),
9208 Handle<JSObject>());
8892 } 9209 }
8893 9210
8894 // Second fill all stack locals. 9211 // Second fill all stack locals.
8895 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { 9212 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
8896 SetProperty(local_scope, 9213 RETURN_IF_EMPTY_HANDLE_VALUE(
8897 scope_info.stack_slot_name(i), 9214 SetProperty(local_scope,
8898 Handle<Object>(frame->GetExpression(i)), NONE); 9215 scope_info.stack_slot_name(i),
9216 Handle<Object>(frame->GetExpression(i)), NONE),
9217 Handle<JSObject>());
8899 } 9218 }
8900 9219
8901 // Third fill all context locals. 9220 // Third fill all context locals.
8902 Handle<Context> frame_context(Context::cast(frame->context())); 9221 Handle<Context> frame_context(Context::cast(frame->context()));
8903 Handle<Context> function_context(frame_context->fcontext()); 9222 Handle<Context> function_context(frame_context->fcontext());
8904 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, 9223 if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
8905 function_context, local_scope); 9224 function_context, local_scope)) {
9225 return Handle<JSObject>();
9226 }
8906 9227
8907 // Finally copy any properties from the function context extension. This will 9228 // Finally copy any properties from the function context extension. This will
8908 // be variables introduced by eval. 9229 // be variables introduced by eval.
8909 if (function_context->closure() == *function) { 9230 if (function_context->closure() == *function) {
8910 if (function_context->has_extension() && 9231 if (function_context->has_extension() &&
8911 !function_context->IsGlobalContext()) { 9232 !function_context->IsGlobalContext()) {
8912 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 9233 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
8913 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); 9234 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
8914 for (int i = 0; i < keys->length(); i++) { 9235 for (int i = 0; i < keys->length(); i++) {
8915 // Names of variables introduced by eval are strings. 9236 // Names of variables introduced by eval are strings.
8916 ASSERT(keys->get(i)->IsString()); 9237 ASSERT(keys->get(i)->IsString());
8917 Handle<String> key(String::cast(keys->get(i))); 9238 Handle<String> key(String::cast(keys->get(i)));
8918 SetProperty(local_scope, key, GetProperty(ext, key), NONE); 9239 RETURN_IF_EMPTY_HANDLE_VALUE(
9240 SetProperty(local_scope, key, GetProperty(ext, key), NONE),
9241 Handle<JSObject>());
8919 } 9242 }
8920 } 9243 }
8921 } 9244 }
8922 return local_scope; 9245 return local_scope;
8923 } 9246 }
8924 9247
8925 9248
8926 // Create a plain JSObject which materializes the closure content for the 9249 // Create a plain JSObject which materializes the closure content for the
8927 // context. 9250 // context.
8928 static Handle<JSObject> MaterializeClosure(Handle<Context> context) { 9251 static Handle<JSObject> MaterializeClosure(Handle<Context> context) {
(...skipping 12 matching lines...) Expand all
8941 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(), 9264 shared->scope_info()->ContextSlotIndex(Heap::arguments_shadow_symbol(),
8942 NULL); 9265 NULL);
8943 if (arguments_shadow_index >= 0) { 9266 if (arguments_shadow_index >= 0) {
8944 // In this case all the arguments are available in the arguments shadow 9267 // In this case all the arguments are available in the arguments shadow
8945 // object. 9268 // object.
8946 Handle<JSObject> arguments_shadow( 9269 Handle<JSObject> arguments_shadow(
8947 JSObject::cast(context->get(arguments_shadow_index))); 9270 JSObject::cast(context->get(arguments_shadow_index)));
8948 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { 9271 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
8949 // We don't expect exception-throwing getters on the arguments shadow. 9272 // We don't expect exception-throwing getters on the arguments shadow.
8950 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); 9273 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
8951 SetProperty(closure_scope, 9274 RETURN_IF_EMPTY_HANDLE_VALUE(
8952 scope_info.parameter_name(i), 9275 SetProperty(closure_scope,
8953 Handle<Object>(element), 9276 scope_info.parameter_name(i),
8954 NONE); 9277 Handle<Object>(element),
9278 NONE),
9279 Handle<JSObject>());
8955 } 9280 }
8956 } 9281 }
8957 9282
8958 // Fill all context locals to the context extension. 9283 // Fill all context locals to the context extension.
8959 CopyContextLocalsToScopeObject(serialized_scope_info, scope_info, 9284 if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
8960 context, closure_scope); 9285 context, closure_scope)) {
9286 return Handle<JSObject>();
9287 }
8961 9288
8962 // Finally copy any properties from the function context extension. This will 9289 // Finally copy any properties from the function context extension. This will
8963 // be variables introduced by eval. 9290 // be variables introduced by eval.
8964 if (context->has_extension()) { 9291 if (context->has_extension()) {
8965 Handle<JSObject> ext(JSObject::cast(context->extension())); 9292 Handle<JSObject> ext(JSObject::cast(context->extension()));
8966 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); 9293 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
8967 for (int i = 0; i < keys->length(); i++) { 9294 for (int i = 0; i < keys->length(); i++) {
8968 // Names of variables introduced by eval are strings. 9295 // Names of variables introduced by eval are strings.
8969 ASSERT(keys->get(i)->IsString()); 9296 ASSERT(keys->get(i)->IsString());
8970 Handle<String> key(String::cast(keys->get(i))); 9297 Handle<String> key(String::cast(keys->get(i)));
8971 SetProperty(closure_scope, key, GetProperty(ext, key), NONE); 9298 RETURN_IF_EMPTY_HANDLE_VALUE(
9299 SetProperty(closure_scope, key, GetProperty(ext, key), NONE),
9300 Handle<JSObject>());
8972 } 9301 }
8973 } 9302 }
8974 9303
8975 return closure_scope; 9304 return closure_scope;
8976 } 9305 }
8977 9306
8978 9307
8979 // Iterate over the actual scopes visible from a stack frame. All scopes are 9308 // Iterate over the actual scopes visible from a stack frame. All scopes are
8980 // backed by an actual context except the local scope, which is inserted 9309 // backed by an actual context except the local scope, which is inserted
8981 // "artifically" in the context chain. 9310 // "artifically" in the context chain.
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
9248 return Heap::undefined_value(); 9577 return Heap::undefined_value();
9249 } 9578 }
9250 9579
9251 // Calculate the size of the result. 9580 // Calculate the size of the result.
9252 int details_size = kScopeDetailsSize; 9581 int details_size = kScopeDetailsSize;
9253 Handle<FixedArray> details = Factory::NewFixedArray(details_size); 9582 Handle<FixedArray> details = Factory::NewFixedArray(details_size);
9254 9583
9255 // Fill in scope details. 9584 // Fill in scope details.
9256 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); 9585 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
9257 Handle<JSObject> scope_object = it.ScopeObject(); 9586 Handle<JSObject> scope_object = it.ScopeObject();
9587 RETURN_IF_EMPTY_HANDLE(scope_object);
9258 details->set(kScopeDetailsObjectIndex, *scope_object); 9588 details->set(kScopeDetailsObjectIndex, *scope_object);
9259 9589
9260 return *Factory::NewJSArrayWithElements(details); 9590 return *Factory::NewJSArrayWithElements(details);
9261 } 9591 }
9262 9592
9263 9593
9264 static MaybeObject* Runtime_DebugPrintScopes(Arguments args) { 9594 static MaybeObject* Runtime_DebugPrintScopes(Arguments args) {
9265 HandleScope scope; 9595 HandleScope scope;
9266 ASSERT(args.length() == 0); 9596 ASSERT(args.length() == 0);
9267 9597
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
9729 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value()); 10059 Factory::NewFunction(Factory::empty_string(), Factory::undefined_value());
9730 go_between->set_context(function->context()); 10060 go_between->set_context(function->context());
9731 #ifdef DEBUG 10061 #ifdef DEBUG
9732 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info()); 10062 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info());
9733 ASSERT(go_between_sinfo.number_of_parameters() == 0); 10063 ASSERT(go_between_sinfo.number_of_parameters() == 0);
9734 ASSERT(go_between_sinfo.number_of_context_slots() == 0); 10064 ASSERT(go_between_sinfo.number_of_context_slots() == 0);
9735 #endif 10065 #endif
9736 10066
9737 // Materialize the content of the local scope into a JSObject. 10067 // Materialize the content of the local scope into a JSObject.
9738 Handle<JSObject> local_scope = MaterializeLocalScope(frame); 10068 Handle<JSObject> local_scope = MaterializeLocalScope(frame);
10069 RETURN_IF_EMPTY_HANDLE(local_scope);
9739 10070
9740 // Allocate a new context for the debug evaluation and set the extension 10071 // Allocate a new context for the debug evaluation and set the extension
9741 // object build. 10072 // object build.
9742 Handle<Context> context = 10073 Handle<Context> context =
9743 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); 10074 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between);
9744 context->set_extension(*local_scope); 10075 context->set_extension(*local_scope);
9745 // Copy any with contexts present and chain them in front of this context. 10076 // Copy any with contexts present and chain them in front of this context.
9746 Handle<Context> frame_context(Context::cast(frame->context())); 10077 Handle<Context> frame_context(Context::cast(frame->context()));
9747 Handle<Context> function_context(frame_context->fcontext()); 10078 Handle<Context> function_context(frame_context->fcontext());
9748 context = CopyWithContextChain(frame_context, context); 10079 context = CopyWithContextChain(frame_context, context);
9749 10080
9750 if (additional_context->IsJSObject()) { 10081 if (additional_context->IsJSObject()) {
9751 context = Factory::NewWithContext(context, 10082 context = Factory::NewWithContext(context,
9752 Handle<JSObject>::cast(additional_context), false); 10083 Handle<JSObject>::cast(additional_context), false);
9753 } 10084 }
9754 10085
9755 // Wrap the evaluation statement in a new function compiled in the newly 10086 // Wrap the evaluation statement in a new function compiled in the newly
9756 // created context. The function has one parameter which has to be called 10087 // created context. The function has one parameter which has to be called
9757 // 'arguments'. This it to have access to what would have been 'arguments' in 10088 // 'arguments'. This it to have access to what would have been 'arguments' in
9758 // the function being debugged. 10089 // the function being debugged.
9759 // function(arguments,__source__) {return eval(__source__);} 10090 // function(arguments,__source__) {return eval(__source__);}
9760 static const char* source_str = 10091 static const char* source_str =
9761 "(function(arguments,__source__){return eval(__source__);})"; 10092 "(function(arguments,__source__){return eval(__source__);})";
9762 static const int source_str_length = StrLength(source_str); 10093 static const int source_str_length = StrLength(source_str);
9763 Handle<String> function_source = 10094 Handle<String> function_source =
9764 Factory::NewStringFromAscii(Vector<const char>(source_str, 10095 Factory::NewStringFromAscii(Vector<const char>(source_str,
9765 source_str_length)); 10096 source_str_length));
10097
10098 // Currently, the eval code will be executed in non-strict mode,
10099 // even in the strict code context.
9766 Handle<SharedFunctionInfo> shared = 10100 Handle<SharedFunctionInfo> shared =
9767 Compiler::CompileEval(function_source, 10101 Compiler::CompileEval(function_source,
9768 context, 10102 context,
9769 context->IsGlobalContext()); 10103 context->IsGlobalContext(),
10104 kNonStrictMode);
9770 if (shared.is_null()) return Failure::Exception(); 10105 if (shared.is_null()) return Failure::Exception();
9771 Handle<JSFunction> compiled_function = 10106 Handle<JSFunction> compiled_function =
9772 Factory::NewFunctionFromSharedFunctionInfo(shared, context); 10107 Factory::NewFunctionFromSharedFunctionInfo(shared, context);
9773 10108
9774 // Invoke the result of the compilation to get the evaluation function. 10109 // Invoke the result of the compilation to get the evaluation function.
9775 bool has_pending_exception; 10110 bool has_pending_exception;
9776 Handle<Object> receiver(frame->receiver()); 10111 Handle<Object> receiver(frame->receiver());
9777 Handle<Object> evaluation_function = 10112 Handle<Object> evaluation_function =
9778 Execution::Call(compiled_function, receiver, 0, NULL, 10113 Execution::Call(compiled_function, receiver, 0, NULL,
9779 &has_pending_exception); 10114 &has_pending_exception);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
9841 Handle<JSFunction> go_between = Factory::NewFunction( 10176 Handle<JSFunction> go_between = Factory::NewFunction(
9842 Factory::empty_string(), Factory::undefined_value()); 10177 Factory::empty_string(), Factory::undefined_value());
9843 go_between->set_context(*context); 10178 go_between->set_context(*context);
9844 context = 10179 context =
9845 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between); 10180 Factory::NewFunctionContext(Context::MIN_CONTEXT_SLOTS, go_between);
9846 context->set_extension(JSObject::cast(*additional_context)); 10181 context->set_extension(JSObject::cast(*additional_context));
9847 is_global = false; 10182 is_global = false;
9848 } 10183 }
9849 10184
9850 // Compile the source to be evaluated. 10185 // Compile the source to be evaluated.
10186 // Currently, the eval code will be executed in non-strict mode,
10187 // even in the strict code context.
9851 Handle<SharedFunctionInfo> shared = 10188 Handle<SharedFunctionInfo> shared =
9852 Compiler::CompileEval(source, 10189 Compiler::CompileEval(source, context, is_global, kNonStrictMode);
9853 context,
9854 is_global);
9855 if (shared.is_null()) return Failure::Exception(); 10190 if (shared.is_null()) return Failure::Exception();
9856 Handle<JSFunction> compiled_function = 10191 Handle<JSFunction> compiled_function =
9857 Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared, 10192 Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared,
9858 context)); 10193 context));
9859 10194
9860 // Invoke the result of the compilation to get the evaluation function. 10195 // Invoke the result of the compilation to get the evaluation function.
9861 bool has_pending_exception; 10196 bool has_pending_exception;
9862 Handle<Object> receiver = Top::global(); 10197 Handle<Object> receiver = Top::global();
9863 Handle<Object> result = 10198 Handle<Object> result =
9864 Execution::Call(compiled_function, receiver, 0, NULL, 10199 Execution::Call(compiled_function, receiver, 0, NULL,
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
10327 // LiveEdit::FunctionPatchabilityStatus type. 10662 // LiveEdit::FunctionPatchabilityStatus type.
10328 static MaybeObject* Runtime_LiveEditCheckAndDropActivations(Arguments args) { 10663 static MaybeObject* Runtime_LiveEditCheckAndDropActivations(Arguments args) {
10329 ASSERT(args.length() == 2); 10664 ASSERT(args.length() == 2);
10330 HandleScope scope; 10665 HandleScope scope;
10331 CONVERT_ARG_CHECKED(JSArray, shared_array, 0); 10666 CONVERT_ARG_CHECKED(JSArray, shared_array, 0);
10332 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]); 10667 CONVERT_BOOLEAN_CHECKED(do_drop, args[1]);
10333 10668
10334 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop); 10669 return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
10335 } 10670 }
10336 10671
10337 // Compares 2 strings line-by-line and returns diff in form of JSArray of 10672 // Compares 2 strings line-by-line, then token-wise and returns diff in form
10338 // triplets (pos1, pos1_end, pos2_end) describing list of diff chunks. 10673 // of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
10339 static MaybeObject* Runtime_LiveEditCompareStringsLinewise(Arguments args) { 10674 // of diff chunks.
10675 static MaybeObject* Runtime_LiveEditCompareStrings(Arguments args) {
10340 ASSERT(args.length() == 2); 10676 ASSERT(args.length() == 2);
10341 HandleScope scope; 10677 HandleScope scope;
10342 CONVERT_ARG_CHECKED(String, s1, 0); 10678 CONVERT_ARG_CHECKED(String, s1, 0);
10343 CONVERT_ARG_CHECKED(String, s2, 1); 10679 CONVERT_ARG_CHECKED(String, s2, 1);
10344 10680
10345 return *LiveEdit::CompareStringsLinewise(s1, s2); 10681 return *LiveEdit::CompareStrings(s1, s2);
10346 } 10682 }
10347 10683
10348 10684
10349 10685
10350 // A testing entry. Returns statement position which is the closest to 10686 // A testing entry. Returns statement position which is the closest to
10351 // source_position. 10687 // source_position.
10352 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(Arguments args) { 10688 static MaybeObject* Runtime_GetFunctionCodePositionFromSource(Arguments args) {
10353 ASSERT(args.length() == 2); 10689 ASSERT(args.length() == 2);
10354 HandleScope scope; 10690 HandleScope scope;
10355 CONVERT_ARG_CHECKED(JSFunction, function, 0); 10691 CONVERT_ARG_CHECKED(JSFunction, function, 0);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
10405 } 10741 }
10406 } 10742 }
10407 if (!pending_exception) { 10743 if (!pending_exception) {
10408 return *result; 10744 return *result;
10409 } else { 10745 } else {
10410 return Failure::Exception(); 10746 return Failure::Exception();
10411 } 10747 }
10412 } 10748 }
10413 10749
10414 10750
10751 // Sets a v8 flag.
10752 static MaybeObject* Runtime_SetFlags(Arguments args) {
10753 CONVERT_CHECKED(String, arg, args[0]);
10754 SmartPointer<char> flags =
10755 arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
10756 FlagList::SetFlagsFromString(*flags, StrLength(*flags));
10757 return Heap::undefined_value();
10758 }
10759
10760
10761 // Performs a GC.
10762 // Presently, it only does a full GC.
10763 static MaybeObject* Runtime_CollectGarbage(Arguments args) {
10764 Heap::CollectAllGarbage(true);
10765 return Heap::undefined_value();
10766 }
10767
10768
10769 // Gets the current heap usage.
10770 static MaybeObject* Runtime_GetHeapUsage(Arguments args) {
10771 int usage = static_cast<int>(Heap::SizeOfObjects());
10772 if (!Smi::IsValid(usage)) {
10773 return *Factory::NewNumberFromInt(usage);
10774 }
10775 return Smi::FromInt(usage);
10776 }
10415 #endif // ENABLE_DEBUGGER_SUPPORT 10777 #endif // ENABLE_DEBUGGER_SUPPORT
10416 10778
10779
10417 #ifdef ENABLE_LOGGING_AND_PROFILING 10780 #ifdef ENABLE_LOGGING_AND_PROFILING
10418
10419 static MaybeObject* Runtime_ProfilerResume(Arguments args) { 10781 static MaybeObject* Runtime_ProfilerResume(Arguments args) {
10420 NoHandleAllocation ha; 10782 NoHandleAllocation ha;
10421 ASSERT(args.length() == 2); 10783 ASSERT(args.length() == 2);
10422 10784
10423 CONVERT_CHECKED(Smi, smi_modules, args[0]); 10785 CONVERT_CHECKED(Smi, smi_modules, args[0]);
10424 CONVERT_CHECKED(Smi, smi_tag, args[1]); 10786 CONVERT_CHECKED(Smi, smi_tag, args[1]);
10425 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value()); 10787 v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
10426 return Heap::undefined_value(); 10788 return Heap::undefined_value();
10427 } 10789 }
10428 10790
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
10586 ASSERT(args.length() == 2); 10948 ASSERT(args.length() == 2);
10587 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) + 10949 OS::PrintError("abort: %s\n", reinterpret_cast<char*>(args[0]) +
10588 Smi::cast(args[1])->value()); 10950 Smi::cast(args[1])->value());
10589 Top::PrintStack(); 10951 Top::PrintStack();
10590 OS::Abort(); 10952 OS::Abort();
10591 UNREACHABLE(); 10953 UNREACHABLE();
10592 return NULL; 10954 return NULL;
10593 } 10955 }
10594 10956
10595 10957
10596 MUST_USE_RESULT static MaybeObject* CacheMiss(FixedArray* cache_obj,
10597 int index,
10598 Object* key_obj) {
10599 ASSERT(index % 2 == 0); // index of the key
10600 ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
10601 ASSERT(index < cache_obj->length());
10602
10603 HandleScope scope;
10604
10605 Handle<FixedArray> cache(cache_obj);
10606 Handle<Object> key(key_obj);
10607 Handle<JSFunction> factory(JSFunction::cast(
10608 cache->get(JSFunctionResultCache::kFactoryIndex)));
10609 // TODO(antonm): consider passing a receiver when constructing a cache.
10610 Handle<Object> receiver(Top::global_context()->global());
10611
10612 Handle<Object> value;
10613 {
10614 // This handle is nor shared, nor used later, so it's safe.
10615 Object** argv[] = { key.location() };
10616 bool pending_exception = false;
10617 value = Execution::Call(factory,
10618 receiver,
10619 1,
10620 argv,
10621 &pending_exception);
10622 if (pending_exception) return Failure::Exception();
10623 }
10624
10625 cache->set(index, *key);
10626 cache->set(index + 1, *value);
10627 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(index));
10628
10629 return *value;
10630 }
10631
10632
10633 static MaybeObject* Runtime_GetFromCache(Arguments args) { 10958 static MaybeObject* Runtime_GetFromCache(Arguments args) {
10634 // This is only called from codegen, so checks might be more lax. 10959 // This is only called from codegen, so checks might be more lax.
10635 CONVERT_CHECKED(FixedArray, cache, args[0]); 10960 CONVERT_CHECKED(JSFunctionResultCache, cache, args[0]);
10636 Object* key = args[1]; 10961 Object* key = args[1];
10637 10962
10638 const int finger_index = 10963 int finger_index = cache->finger_index();
10639 Smi::cast(cache->get(JSFunctionResultCache::kFingerIndex))->value();
10640
10641 Object* o = cache->get(finger_index); 10964 Object* o = cache->get(finger_index);
10642 if (o == key) { 10965 if (o == key) {
10643 // The fastest case: hit the same place again. 10966 // The fastest case: hit the same place again.
10644 return cache->get(finger_index + 1); 10967 return cache->get(finger_index + 1);
10645 } 10968 }
10646 10969
10647 for (int i = finger_index - 2; 10970 for (int i = finger_index - 2;
10648 i >= JSFunctionResultCache::kEntriesIndex; 10971 i >= JSFunctionResultCache::kEntriesIndex;
10649 i -= 2) { 10972 i -= 2) {
10650 o = cache->get(i); 10973 o = cache->get(i);
10651 if (o == key) { 10974 if (o == key) {
10652 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); 10975 cache->set_finger_index(i);
10653 return cache->get(i + 1); 10976 return cache->get(i + 1);
10654 } 10977 }
10655 } 10978 }
10656 10979
10657 const int size = 10980 int size = cache->size();
10658 Smi::cast(cache->get(JSFunctionResultCache::kCacheSizeIndex))->value();
10659 ASSERT(size <= cache->length()); 10981 ASSERT(size <= cache->length());
10660 10982
10661 for (int i = size - 2; i > finger_index; i -= 2) { 10983 for (int i = size - 2; i > finger_index; i -= 2) {
10662 o = cache->get(i); 10984 o = cache->get(i);
10663 if (o == key) { 10985 if (o == key) {
10664 cache->set(JSFunctionResultCache::kFingerIndex, Smi::FromInt(i)); 10986 cache->set_finger_index(i);
10665 return cache->get(i + 1); 10987 return cache->get(i + 1);
10666 } 10988 }
10667 } 10989 }
10668 10990
10669 // Cache miss. If we have spare room, put new data into it, otherwise 10991 // There is no value in the cache. Invoke the function and cache result.
10670 // evict post finger entry which must be least recently used. 10992 HandleScope scope;
10671 if (size < cache->length()) { 10993
10672 cache->set(JSFunctionResultCache::kCacheSizeIndex, Smi::FromInt(size + 2)); 10994 Handle<JSFunctionResultCache> cache_handle(cache);
10673 return CacheMiss(cache, size, key); 10995 Handle<Object> key_handle(key);
10996 Handle<Object> value;
10997 {
10998 Handle<JSFunction> factory(JSFunction::cast(
10999 cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
11000 // TODO(antonm): consider passing a receiver when constructing a cache.
11001 Handle<Object> receiver(Top::global_context()->global());
11002 // This handle is nor shared, nor used later, so it's safe.
11003 Object** argv[] = { key_handle.location() };
11004 bool pending_exception = false;
11005 value = Execution::Call(factory,
11006 receiver,
11007 1,
11008 argv,
11009 &pending_exception);
11010 if (pending_exception) return Failure::Exception();
11011 }
11012
11013 #ifdef DEBUG
11014 cache_handle->JSFunctionResultCacheVerify();
11015 #endif
11016
11017 // Function invocation may have cleared the cache. Reread all the data.
11018 finger_index = cache_handle->finger_index();
11019 size = cache_handle->size();
11020
11021 // If we have spare room, put new data into it, otherwise evict post finger
11022 // entry which is likely to be the least recently used.
11023 int index = -1;
11024 if (size < cache_handle->length()) {
11025 cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
11026 index = size;
10674 } else { 11027 } else {
10675 int target_index = finger_index + JSFunctionResultCache::kEntrySize; 11028 index = finger_index + JSFunctionResultCache::kEntrySize;
10676 if (target_index == cache->length()) { 11029 if (index == cache_handle->length()) {
10677 target_index = JSFunctionResultCache::kEntriesIndex; 11030 index = JSFunctionResultCache::kEntriesIndex;
10678 } 11031 }
10679 return CacheMiss(cache, target_index, key);
10680 } 11032 }
11033
11034 ASSERT(index % 2 == 0);
11035 ASSERT(index >= JSFunctionResultCache::kEntriesIndex);
11036 ASSERT(index < cache_handle->length());
11037
11038 cache_handle->set(index, *key_handle);
11039 cache_handle->set(index + 1, *value);
11040 cache_handle->set_finger_index(index);
11041
11042 #ifdef DEBUG
11043 cache_handle->JSFunctionResultCacheVerify();
11044 #endif
11045
11046 return *value;
10681 } 11047 }
10682 11048
11049
11050 static MaybeObject* Runtime_NewMessageObject(Arguments args) {
11051 HandleScope scope;
11052 CONVERT_ARG_CHECKED(String, type, 0);
11053 CONVERT_ARG_CHECKED(JSArray, arguments, 1);
11054 return *Factory::NewJSMessageObject(type,
11055 arguments,
11056 0,
11057 0,
11058 Factory::undefined_value(),
11059 Factory::undefined_value(),
11060 Factory::undefined_value());
11061 }
11062
11063
11064 static MaybeObject* Runtime_MessageGetType(Arguments args) {
11065 CONVERT_CHECKED(JSMessageObject, message, args[0]);
11066 return message->type();
11067 }
11068
11069
11070 static MaybeObject* Runtime_MessageGetArguments(Arguments args) {
11071 CONVERT_CHECKED(JSMessageObject, message, args[0]);
11072 return message->arguments();
11073 }
11074
11075
11076 static MaybeObject* Runtime_MessageGetStartPosition(Arguments args) {
11077 CONVERT_CHECKED(JSMessageObject, message, args[0]);
11078 return Smi::FromInt(message->start_position());
11079 }
11080
11081
11082 static MaybeObject* Runtime_MessageGetScript(Arguments args) {
11083 CONVERT_CHECKED(JSMessageObject, message, args[0]);
11084 return message->script();
11085 }
11086
11087
10683 #ifdef DEBUG 11088 #ifdef DEBUG
10684 // ListNatives is ONLY used by the fuzz-natives.js in debug mode 11089 // ListNatives is ONLY used by the fuzz-natives.js in debug mode
10685 // Exclude the code in release mode. 11090 // Exclude the code in release mode.
10686 static MaybeObject* Runtime_ListNatives(Arguments args) { 11091 static MaybeObject* Runtime_ListNatives(Arguments args) {
10687 ASSERT(args.length() == 0); 11092 ASSERT(args.length() == 0);
10688 HandleScope scope; 11093 HandleScope scope;
10689 Handle<JSArray> result = Factory::NewJSArray(0); 11094 Handle<JSArray> result = Factory::NewJSArray(0);
10690 int index = 0; 11095 int index = 0;
10691 bool inline_runtime_functions = false; 11096 bool inline_runtime_functions = false;
10692 #define ADD_ENTRY(Name, argc, ressize) \ 11097 #define ADD_ENTRY(Name, argc, ressize) \
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
10802 } else { 11207 } else {
10803 // Handle last resort GC and make sure to allow future allocations 11208 // Handle last resort GC and make sure to allow future allocations
10804 // to grow the heap without causing GCs (if possible). 11209 // to grow the heap without causing GCs (if possible).
10805 Counters::gc_last_resort_from_js.Increment(); 11210 Counters::gc_last_resort_from_js.Increment();
10806 Heap::CollectAllGarbage(false); 11211 Heap::CollectAllGarbage(false);
10807 } 11212 }
10808 } 11213 }
10809 11214
10810 11215
10811 } } // namespace v8::internal 11216 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698