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

Side by Side Diff: src/runtime.cc

Issue 6614010: [Isolates] Merge 6700:7030 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 years, 9 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 22 matching lines...) Expand all
33 #include "api.h" 33 #include "api.h"
34 #include "arguments.h" 34 #include "arguments.h"
35 #include "codegen.h" 35 #include "codegen.h"
36 #include "compilation-cache.h" 36 #include "compilation-cache.h"
37 #include "compiler.h" 37 #include "compiler.h"
38 #include "cpu.h" 38 #include "cpu.h"
39 #include "dateparser-inl.h" 39 #include "dateparser-inl.h"
40 #include "debug.h" 40 #include "debug.h"
41 #include "deoptimizer.h" 41 #include "deoptimizer.h"
42 #include "execution.h" 42 #include "execution.h"
43 #include "global-handles.h"
43 #include "jsregexp.h" 44 #include "jsregexp.h"
44 #include "liveedit.h" 45 #include "liveedit.h"
46 #include "liveobjectlist-inl.h"
45 #include "parser.h" 47 #include "parser.h"
46 #include "platform.h" 48 #include "platform.h"
47 #include "runtime.h" 49 #include "runtime.h"
48 #include "runtime-profiler.h" 50 #include "runtime-profiler.h"
49 #include "scopeinfo.h" 51 #include "scopeinfo.h"
50 #include "smart-pointer.h" 52 #include "smart-pointer.h"
51 #include "stub-cache.h" 53 #include "stub-cache.h"
52 #include "v8threads.h" 54 #include "v8threads.h"
53 #include "string-search.h" 55 #include "string-search.h"
54 56
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 // an array. 154 // an array.
153 if (attributes != NONE) continue; 155 if (attributes != NONE) continue;
154 Object* value = 156 Object* value =
155 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); 157 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
156 if (value->IsJSObject()) { 158 if (value->IsJSObject()) {
157 JSObject* js_object = JSObject::cast(value); 159 JSObject* js_object = JSObject::cast(value);
158 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object); 160 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, js_object);
159 if (!maybe_result->ToObject(&result)) return maybe_result; 161 if (!maybe_result->ToObject(&result)) return maybe_result;
160 } 162 }
161 { MaybeObject* maybe_result = 163 { MaybeObject* maybe_result =
162 copy->SetProperty(key_string, result, NONE); 164 // Creating object copy for literals. No strict mode needed.
165 copy->SetProperty(key_string, result, NONE, kNonStrictMode);
163 if (!maybe_result->ToObject(&result)) return maybe_result; 166 if (!maybe_result->ToObject(&result)) return maybe_result;
164 } 167 }
165 } 168 }
166 } 169 }
167 } 170 }
168 171
169 // Deep copy local elements. 172 // Deep copy local elements.
170 // Pixel elements cannot be created using an object literal. 173 // Pixel elements cannot be created using an object literal.
171 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements()); 174 ASSERT(!copy->HasPixelElements() && !copy->HasExternalArrayElements());
172 switch (copy->GetElementsKind()) { 175 switch (copy->GetElementsKind()) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 JSFunction* constructor = 569 JSFunction* constructor =
567 isolate->context()->global_context()-> 570 isolate->context()->global_context()->
568 context_extension_function(); 571 context_extension_function();
569 Object* object; 572 Object* object;
570 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor); 573 { MaybeObject* maybe_object = isolate->heap()->AllocateJSObject(constructor);
571 if (!maybe_object->ToObject(&object)) return maybe_object; 574 if (!maybe_object->ToObject(&object)) return maybe_object;
572 } 575 }
573 // Assign the exception value to the catch variable and make sure 576 // Assign the exception value to the catch variable and make sure
574 // that the catch variable is DontDelete. 577 // that the catch variable is DontDelete.
575 { MaybeObject* maybe_value = 578 { MaybeObject* maybe_value =
576 JSObject::cast(object)->SetProperty(key, value, DONT_DELETE); 579 // Passing non-strict per ECMA-262 5th Ed. 12.14. Catch, bullet #4.
580 JSObject::cast(object)->SetProperty(
581 key, value, DONT_DELETE, kNonStrictMode);
577 if (!maybe_value->ToObject(&value)) return maybe_value; 582 if (!maybe_value->ToObject(&value)) return maybe_value;
578 } 583 }
579 return object; 584 return object;
580 } 585 }
581 586
582 587
583 static MaybeObject* Runtime_ClassOf(RUNTIME_CALLING_CONVENTION) { 588 static MaybeObject* Runtime_ClassOf(RUNTIME_CALLING_CONVENTION) {
584 RUNTIME_GET_ISOLATE; 589 RUNTIME_GET_ISOLATE;
585 NoHandleAllocation ha; 590 NoHandleAllocation ha;
586 ASSERT(args.length() == 1); 591 ASSERT(args.length() == 1);
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 elms->set(VALUE_INDEX, *substr); 815 elms->set(VALUE_INDEX, *substr);
811 elms->set(WRITABLE_INDEX, heap->false_value()); 816 elms->set(WRITABLE_INDEX, heap->false_value());
812 elms->set(ENUMERABLE_INDEX, heap->false_value()); 817 elms->set(ENUMERABLE_INDEX, heap->false_value());
813 elms->set(CONFIGURABLE_INDEX, heap->false_value()); 818 elms->set(CONFIGURABLE_INDEX, heap->false_value());
814 return *desc; 819 return *desc;
815 } 820 }
816 821
817 case JSObject::INTERCEPTED_ELEMENT: 822 case JSObject::INTERCEPTED_ELEMENT:
818 case JSObject::FAST_ELEMENT: { 823 case JSObject::FAST_ELEMENT: {
819 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); 824 elms->set(IS_ACCESSOR_INDEX, heap->false_value());
820 elms->set(VALUE_INDEX, *GetElement(obj, index)); 825 Handle<Object> value = GetElement(obj, index);
826 elms->set(VALUE_INDEX, *value);
821 elms->set(WRITABLE_INDEX, heap->true_value()); 827 elms->set(WRITABLE_INDEX, heap->true_value());
822 elms->set(ENUMERABLE_INDEX, heap->true_value()); 828 elms->set(ENUMERABLE_INDEX, heap->true_value());
823 elms->set(CONFIGURABLE_INDEX, heap->true_value()); 829 elms->set(CONFIGURABLE_INDEX, heap->true_value());
824 return *desc; 830 return *desc;
825 } 831 }
826 832
827 case JSObject::DICTIONARY_ELEMENT: { 833 case JSObject::DICTIONARY_ELEMENT: {
828 Handle<JSObject> holder = obj; 834 Handle<JSObject> holder = obj;
829 if (obj->IsJSGlobalProxy()) { 835 if (obj->IsJSGlobalProxy()) {
830 Object* proto = obj->GetPrototype(); 836 Object* proto = obj->GetPrototype();
(...skipping 12 matching lines...) Expand all
843 FixedArray::cast(dictionary->ValueAt(entry)); 849 FixedArray::cast(dictionary->ValueAt(entry));
844 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); 850 elms->set(IS_ACCESSOR_INDEX, heap->true_value());
845 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { 851 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
846 elms->set(GETTER_INDEX, callbacks->get(0)); 852 elms->set(GETTER_INDEX, callbacks->get(0));
847 } 853 }
848 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { 854 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
849 elms->set(SETTER_INDEX, callbacks->get(1)); 855 elms->set(SETTER_INDEX, callbacks->get(1));
850 } 856 }
851 break; 857 break;
852 } 858 }
853 case NORMAL: 859 case NORMAL: {
854 // This is a data property. 860 // This is a data property.
855 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); 861 elms->set(IS_ACCESSOR_INDEX, heap->false_value());
856 elms->set(VALUE_INDEX, *GetElement(obj, index)); 862 Handle<Object> value = GetElement(obj, index);
863 elms->set(VALUE_INDEX, *value);
857 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); 864 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly()));
858 break; 865 break;
866 }
859 default: 867 default:
860 UNREACHABLE(); 868 UNREACHABLE();
861 break; 869 break;
862 } 870 }
863 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum())); 871 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!details.IsDontEnum()));
864 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete())); 872 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!details.IsDontDelete()));
865 return *desc; 873 return *desc;
866 } 874 }
867 } 875 }
868 } 876 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 isolate->factory()->NewStringFromAscii(CStrVector(type)); 1042 isolate->factory()->NewStringFromAscii(CStrVector(type));
1035 Handle<Object> args[2] = { type_handle, name }; 1043 Handle<Object> args[2] = { type_handle, name };
1036 Handle<Object> error = 1044 Handle<Object> error =
1037 isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2)); 1045 isolate->factory()->NewTypeError("redeclaration", HandleVector(args, 2));
1038 return isolate->Throw(*error); 1046 return isolate->Throw(*error);
1039 } 1047 }
1040 1048
1041 1049
1042 static MaybeObject* Runtime_DeclareGlobals(RUNTIME_CALLING_CONVENTION) { 1050 static MaybeObject* Runtime_DeclareGlobals(RUNTIME_CALLING_CONVENTION) {
1043 RUNTIME_GET_ISOLATE; 1051 RUNTIME_GET_ISOLATE;
1052 ASSERT(args.length() == 4);
1044 HandleScope scope(isolate); 1053 HandleScope scope(isolate);
1045 Handle<GlobalObject> global = Handle<GlobalObject>( 1054 Handle<GlobalObject> global = Handle<GlobalObject>(
1046 isolate->context()->global()); 1055 isolate->context()->global());
1047 1056
1048 Handle<Context> context = args.at<Context>(0); 1057 Handle<Context> context = args.at<Context>(0);
1049 CONVERT_ARG_CHECKED(FixedArray, pairs, 1); 1058 CONVERT_ARG_CHECKED(FixedArray, pairs, 1);
1050 bool is_eval = Smi::cast(args[2])->value() == 1; 1059 bool is_eval = Smi::cast(args[2])->value() == 1;
1060 StrictModeFlag strict_mode =
1061 static_cast<StrictModeFlag>(Smi::cast(args[3])->value());
1062 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1051 1063
1052 // Compute the property attributes. According to ECMA-262, section 1064 // Compute the property attributes. According to ECMA-262, section
1053 // 13, page 71, the property must be read-only and 1065 // 13, page 71, the property must be read-only and
1054 // non-deletable. However, neither SpiderMonkey nor KJS creates the 1066 // non-deletable. However, neither SpiderMonkey nor KJS creates the
1055 // property as read-only, so we don't either. 1067 // property as read-only, so we don't either.
1056 PropertyAttributes base = is_eval ? NONE : DONT_DELETE; 1068 PropertyAttributes base = is_eval ? NONE : DONT_DELETE;
1057 1069
1058 // Traverse the name/value pairs and set the properties. 1070 // Traverse the name/value pairs and set the properties.
1059 int length = pairs->length(); 1071 int length = pairs->length();
1060 for (int i = 0; i < length; i += 2) { 1072 for (int i = 0; i < length; i += 2) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1092 const char* type = (is_read_only) ? "const" : "var"; 1104 const char* type = (is_read_only) ? "const" : "var";
1093 return ThrowRedeclarationError(isolate, type, name); 1105 return ThrowRedeclarationError(isolate, type, name);
1094 }; 1106 };
1095 // The property already exists without conflicting: Go to 1107 // The property already exists without conflicting: Go to
1096 // the next declaration. 1108 // the next declaration.
1097 continue; 1109 continue;
1098 } 1110 }
1099 // Fall-through and introduce the absent property by using 1111 // Fall-through and introduce the absent property by using
1100 // SetProperty. 1112 // SetProperty.
1101 } else { 1113 } else {
1114 // For const properties, we treat a callback with this name
1115 // even in the prototype as a conflicting declaration.
1116 if (is_const_property && (lookup.type() == CALLBACKS)) {
1117 return ThrowRedeclarationError(isolate, "const", name);
1118 }
1119 // Otherwise, we check for locally conflicting declarations.
1102 if (is_local && (is_read_only || is_const_property)) { 1120 if (is_local && (is_read_only || is_const_property)) {
1103 const char* type = (is_read_only) ? "const" : "var"; 1121 const char* type = (is_read_only) ? "const" : "var";
1104 return ThrowRedeclarationError(isolate, type, name); 1122 return ThrowRedeclarationError(isolate, type, name);
1105 } 1123 }
1106 // The property already exists without conflicting: Go to 1124 // The property already exists without conflicting: Go to
1107 // the next declaration. 1125 // the next declaration.
1108 continue; 1126 continue;
1109 } 1127 }
1110 } 1128 }
1111 } else { 1129 } else {
1112 // Copy the function and update its context. Use it as value. 1130 // Copy the function and update its context. Use it as value.
1113 Handle<SharedFunctionInfo> shared = 1131 Handle<SharedFunctionInfo> shared =
1114 Handle<SharedFunctionInfo>::cast(value); 1132 Handle<SharedFunctionInfo>::cast(value);
1115 Handle<JSFunction> function = 1133 Handle<JSFunction> function =
1116 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, 1134 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
1117 context, 1135 context,
1118 TENURED); 1136 TENURED);
1119 value = function; 1137 value = function;
1120 } 1138 }
1121 1139
1122 LookupResult lookup; 1140 LookupResult lookup;
1123 global->LocalLookup(*name, &lookup); 1141 global->LocalLookup(*name, &lookup);
1124 1142
1125 PropertyAttributes attributes = is_const_property 1143 PropertyAttributes attributes = is_const_property
1126 ? static_cast<PropertyAttributes>(base | READ_ONLY) 1144 ? static_cast<PropertyAttributes>(base | READ_ONLY)
1127 : base; 1145 : base;
1128 1146
1129 if (lookup.IsProperty()) { 1147 // There's a local property that we need to overwrite because
1130 // There's a local property that we need to overwrite because 1148 // we're either declaring a function or there's an interceptor
1131 // we're either declaring a function or there's an interceptor 1149 // that claims the property is absent.
1132 // that claims the property is absent. 1150 //
1151 // Check for conflicting re-declarations. We cannot have
1152 // conflicting types in case of intercepted properties because
1153 // they are absent.
1154 if (lookup.IsProperty() &&
1155 (lookup.type() != INTERCEPTOR) &&
1156 (lookup.IsReadOnly() || is_const_property)) {
1157 const char* type = (lookup.IsReadOnly()) ? "const" : "var";
1158 return ThrowRedeclarationError(isolate, type, name);
1159 }
1133 1160
1134 // Check for conflicting re-declarations. We cannot have 1161 // Safari does not allow the invocation of callback setters for
1135 // conflicting types in case of intercepted properties because 1162 // function declarations. To mimic this behavior, we do not allow
1136 // they are absent. 1163 // the invocation of setters for function values. This makes a
1137 if (lookup.type() != INTERCEPTOR && 1164 // difference for global functions with the same names as event
1138 (lookup.IsReadOnly() || is_const_property)) { 1165 // handlers such as "function onload() {}". Firefox does call the
1139 const char* type = (lookup.IsReadOnly()) ? "const" : "var"; 1166 // onload setter in those case and Safari does not. We follow
1140 return ThrowRedeclarationError(isolate, type, name); 1167 // Safari for compatibility.
1168 if (value->IsJSFunction()) {
1169 // Do not change DONT_DELETE to false from true.
1170 if (lookup.IsProperty() && (lookup.type() != INTERCEPTOR)) {
1171 attributes = static_cast<PropertyAttributes>(
1172 attributes | (lookup.GetAttributes() & DONT_DELETE));
1141 } 1173 }
1142 Handle<Object> result = SetProperty(global, name, value, attributes); 1174 RETURN_IF_EMPTY_HANDLE(isolate,
1143 if (result.is_null()) { 1175 SetLocalPropertyIgnoreAttributes(global,
1144 ASSERT(isolate->has_pending_exception()); 1176 name,
1145 return Failure::Exception(); 1177 value,
1146 } 1178 attributes));
1147 } else { 1179 } else {
1148 // If a property with this name does not already exist on the 1180 RETURN_IF_EMPTY_HANDLE(isolate,
1149 // global object add the property locally. We take special 1181 SetProperty(global,
1150 // precautions to always add it as a local property even in case 1182 name,
1151 // of callbacks in the prototype chain (this rules out using 1183 value,
1152 // SetProperty). Also, we must use the handle-based version to 1184 attributes,
1153 // avoid GC issues. 1185 strict_mode));
1154 Handle<Object> result =
1155 SetLocalPropertyIgnoreAttributes(global, name, value, attributes);
1156 if (result.is_null()) {
1157 ASSERT(isolate->has_pending_exception());
1158 return Failure::Exception();
1159 }
1160 } 1186 }
1161 } 1187 }
1162 1188
1163 ASSERT(!isolate->has_pending_exception()); 1189 ASSERT(!isolate->has_pending_exception());
1164 return isolate->heap()->undefined_value(); 1190 return isolate->heap()->undefined_value();
1165 } 1191 }
1166 1192
1167 1193
1168 static MaybeObject* Runtime_DeclareContextSlot(RUNTIME_CALLING_CONVENTION) { 1194 static MaybeObject* Runtime_DeclareContextSlot(RUNTIME_CALLING_CONVENTION) {
1169 RUNTIME_GET_ISOLATE; 1195 RUNTIME_GET_ISOLATE;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 } 1236 }
1211 } else { 1237 } else {
1212 // The holder is an arguments object. 1238 // The holder is an arguments object.
1213 Handle<JSObject> arguments(Handle<JSObject>::cast(holder)); 1239 Handle<JSObject> arguments(Handle<JSObject>::cast(holder));
1214 Handle<Object> result = SetElement(arguments, index, initial_value); 1240 Handle<Object> result = SetElement(arguments, index, initial_value);
1215 if (result.is_null()) return Failure::Exception(); 1241 if (result.is_null()) return Failure::Exception();
1216 } 1242 }
1217 } else { 1243 } else {
1218 // Slow case: The property is not in the FixedArray part of the context. 1244 // Slow case: The property is not in the FixedArray part of the context.
1219 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1245 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1220 Handle<Object> result = 1246 RETURN_IF_EMPTY_HANDLE(
1221 SetProperty(context_ext, name, initial_value, mode); 1247 isolate,
1222 if (result.is_null()) return Failure::Exception(); 1248 SetProperty(context_ext, name, initial_value,
1249 mode, kNonStrictMode));
1223 } 1250 }
1224 } 1251 }
1225 1252
1226 } else { 1253 } else {
1227 // The property is not in the function context. It needs to be 1254 // The property is not in the function context. It needs to be
1228 // "declared" in the function context's extension context, or in the 1255 // "declared" in the function context's extension context, or in the
1229 // global context. 1256 // global context.
1230 Handle<JSObject> context_ext; 1257 Handle<JSObject> context_ext;
1231 if (context->has_extension()) { 1258 if (context->has_extension()) {
1232 // The function context's extension context exists - use it. 1259 // The function context's extension context exists - use it.
1233 context_ext = Handle<JSObject>(context->extension()); 1260 context_ext = Handle<JSObject>(context->extension());
1234 } else { 1261 } else {
1235 // The function context's extension context does not exists - allocate 1262 // The function context's extension context does not exists - allocate
1236 // it. 1263 // it.
1237 context_ext = isolate->factory()->NewJSObject( 1264 context_ext = isolate->factory()->NewJSObject(
1238 isolate->context_extension_function()); 1265 isolate->context_extension_function());
1239 // And store it in the extension slot. 1266 // And store it in the extension slot.
1240 context->set_extension(*context_ext); 1267 context->set_extension(*context_ext);
1241 } 1268 }
1242 ASSERT(*context_ext != NULL); 1269 ASSERT(*context_ext != NULL);
1243 1270
1244 // Declare the property by setting it to the initial value if provided, 1271 // Declare the property by setting it to the initial value if provided,
1245 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for 1272 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
1246 // constant declarations). 1273 // constant declarations).
1247 ASSERT(!context_ext->HasLocalProperty(*name)); 1274 ASSERT(!context_ext->HasLocalProperty(*name));
1248 Handle<Object> value(isolate->heap()->undefined_value(), isolate); 1275 Handle<Object> value(isolate->heap()->undefined_value(), isolate);
1249 if (*initial_value != NULL) value = initial_value; 1276 if (*initial_value != NULL) value = initial_value;
1250 Handle<Object> result = SetProperty(context_ext, name, value, mode); 1277 // Declaring a const context slot is a conflicting declaration if
1251 if (result.is_null()) return Failure::Exception(); 1278 // there is a callback with that name in a prototype. It is
1279 // allowed to introduce const variables in
1280 // JSContextExtensionObjects. They are treated specially in
1281 // SetProperty and no setters are invoked for those since they are
1282 // not real JSObjects.
1283 if (initial_value->IsTheHole() &&
1284 !context_ext->IsJSContextExtensionObject()) {
1285 LookupResult lookup;
1286 context_ext->Lookup(*name, &lookup);
1287 if (lookup.IsProperty() && (lookup.type() == CALLBACKS)) {
1288 return ThrowRedeclarationError(isolate, "const", name);
1289 }
1290 }
1291 RETURN_IF_EMPTY_HANDLE(isolate,
1292 SetProperty(context_ext, name, value, mode,
1293 kNonStrictMode));
1252 } 1294 }
1253 1295
1254 return isolate->heap()->undefined_value(); 1296 return isolate->heap()->undefined_value();
1255 } 1297 }
1256 1298
1257 1299
1258 static MaybeObject* Runtime_InitializeVarGlobal(RUNTIME_CALLING_CONVENTION) { 1300 static MaybeObject* Runtime_InitializeVarGlobal(RUNTIME_CALLING_CONVENTION) {
1259 RUNTIME_GET_ISOLATE; 1301 RUNTIME_GET_ISOLATE;
1260 NoHandleAllocation nha; 1302 NoHandleAllocation nha;
1303 // args[0] == name
1304 // args[1] == strict_mode
1305 // args[2] == value (optional)
1261 1306
1262 // Determine if we need to assign to the variable if it already 1307 // Determine if we need to assign to the variable if it already
1263 // exists (based on the number of arguments). 1308 // exists (based on the number of arguments).
1264 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); 1309 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
1265 bool assign = args.length() == 2; 1310 bool assign = args.length() == 3;
1266 1311
1267 CONVERT_ARG_CHECKED(String, name, 0); 1312 CONVERT_ARG_CHECKED(String, name, 0);
1268 GlobalObject* global = isolate->context()->global(); 1313 GlobalObject* global = isolate->context()->global();
1314 RUNTIME_ASSERT(args[1]->IsSmi());
1315 StrictModeFlag strict_mode =
1316 static_cast<StrictModeFlag>(Smi::cast(args[1])->value());
1317 ASSERT(strict_mode == kStrictMode || strict_mode == kNonStrictMode);
1269 1318
1270 // According to ECMA-262, section 12.2, page 62, the property must 1319 // According to ECMA-262, section 12.2, page 62, the property must
1271 // not be deletable. 1320 // not be deletable.
1272 PropertyAttributes attributes = DONT_DELETE; 1321 PropertyAttributes attributes = DONT_DELETE;
1273 1322
1274 // Lookup the property locally in the global object. If it isn't 1323 // Lookup the property locally in the global object. If it isn't
1275 // there, there is a property with this name in the prototype chain. 1324 // there, there is a property with this name in the prototype chain.
1276 // We follow Safari and Firefox behavior and only set the property 1325 // We follow Safari and Firefox behavior and only set the property
1277 // locally if there is an explicit initialization value that we have 1326 // locally if there is an explicit initialization value that we have
1278 // to assign to the property. When adding the property we take 1327 // to assign to the property.
1279 // special precautions to always add it as a local property even in
1280 // case of callbacks in the prototype chain (this rules out using
1281 // SetProperty). We have SetLocalPropertyIgnoreAttributes for
1282 // this.
1283 // Note that objects can have hidden prototypes, so we need to traverse 1328 // Note that objects can have hidden prototypes, so we need to traverse
1284 // the whole chain of hidden prototypes to do a 'local' lookup. 1329 // the whole chain of hidden prototypes to do a 'local' lookup.
1285 JSObject* real_holder = global; 1330 JSObject* real_holder = global;
1286 LookupResult lookup; 1331 LookupResult lookup;
1287 while (true) { 1332 while (true) {
1288 real_holder->LocalLookup(*name, &lookup); 1333 real_holder->LocalLookup(*name, &lookup);
1289 if (lookup.IsProperty()) { 1334 if (lookup.IsProperty()) {
1290 // Determine if this is a redeclaration of something read-only. 1335 // Determine if this is a redeclaration of something read-only.
1291 if (lookup.IsReadOnly()) { 1336 if (lookup.IsReadOnly()) {
1292 // If we found readonly property on one of hidden prototypes, 1337 // If we found readonly property on one of hidden prototypes,
(...skipping 25 matching lines...) Expand all
1318 } 1363 }
1319 } 1364 }
1320 1365
1321 if (found && !assign) { 1366 if (found && !assign) {
1322 // The global property is there and we're not assigning any value 1367 // The global property is there and we're not assigning any value
1323 // to it. Just return. 1368 // to it. Just return.
1324 return isolate->heap()->undefined_value(); 1369 return isolate->heap()->undefined_value();
1325 } 1370 }
1326 1371
1327 // Assign the value (or undefined) to the property. 1372 // Assign the value (or undefined) to the property.
1328 Object* value = (assign) ? args[1] : isolate->heap()->undefined_value(); 1373 Object* value = (assign) ? args[2] : isolate->heap()->undefined_value();
1329 return real_holder->SetProperty(&lookup, *name, value, attributes); 1374 return real_holder->SetProperty(
1375 &lookup, *name, value, attributes, strict_mode);
1330 } 1376 }
1331 1377
1332 Object* proto = real_holder->GetPrototype(); 1378 Object* proto = real_holder->GetPrototype();
1333 if (!proto->IsJSObject()) 1379 if (!proto->IsJSObject())
1334 break; 1380 break;
1335 1381
1336 if (!JSObject::cast(proto)->map()->is_hidden_prototype()) 1382 if (!JSObject::cast(proto)->map()->is_hidden_prototype())
1337 break; 1383 break;
1338 1384
1339 real_holder = JSObject::cast(proto); 1385 real_holder = JSObject::cast(proto);
1340 } 1386 }
1341 1387
1342 global = isolate->context()->global(); 1388 global = isolate->context()->global();
1343 if (assign) { 1389 if (assign) {
1344 return global->SetLocalPropertyIgnoreAttributes(*name, 1390 return global->SetProperty(*name, args[2], attributes, strict_mode);
1345 args[1],
1346 attributes);
1347 } 1391 }
1348 return isolate->heap()->undefined_value(); 1392 return isolate->heap()->undefined_value();
1349 } 1393 }
1350 1394
1351 1395
1352 static MaybeObject* Runtime_InitializeConstGlobal(RUNTIME_CALLING_CONVENTION) { 1396 static MaybeObject* Runtime_InitializeConstGlobal(RUNTIME_CALLING_CONVENTION) {
1353 RUNTIME_GET_ISOLATE; 1397 RUNTIME_GET_ISOLATE;
1354 // All constants are declared with an initial value. The name 1398 // All constants are declared with an initial value. The name
1355 // of the constant is the first argument and the initial value 1399 // of the constant is the first argument and the initial value
1356 // is the second. 1400 // is the second.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { 1438 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
1395 return ThrowRedeclarationError(isolate, "var", name); 1439 return ThrowRedeclarationError(isolate, "var", name);
1396 } 1440 }
1397 1441
1398 // Restore global object from context (in case of GC) and continue 1442 // Restore global object from context (in case of GC) and continue
1399 // with setting the value because the property is either absent or 1443 // with setting the value because the property is either absent or
1400 // read-only. We also have to do redo the lookup. 1444 // read-only. We also have to do redo the lookup.
1401 HandleScope handle_scope(isolate); 1445 HandleScope handle_scope(isolate);
1402 Handle<GlobalObject> global(isolate->context()->global()); 1446 Handle<GlobalObject> global(isolate->context()->global());
1403 1447
1404 // BUG 1213579: Handle the case where we have to set a read-only 1448 // BUG 1213575: Handle the case where we have to set a read-only
1405 // property through an interceptor and only do it if it's 1449 // property through an interceptor and only do it if it's
1406 // uninitialized, e.g. the hole. Nirk... 1450 // uninitialized, e.g. the hole. Nirk...
1407 SetProperty(global, name, value, attributes); 1451 // Passing non-strict mode because the property is writable.
1452 RETURN_IF_EMPTY_HANDLE(isolate,
1453 SetProperty(global,
1454 name,
1455 value,
1456 attributes,
1457 kNonStrictMode));
1408 return *value; 1458 return *value;
1409 } 1459 }
1410 1460
1411 // Set the value, but only we're assigning the initial value to a 1461 // Set the value, but only we're assigning the initial value to a
1412 // constant. For now, we determine this by checking if the 1462 // constant. For now, we determine this by checking if the
1413 // current value is the hole. 1463 // current value is the hole.
1464 // Strict mode handling not needed (const disallowed in strict mode).
1414 PropertyType type = lookup.type(); 1465 PropertyType type = lookup.type();
1415 if (type == FIELD) { 1466 if (type == FIELD) {
1416 FixedArray* properties = global->properties(); 1467 FixedArray* properties = global->properties();
1417 int index = lookup.GetFieldIndex(); 1468 int index = lookup.GetFieldIndex();
1418 if (properties->get(index)->IsTheHole()) { 1469 if (properties->get(index)->IsTheHole()) {
1419 properties->set(index, *value); 1470 properties->set(index, *value);
1420 } 1471 }
1421 } else if (type == NORMAL) { 1472 } else if (type == NORMAL) {
1422 if (global->GetNormalizedProperty(&lookup)->IsTheHole()) { 1473 if (global->GetNormalizedProperty(&lookup)->IsTheHole()) {
1423 global->SetNormalizedProperty(&lookup, *value); 1474 global->SetNormalizedProperty(&lookup, *value);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1482 SetElement(arguments, index, value); 1533 SetElement(arguments, index, value);
1483 } 1534 }
1484 return *value; 1535 return *value;
1485 } 1536 }
1486 1537
1487 // The property could not be found, we introduce it in the global 1538 // The property could not be found, we introduce it in the global
1488 // context. 1539 // context.
1489 if (attributes == ABSENT) { 1540 if (attributes == ABSENT) {
1490 Handle<JSObject> global = Handle<JSObject>( 1541 Handle<JSObject> global = Handle<JSObject>(
1491 isolate->context()->global()); 1542 isolate->context()->global());
1492 SetProperty(global, name, value, NONE); 1543 // Strict mode not needed (const disallowed in strict mode).
1544 RETURN_IF_EMPTY_HANDLE(
1545 isolate,
1546 SetProperty(global, name, value, NONE, kNonStrictMode));
1493 return *value; 1547 return *value;
1494 } 1548 }
1495 1549
1496 // The property was present in a context extension object. 1550 // The property was present in a context extension object.
1497 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder); 1551 Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
1498 1552
1499 if (*context_ext == context->extension()) { 1553 if (*context_ext == context->extension()) {
1500 // This is the property that was introduced by the const 1554 // This is the property that was introduced by the const
1501 // declaration. Set it if it hasn't been set before. NOTE: We 1555 // declaration. Set it if it hasn't been set before. NOTE: We
1502 // cannot use GetProperty() to get the current value as it 1556 // cannot use GetProperty() to get the current value as it
(...skipping 16 matching lines...) Expand all
1519 } 1573 }
1520 } else { 1574 } else {
1521 // We should not reach here. Any real, named property should be 1575 // We should not reach here. Any real, named property should be
1522 // either a field or a dictionary slot. 1576 // either a field or a dictionary slot.
1523 UNREACHABLE(); 1577 UNREACHABLE();
1524 } 1578 }
1525 } else { 1579 } else {
1526 // The property was found in a different context extension object. 1580 // The property was found in a different context extension object.
1527 // Set it if it is not a read-only property. 1581 // Set it if it is not a read-only property.
1528 if ((attributes & READ_ONLY) == 0) { 1582 if ((attributes & READ_ONLY) == 0) {
1529 Handle<Object> set = SetProperty(context_ext, name, value, attributes); 1583 // Strict mode not needed (const disallowed in strict mode).
1530 // Setting a property might throw an exception. Exceptions 1584 RETURN_IF_EMPTY_HANDLE(
1531 // are converted to empty handles in handle operations. We 1585 isolate,
1532 // need to convert back to exceptions here. 1586 SetProperty(context_ext, name, value, attributes, kNonStrictMode));
1533 if (set.is_null()) {
1534 ASSERT(isolate->has_pending_exception());
1535 return Failure::Exception();
1536 }
1537 } 1587 }
1538 } 1588 }
1539 1589
1540 return *value; 1590 return *value;
1541 } 1591 }
1542 1592
1543 1593
1544 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties( 1594 static MaybeObject* Runtime_OptimizeObjectForAddingMultipleProperties(
1545 RUNTIME_CALLING_CONVENTION) { 1595 RUNTIME_CALLING_CONVENTION) {
1546 RUNTIME_GET_ISOLATE; 1596 RUNTIME_GET_ISOLATE;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 Builtins::Name builtin_name) { 1748 Builtins::Name builtin_name) {
1699 Handle<String> key = isolate->factory()->LookupAsciiSymbol(name); 1749 Handle<String> key = isolate->factory()->LookupAsciiSymbol(name);
1700 Handle<Code> code(isolate->builtins()->builtin(builtin_name)); 1750 Handle<Code> code(isolate->builtins()->builtin(builtin_name));
1701 Handle<JSFunction> optimized = 1751 Handle<JSFunction> optimized =
1702 isolate->factory()->NewFunction(key, 1752 isolate->factory()->NewFunction(key,
1703 JS_OBJECT_TYPE, 1753 JS_OBJECT_TYPE,
1704 JSObject::kHeaderSize, 1754 JSObject::kHeaderSize,
1705 code, 1755 code,
1706 false); 1756 false);
1707 optimized->shared()->DontAdaptArguments(); 1757 optimized->shared()->DontAdaptArguments();
1708 SetProperty(holder, key, optimized, NONE); 1758 SetProperty(holder, key, optimized, NONE, kStrictMode);
1709 return optimized; 1759 return optimized;
1710 } 1760 }
1711 1761
1712 1762
1713 static MaybeObject* Runtime_SpecialArrayFunctions(RUNTIME_CALLING_CONVENTION) { 1763 static MaybeObject* Runtime_SpecialArrayFunctions(RUNTIME_CALLING_CONVENTION) {
1714 RUNTIME_GET_ISOLATE; 1764 RUNTIME_GET_ISOLATE;
1715 HandleScope scope(isolate); 1765 HandleScope scope(isolate);
1716 ASSERT(args.length() == 1); 1766 ASSERT(args.length() == 1);
1717 CONVERT_ARG_CHECKED(JSObject, holder, 0); 1767 CONVERT_ARG_CHECKED(JSObject, holder, 0);
1718 1768
(...skipping 2124 matching lines...) Expand 10 before | Expand all | Expand 10 after
3843 uint32_t index; 3893 uint32_t index;
3844 bool is_element = name->AsArrayIndex(&index); 3894 bool is_element = name->AsArrayIndex(&index);
3845 3895
3846 // Special case for elements if any of the flags are true. 3896 // Special case for elements if any of the flags are true.
3847 // If elements are in fast case we always implicitly assume that: 3897 // If elements are in fast case we always implicitly assume that:
3848 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. 3898 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false.
3849 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && 3899 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) &&
3850 is_element) { 3900 is_element) {
3851 // Normalize the elements to enable attributes on the property. 3901 // Normalize the elements to enable attributes on the property.
3852 if (js_object->IsJSGlobalProxy()) { 3902 if (js_object->IsJSGlobalProxy()) {
3903 // We do not need to do access checks here since these has already
3904 // been performed by the call to GetOwnProperty.
3853 Handle<Object> proto(js_object->GetPrototype()); 3905 Handle<Object> proto(js_object->GetPrototype());
3854 // If proxy is detached, ignore the assignment. Alternatively, 3906 // If proxy is detached, ignore the assignment. Alternatively,
3855 // we could throw an exception. 3907 // we could throw an exception.
3856 if (proto->IsNull()) return *obj_value; 3908 if (proto->IsNull()) return *obj_value;
3857 js_object = Handle<JSObject>::cast(proto); 3909 js_object = Handle<JSObject>::cast(proto);
3858 } 3910 }
3859 NormalizeElements(js_object); 3911 NormalizeElements(js_object);
3860 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); 3912 Handle<NumberDictionary> dictionary(js_object->element_dictionary());
3861 // Make sure that we never go back to fast case. 3913 // Make sure that we never go back to fast case.
3862 dictionary->set_requires_slow_elements(); 3914 dictionary->set_requires_slow_elements();
(...skipping 20 matching lines...) Expand all
3883 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); 3935 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
3884 } 3936 }
3885 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 3937 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
3886 // Use IgnoreAttributes version since a readonly property may be 3938 // Use IgnoreAttributes version since a readonly property may be
3887 // overridden and SetProperty does not allow this. 3939 // overridden and SetProperty does not allow this.
3888 return js_object->SetLocalPropertyIgnoreAttributes(*name, 3940 return js_object->SetLocalPropertyIgnoreAttributes(*name,
3889 *obj_value, 3941 *obj_value,
3890 attr); 3942 attr);
3891 } 3943 }
3892 3944
3893 return Runtime::SetObjectProperty(isolate, js_object, name, obj_value, attr); 3945 return Runtime::ForceSetObjectProperty(isolate,
3946 js_object,
3947 name,
3948 obj_value,
3949 attr);
3894 } 3950 }
3895 3951
3896 3952
3897 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate, 3953 MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
3898 Handle<Object> object, 3954 Handle<Object> object,
3899 Handle<Object> key, 3955 Handle<Object> key,
3900 Handle<Object> value, 3956 Handle<Object> value,
3901 PropertyAttributes attr) { 3957 PropertyAttributes attr,
3958 StrictModeFlag strict) {
3902 HandleScope scope(isolate); 3959 HandleScope scope(isolate);
3903 3960
3904 if (object->IsUndefined() || object->IsNull()) { 3961 if (object->IsUndefined() || object->IsNull()) {
3905 Handle<Object> args[2] = { key, object }; 3962 Handle<Object> args[2] = { key, object };
3906 Handle<Object> error = 3963 Handle<Object> error =
3907 isolate->factory()->NewTypeError("non_object_property_store", 3964 isolate->factory()->NewTypeError("non_object_property_store",
3908 HandleVector(args, 2)); 3965 HandleVector(args, 2));
3909 return isolate->Throw(*error); 3966 return isolate->Throw(*error);
3910 } 3967 }
3911 3968
3912 // If the object isn't a JavaScript object, we ignore the store. 3969 // If the object isn't a JavaScript object, we ignore the store.
3913 if (!object->IsJSObject()) return *value; 3970 if (!object->IsJSObject()) return *value;
3914 3971
3915 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 3972 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
3916 3973
3917 // Check if the given key is an array index. 3974 // Check if the given key is an array index.
3918 uint32_t index; 3975 uint32_t index;
3919 if (key->ToArrayIndex(&index)) { 3976 if (key->ToArrayIndex(&index)) {
3920 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 3977 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
3921 // of a string using [] notation. We need to support this too in 3978 // of a string using [] notation. We need to support this too in
3922 // JavaScript. 3979 // JavaScript.
3923 // In the case of a String object we just need to redirect the assignment to 3980 // In the case of a String object we just need to redirect the assignment to
3924 // the underlying string if the index is in range. Since the underlying 3981 // the underlying string if the index is in range. Since the underlying
3925 // string does nothing with the assignment then we can ignore such 3982 // string does nothing with the assignment then we can ignore such
3926 // assignments. 3983 // assignments.
3927 if (js_object->IsStringObjectWithCharacterAt(index)) { 3984 if (js_object->IsStringObjectWithCharacterAt(index)) {
3928 return *value; 3985 return *value;
3929 } 3986 }
3930 3987
3988 // TODO(1220): Implement SetElement strict mode.
3931 Handle<Object> result = SetElement(js_object, index, value); 3989 Handle<Object> result = SetElement(js_object, index, value);
3932 if (result.is_null()) return Failure::Exception(); 3990 if (result.is_null()) return Failure::Exception();
3933 return *value; 3991 return *value;
3934 } 3992 }
3935 3993
3936 if (key->IsString()) { 3994 if (key->IsString()) {
3937 Handle<Object> result; 3995 Handle<Object> result;
3938 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 3996 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
3939 result = SetElement(js_object, index, value); 3997 result = SetElement(js_object, index, value);
3940 } else { 3998 } else {
3941 Handle<String> key_string = Handle<String>::cast(key); 3999 Handle<String> key_string = Handle<String>::cast(key);
3942 key_string->TryFlatten(); 4000 key_string->TryFlatten();
3943 result = SetProperty(js_object, key_string, value, attr); 4001 result = SetProperty(js_object, key_string, value, attr, strict);
3944 } 4002 }
3945 if (result.is_null()) return Failure::Exception(); 4003 if (result.is_null()) return Failure::Exception();
3946 return *value; 4004 return *value;
3947 } 4005 }
3948 4006
3949 // Call-back into JavaScript to convert the key to a string. 4007 // Call-back into JavaScript to convert the key to a string.
3950 bool has_pending_exception = false; 4008 bool has_pending_exception = false;
3951 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4009 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
3952 if (has_pending_exception) return Failure::Exception(); 4010 if (has_pending_exception) return Failure::Exception();
3953 Handle<String> name = Handle<String>::cast(converted); 4011 Handle<String> name = Handle<String>::cast(converted);
3954 4012
3955 if (name->AsArrayIndex(&index)) { 4013 if (name->AsArrayIndex(&index)) {
4014 // TODO(1220): Implement SetElement strict mode.
3956 return js_object->SetElement(index, *value); 4015 return js_object->SetElement(index, *value);
3957 } else { 4016 } else {
3958 return js_object->SetProperty(*name, *value, attr); 4017 return js_object->SetProperty(*name, *value, attr, strict);
3959 } 4018 }
3960 } 4019 }
3961 4020
3962 4021
3963 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 4022 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
3964 Handle<JSObject> js_object, 4023 Handle<JSObject> js_object,
3965 Handle<Object> key, 4024 Handle<Object> key,
3966 Handle<Object> value, 4025 Handle<Object> value,
3967 PropertyAttributes attr) { 4026 PropertyAttributes attr) {
3968 HandleScope scope(isolate); 4027 HandleScope scope(isolate);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4043 } 4102 }
4044 4103
4045 key_string->TryFlatten(); 4104 key_string->TryFlatten();
4046 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION); 4105 return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
4047 } 4106 }
4048 4107
4049 4108
4050 static MaybeObject* Runtime_SetProperty(RUNTIME_CALLING_CONVENTION) { 4109 static MaybeObject* Runtime_SetProperty(RUNTIME_CALLING_CONVENTION) {
4051 RUNTIME_GET_ISOLATE; 4110 RUNTIME_GET_ISOLATE;
4052 NoHandleAllocation ha; 4111 NoHandleAllocation ha;
4053 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); 4112 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
4054 4113
4055 Handle<Object> object = args.at<Object>(0); 4114 Handle<Object> object = args.at<Object>(0);
4056 Handle<Object> key = args.at<Object>(1); 4115 Handle<Object> key = args.at<Object>(1);
4057 Handle<Object> value = args.at<Object>(2); 4116 Handle<Object> value = args.at<Object>(2);
4117 CONVERT_SMI_CHECKED(unchecked_attributes, args[3]);
4118 RUNTIME_ASSERT(
4119 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4120 // Compute attributes.
4121 PropertyAttributes attributes =
4122 static_cast<PropertyAttributes>(unchecked_attributes);
4058 4123
4059 // Compute attributes. 4124 StrictModeFlag strict = kNonStrictMode;
4060 PropertyAttributes attributes = NONE; 4125 if (args.length() == 5) {
4061 if (args.length() == 4) { 4126 CONVERT_SMI_CHECKED(strict_unchecked, args[4]);
4062 CONVERT_CHECKED(Smi, value_obj, args[3]); 4127 RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
4063 int unchecked_value = value_obj->value(); 4128 strict_unchecked == kNonStrictMode);
4064 // Only attribute bits should be set. 4129 strict = static_cast<StrictModeFlag>(strict_unchecked);
4065 RUNTIME_ASSERT(
4066 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4067 attributes = static_cast<PropertyAttributes>(unchecked_value);
4068 } 4130 }
4069 return Runtime::SetObjectProperty(isolate, object, key, value, attributes); 4131
4132 return Runtime::SetObjectProperty(isolate,
4133 object,
4134 key,
4135 value,
4136 attributes,
4137 strict);
4070 } 4138 }
4071 4139
4072 4140
4073 // Set a local property, even if it is READ_ONLY. If the property does not 4141 // Set a local property, even if it is READ_ONLY. If the property does not
4074 // exist, it will be added with attributes NONE. 4142 // exist, it will be added with attributes NONE.
4075 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty( 4143 static MaybeObject* Runtime_IgnoreAttributesAndSetProperty(
4076 RUNTIME_CALLING_CONVENTION) { 4144 RUNTIME_CALLING_CONVENTION) {
4077 RUNTIME_GET_ISOLATE; 4145 RUNTIME_GET_ISOLATE;
4078 NoHandleAllocation ha; 4146 NoHandleAllocation ha;
4079 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); 4147 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
(...skipping 11 matching lines...) Expand all
4091 } 4159 }
4092 4160
4093 return object-> 4161 return object->
4094 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); 4162 SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
4095 } 4163 }
4096 4164
4097 4165
4098 static MaybeObject* Runtime_DeleteProperty(RUNTIME_CALLING_CONVENTION) { 4166 static MaybeObject* Runtime_DeleteProperty(RUNTIME_CALLING_CONVENTION) {
4099 RUNTIME_GET_ISOLATE; 4167 RUNTIME_GET_ISOLATE;
4100 NoHandleAllocation ha; 4168 NoHandleAllocation ha;
4101 ASSERT(args.length() == 2); 4169 ASSERT(args.length() == 3);
4102 4170
4103 CONVERT_CHECKED(JSObject, object, args[0]); 4171 CONVERT_CHECKED(JSObject, object, args[0]);
4104 CONVERT_CHECKED(String, key, args[1]); 4172 CONVERT_CHECKED(String, key, args[1]);
4105 return object->DeleteProperty(key, JSObject::NORMAL_DELETION); 4173 CONVERT_SMI_CHECKED(strict, args[2]);
4174 return object->DeleteProperty(key, (strict == kStrictMode)
4175 ? JSObject::STRICT_DELETION
4176 : JSObject::NORMAL_DELETION);
4106 } 4177 }
4107 4178
4108 4179
4109 static Object* HasLocalPropertyImplementation(Isolate* isolate, 4180 static Object* HasLocalPropertyImplementation(Isolate* isolate,
4110 Handle<JSObject> object, 4181 Handle<JSObject> object,
4111 Handle<String> key) { 4182 Handle<String> key) {
4112 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); 4183 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
4113 // Handle hidden prototypes. If there's a hidden prototype above this thing 4184 // Handle hidden prototypes. If there's a hidden prototype above this thing
4114 // then we have to check it for properties, because they are supposed to 4185 // then we have to check it for properties, because they are supposed to
4115 // look like they are on this object. 4186 // look like they are on this object.
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
4410 return isolate->heap()->undefined_value(); 4481 return isolate->heap()->undefined_value();
4411 } 4482 }
4412 4483
4413 4484
4414 static MaybeObject* Runtime_LocalKeys(RUNTIME_CALLING_CONVENTION) { 4485 static MaybeObject* Runtime_LocalKeys(RUNTIME_CALLING_CONVENTION) {
4415 RUNTIME_GET_ISOLATE; 4486 RUNTIME_GET_ISOLATE;
4416 ASSERT_EQ(args.length(), 1); 4487 ASSERT_EQ(args.length(), 1);
4417 CONVERT_CHECKED(JSObject, raw_object, args[0]); 4488 CONVERT_CHECKED(JSObject, raw_object, args[0]);
4418 HandleScope scope(isolate); 4489 HandleScope scope(isolate);
4419 Handle<JSObject> object(raw_object); 4490 Handle<JSObject> object(raw_object);
4491
4492 if (object->IsJSGlobalProxy()) {
4493 // Do access checks before going to the global object.
4494 if (object->IsAccessCheckNeeded() &&
4495 !isolate->MayNamedAccess(*object, isolate->heap()->undefined_value(),
4496 v8::ACCESS_KEYS)) {
4497 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_KEYS);
4498 return *isolate->factory()->NewJSArray(0);
4499 }
4500
4501 Handle<Object> proto(object->GetPrototype());
4502 // If proxy is detached we simply return an empty array.
4503 if (proto->IsNull()) return *isolate->factory()->NewJSArray(0);
4504 object = Handle<JSObject>::cast(proto);
4505 }
4506
4420 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, 4507 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object,
4421 LOCAL_ONLY); 4508 LOCAL_ONLY);
4422 // Some fast paths through GetKeysInFixedArrayFor reuse a cached 4509 // Some fast paths through GetKeysInFixedArrayFor reuse a cached
4423 // property array and since the result is mutable we have to create 4510 // property array and since the result is mutable we have to create
4424 // a fresh clone on each invocation. 4511 // a fresh clone on each invocation.
4425 int length = contents->length(); 4512 int length = contents->length();
4426 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); 4513 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
4427 for (int i = 0; i < length; i++) { 4514 for (int i = 0; i < length; i++) {
4428 Object* entry = contents->get(i); 4515 Object* entry = contents->get(i);
4429 if (entry->IsString()) { 4516 if (entry->IsString()) {
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after
6051 SeqTwoByteString* answer = SeqTwoByteString::cast(object); 6138 SeqTwoByteString* answer = SeqTwoByteString::cast(object);
6052 StringBuilderConcatHelper(special, 6139 StringBuilderConcatHelper(special,
6053 answer->GetChars(), 6140 answer->GetChars(),
6054 fixed_array, 6141 fixed_array,
6055 array_length); 6142 array_length);
6056 return answer; 6143 return answer;
6057 } 6144 }
6058 } 6145 }
6059 6146
6060 6147
6148 static MaybeObject* Runtime_StringBuilderJoin(RUNTIME_CALLING_CONVENTION) {
6149 RUNTIME_GET_ISOLATE;
6150 NoHandleAllocation ha;
6151 ASSERT(args.length() == 3);
6152 CONVERT_CHECKED(JSArray, array, args[0]);
6153 if (!args[1]->IsSmi()) {
6154 isolate->context()->mark_out_of_memory();
6155 return Failure::OutOfMemoryException();
6156 }
6157 int array_length = Smi::cast(args[1])->value();
6158 CONVERT_CHECKED(String, separator, args[2]);
6159
6160 if (!array->HasFastElements()) {
6161 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6162 }
6163 FixedArray* fixed_array = FixedArray::cast(array->elements());
6164 if (fixed_array->length() < array_length) {
6165 array_length = fixed_array->length();
6166 }
6167
6168 if (array_length == 0) {
6169 return isolate->heap()->empty_string();
6170 } else if (array_length == 1) {
6171 Object* first = fixed_array->get(0);
6172 if (first->IsString()) return first;
6173 }
6174
6175 int separator_length = separator->length();
6176 int max_nof_separators =
6177 (String::kMaxLength + separator_length - 1) / separator_length;
6178 if (max_nof_separators < (array_length - 1)) {
6179 isolate->context()->mark_out_of_memory();
6180 return Failure::OutOfMemoryException();
6181 }
6182 int length = (array_length - 1) * separator_length;
6183 for (int i = 0; i < array_length; i++) {
6184 Object* element_obj = fixed_array->get(i);
6185 if (!element_obj->IsString()) {
6186 // TODO(1161): handle this case.
6187 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6188 }
6189 String* element = String::cast(element_obj);
6190 int increment = element->length();
6191 if (increment > String::kMaxLength - length) {
6192 isolate->context()->mark_out_of_memory();
6193 return Failure::OutOfMemoryException();
6194 }
6195 length += increment;
6196 }
6197
6198 Object* object;
6199 { MaybeObject* maybe_object =
6200 isolate->heap()->AllocateRawTwoByteString(length);
6201 if (!maybe_object->ToObject(&object)) return maybe_object;
6202 }
6203 SeqTwoByteString* answer = SeqTwoByteString::cast(object);
6204
6205 uc16* sink = answer->GetChars();
6206 #ifdef DEBUG
6207 uc16* end = sink + length;
6208 #endif
6209
6210 String* first = String::cast(fixed_array->get(0));
6211 int first_length = first->length();
6212 String::WriteToFlat(first, sink, 0, first_length);
6213 sink += first_length;
6214
6215 for (int i = 1; i < array_length; i++) {
6216 ASSERT(sink + separator_length <= end);
6217 String::WriteToFlat(separator, sink, 0, separator_length);
6218 sink += separator_length;
6219
6220 String* element = String::cast(fixed_array->get(i));
6221 int element_length = element->length();
6222 ASSERT(sink + element_length <= end);
6223 String::WriteToFlat(element, sink, 0, element_length);
6224 sink += element_length;
6225 }
6226 ASSERT(sink == end);
6227
6228 ASSERT(!answer->HasOnlyAsciiChars()); // Use %_FastAsciiArrayJoin instead.
6229 return answer;
6230 }
6231
6232
6061 static MaybeObject* Runtime_NumberOr(RUNTIME_CALLING_CONVENTION) { 6233 static MaybeObject* Runtime_NumberOr(RUNTIME_CALLING_CONVENTION) {
6062 RUNTIME_GET_ISOLATE; 6234 RUNTIME_GET_ISOLATE;
6063 NoHandleAllocation ha; 6235 NoHandleAllocation ha;
6064 ASSERT(args.length() == 2); 6236 ASSERT(args.length() == 2);
6065 6237
6066 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); 6238 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
6067 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); 6239 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
6068 return isolate->heap()->NumberFromInt32(x | y); 6240 return isolate->heap()->NumberFromInt32(x | y);
6069 } 6241 }
6070 6242
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
7125 if (!function->has_initial_map() && 7297 if (!function->has_initial_map() &&
7126 shared->IsInobjectSlackTrackingInProgress()) { 7298 shared->IsInobjectSlackTrackingInProgress()) {
7127 // The tracking is already in progress for another function. We can only 7299 // The tracking is already in progress for another function. We can only
7128 // track one initial_map at a time, so we force the completion before the 7300 // track one initial_map at a time, so we force the completion before the
7129 // function is called as a constructor for the first time. 7301 // function is called as a constructor for the first time.
7130 shared->CompleteInobjectSlackTracking(); 7302 shared->CompleteInobjectSlackTracking();
7131 } 7303 }
7132 7304
7133 bool first_allocation = !shared->live_objects_may_exist(); 7305 bool first_allocation = !shared->live_objects_may_exist();
7134 Handle<JSObject> result = isolate->factory()->NewJSObject(function); 7306 Handle<JSObject> result = isolate->factory()->NewJSObject(function);
7307 RETURN_IF_EMPTY_HANDLE(isolate, result);
7135 // Delay setting the stub if inobject slack tracking is in progress. 7308 // Delay setting the stub if inobject slack tracking is in progress.
7136 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) { 7309 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) {
7137 TrySettingInlineConstructStub(isolate, function); 7310 TrySettingInlineConstructStub(isolate, function);
7138 } 7311 }
7139 7312
7140 isolate->counters()->constructed_objects()->Increment(); 7313 isolate->counters()->constructed_objects()->Increment();
7141 isolate->counters()->constructed_objects_runtime()->Increment(); 7314 isolate->counters()->constructed_objects_runtime()->Increment();
7142 7315
7143 return *result; 7316 return *result;
7144 } 7317 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
7201 if (FLAG_trace_opt) { 7374 if (FLAG_trace_opt) {
7202 PrintF("[failed to optimize "); 7375 PrintF("[failed to optimize ");
7203 function->PrintName(); 7376 function->PrintName();
7204 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n", 7377 PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
7205 function->shared()->code()->optimizable() ? "T" : "F", 7378 function->shared()->code()->optimizable() ? "T" : "F",
7206 isolate->debug()->has_break_points() ? "T" : "F"); 7379 isolate->debug()->has_break_points() ? "T" : "F");
7207 } 7380 }
7208 function->ReplaceCode(function->shared()->code()); 7381 function->ReplaceCode(function->shared()->code());
7209 return function->code(); 7382 return function->code();
7210 } 7383 }
7211 if (CompileOptimized(function, AstNode::kNoNumber)) { 7384 if (CompileOptimized(function, AstNode::kNoNumber, CLEAR_EXCEPTION)) {
7212 return function->code(); 7385 return function->code();
7213 } 7386 }
7214 if (FLAG_trace_opt) { 7387 if (FLAG_trace_opt) {
7215 PrintF("[failed to optimize "); 7388 PrintF("[failed to optimize ");
7216 function->PrintName(); 7389 function->PrintName();
7217 PrintF(": optimized compilation failed]\n"); 7390 PrintF(": optimized compilation failed]\n");
7218 } 7391 }
7219 function->ReplaceCode(function->shared()->code()); 7392 function->ReplaceCode(function->shared()->code());
7220 return Failure::Exception(); 7393 return function->code();
7221 } 7394 }
7222 7395
7223 7396
7224 static MaybeObject* Runtime_NotifyDeoptimized(RUNTIME_CALLING_CONVENTION) { 7397 static MaybeObject* Runtime_NotifyDeoptimized(RUNTIME_CALLING_CONVENTION) {
7225 RUNTIME_GET_ISOLATE; 7398 RUNTIME_GET_ISOLATE;
7226 HandleScope scope(isolate); 7399 HandleScope scope(isolate);
7227 ASSERT(args.length() == 1); 7400 ASSERT(args.length() == 1);
7228 RUNTIME_ASSERT(args[0]->IsSmi()); 7401 RUNTIME_ASSERT(args[0]->IsSmi());
7229 Deoptimizer::BailoutType type = 7402 Deoptimizer::BailoutType type =
7230 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value()); 7403 static_cast<Deoptimizer::BailoutType>(Smi::cast(args[0])->value());
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
7375 ASSERT(ast_id != AstNode::kNoNumber); 7548 ASSERT(ast_id != AstNode::kNoNumber);
7376 if (FLAG_trace_osr) { 7549 if (FLAG_trace_osr) {
7377 PrintF("[replacing on-stack at AST id %d in ", ast_id); 7550 PrintF("[replacing on-stack at AST id %d in ", ast_id);
7378 function->PrintName(); 7551 function->PrintName();
7379 PrintF("]\n"); 7552 PrintF("]\n");
7380 } 7553 }
7381 7554
7382 // Try to compile the optimized code. A true return value from 7555 // Try to compile the optimized code. A true return value from
7383 // CompileOptimized means that compilation succeeded, not necessarily 7556 // CompileOptimized means that compilation succeeded, not necessarily
7384 // that optimization succeeded. 7557 // that optimization succeeded.
7385 if (CompileOptimized(function, ast_id) && function->IsOptimized()) { 7558 if (CompileOptimized(function, ast_id, CLEAR_EXCEPTION) &&
7559 function->IsOptimized()) {
7386 DeoptimizationInputData* data = DeoptimizationInputData::cast( 7560 DeoptimizationInputData* data = DeoptimizationInputData::cast(
7387 function->code()->deoptimization_data()); 7561 function->code()->deoptimization_data());
7388 if (data->OsrPcOffset()->value() >= 0) { 7562 if (data->OsrPcOffset()->value() >= 0) {
7389 if (FLAG_trace_osr) { 7563 if (FLAG_trace_osr) {
7390 PrintF("[on-stack replacement offset %d in optimized code]\n", 7564 PrintF("[on-stack replacement offset %d in optimized code]\n",
7391 data->OsrPcOffset()->value()); 7565 data->OsrPcOffset()->value());
7392 } 7566 }
7393 ASSERT(data->OsrAstId()->value() == ast_id); 7567 ASSERT(data->OsrAstId()->value() == ast_id);
7394 } else { 7568 } else {
7395 // We may never generate the desired OSR entry if we emit an 7569 // We may never generate the desired OSR entry if we emit an
(...skipping 22 matching lines...) Expand all
7418 // Allow OSR only at nesting level zero again. 7592 // Allow OSR only at nesting level zero again.
7419 unoptimized->set_allow_osr_at_loop_nesting_level(0); 7593 unoptimized->set_allow_osr_at_loop_nesting_level(0);
7420 7594
7421 // If the optimization attempt succeeded, return the AST id tagged as a 7595 // If the optimization attempt succeeded, return the AST id tagged as a
7422 // smi. This tells the builtin that we need to translate the unoptimized 7596 // smi. This tells the builtin that we need to translate the unoptimized
7423 // frame to an optimized one. 7597 // frame to an optimized one.
7424 if (succeeded) { 7598 if (succeeded) {
7425 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); 7599 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION);
7426 return Smi::FromInt(ast_id); 7600 return Smi::FromInt(ast_id);
7427 } else { 7601 } else {
7602 if (function->IsMarkedForLazyRecompilation()) {
7603 function->ReplaceCode(function->shared()->code());
7604 }
7428 return Smi::FromInt(-1); 7605 return Smi::FromInt(-1);
7429 } 7606 }
7430 } 7607 }
7431 7608
7432 7609
7433 static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) { 7610 static MaybeObject* Runtime_GetFunctionDelegate(RUNTIME_CALLING_CONVENTION) {
7434 RUNTIME_GET_ISOLATE; 7611 RUNTIME_GET_ISOLATE;
7435 HandleScope scope(isolate); 7612 HandleScope scope(isolate);
7436 ASSERT(args.length() == 1); 7613 ASSERT(args.length() == 1);
7437 RUNTIME_ASSERT(!args[0]->IsJSFunction()); 7614 RUNTIME_ASSERT(!args[0]->IsJSFunction());
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
7686 static ObjectPair Runtime_LoadContextSlotNoReferenceError( 7863 static ObjectPair Runtime_LoadContextSlotNoReferenceError(
7687 RUNTIME_CALLING_CONVENTION) { 7864 RUNTIME_CALLING_CONVENTION) {
7688 RUNTIME_GET_ISOLATE; 7865 RUNTIME_GET_ISOLATE;
7689 return LoadContextSlotHelper(args, isolate, false); 7866 return LoadContextSlotHelper(args, isolate, false);
7690 } 7867 }
7691 7868
7692 7869
7693 static MaybeObject* Runtime_StoreContextSlot(RUNTIME_CALLING_CONVENTION) { 7870 static MaybeObject* Runtime_StoreContextSlot(RUNTIME_CALLING_CONVENTION) {
7694 RUNTIME_GET_ISOLATE; 7871 RUNTIME_GET_ISOLATE;
7695 HandleScope scope(isolate); 7872 HandleScope scope(isolate);
7696 ASSERT(args.length() == 3); 7873 ASSERT(args.length() == 4);
7697 7874
7698 Handle<Object> value(args[0], isolate); 7875 Handle<Object> value(args[0], isolate);
7699 CONVERT_ARG_CHECKED(Context, context, 1); 7876 CONVERT_ARG_CHECKED(Context, context, 1);
7700 CONVERT_ARG_CHECKED(String, name, 2); 7877 CONVERT_ARG_CHECKED(String, name, 2);
7878 CONVERT_SMI_CHECKED(strict_unchecked, args[3]);
7879 RUNTIME_ASSERT(strict_unchecked == kStrictMode ||
7880 strict_unchecked == kNonStrictMode);
7881 StrictModeFlag strict = static_cast<StrictModeFlag>(strict_unchecked);
7882
7701 7883
7702 int index; 7884 int index;
7703 PropertyAttributes attributes; 7885 PropertyAttributes attributes;
7704 ContextLookupFlags flags = FOLLOW_CHAINS; 7886 ContextLookupFlags flags = FOLLOW_CHAINS;
7705 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes); 7887 Handle<Object> holder = context->Lookup(name, flags, &index, &attributes);
7706 7888
7707 if (index >= 0) { 7889 if (index >= 0) {
7708 if (holder->IsContext()) { 7890 if (holder->IsContext()) {
7709 // Ignore if read_only variable. 7891 // Ignore if read_only variable.
7710 if ((attributes & READ_ONLY) == 0) { 7892 if ((attributes & READ_ONLY) == 0) {
(...skipping 23 matching lines...) Expand all
7734 // The property was not found. It needs to be stored in the global context. 7916 // The property was not found. It needs to be stored in the global context.
7735 ASSERT(attributes == ABSENT); 7917 ASSERT(attributes == ABSENT);
7736 attributes = NONE; 7918 attributes = NONE;
7737 context_ext = Handle<JSObject>(isolate->context()->global()); 7919 context_ext = Handle<JSObject>(isolate->context()->global());
7738 } 7920 }
7739 7921
7740 // Set the property, but ignore if read_only variable on the context 7922 // Set the property, but ignore if read_only variable on the context
7741 // extension object itself. 7923 // extension object itself.
7742 if ((attributes & READ_ONLY) == 0 || 7924 if ((attributes & READ_ONLY) == 0 ||
7743 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) { 7925 (context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
7744 Handle<Object> result = SetProperty(context_ext, name, value, NONE); 7926 RETURN_IF_EMPTY_HANDLE(isolate,
7745 if (result.is_null()) { 7927 SetProperty(context_ext, name, value, NONE, strict));
7746 // Failure::Exception is converted to a null handle in the 7928 } else if (strict == kStrictMode && (attributes & READ_ONLY) != 0) {
7747 // handle-based methods such as SetProperty. We therefore need 7929 // Setting read only property in strict mode.
7748 // to convert null handles back to exceptions. 7930 Handle<Object> error =
7749 ASSERT(isolate->has_pending_exception()); 7931 isolate->factory()->NewTypeError(
7750 return Failure::Exception(); 7932 "strict_cannot_assign", HandleVector(&name, 1));
7751 } 7933 return isolate->Throw(*error);
7752 } 7934 }
7753 return *value; 7935 return *value;
7754 } 7936 }
7755 7937
7756 7938
7757 static MaybeObject* Runtime_Throw(RUNTIME_CALLING_CONVENTION) { 7939 static MaybeObject* Runtime_Throw(RUNTIME_CALLING_CONVENTION) {
7758 RUNTIME_GET_ISOLATE; 7940 RUNTIME_GET_ISOLATE;
7759 HandleScope scope(isolate); 7941 HandleScope scope(isolate);
7760 ASSERT(args.length() == 1); 7942 ASSERT(args.length() == 1);
7761 7943
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
8088 isolate->factory()->NewFunctionFromSharedFunctionInfo( 8270 isolate->factory()->NewFunctionFromSharedFunctionInfo(
8089 shared, Handle<Context>(isolate->context()), NOT_TENURED); 8271 shared, Handle<Context>(isolate->context()), NOT_TENURED);
8090 return MakePair(*compiled, *receiver); 8272 return MakePair(*compiled, *receiver);
8091 } 8273 }
8092 8274
8093 8275
8094 static ObjectPair Runtime_ResolvePossiblyDirectEval( 8276 static ObjectPair Runtime_ResolvePossiblyDirectEval(
8095 RUNTIME_CALLING_CONVENTION) { 8277 RUNTIME_CALLING_CONVENTION) {
8096 RUNTIME_GET_ISOLATE; 8278 RUNTIME_GET_ISOLATE;
8097 ASSERT(args.length() == 4); 8279 ASSERT(args.length() == 4);
8098 if (!args[0]->IsJSFunction()) {
8099 return MakePair(isolate->ThrowIllegalOperation(), NULL);
8100 }
8101 8280
8102 HandleScope scope(isolate); 8281 HandleScope scope(isolate);
8103 Handle<JSFunction> callee = args.at<JSFunction>(0); 8282 Handle<Object> callee = args.at<Object>(0);
8104 Handle<Object> receiver; // Will be overwritten. 8283 Handle<Object> receiver; // Will be overwritten.
8105 8284
8106 // Compute the calling context. 8285 // Compute the calling context.
8107 Handle<Context> context = Handle<Context>(isolate->context(), isolate); 8286 Handle<Context> context = Handle<Context>(isolate->context(), isolate);
8108 #ifdef DEBUG 8287 #ifdef DEBUG
8109 // Make sure Isolate::context() agrees with the old code that traversed 8288 // Make sure Isolate::context() agrees with the old code that traversed
8110 // the stack frames to compute the context. 8289 // the stack frames to compute the context.
8111 StackFrameLocator locator; 8290 StackFrameLocator locator;
8112 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 8291 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
8113 ASSERT(Context::cast(frame->context()) == *context); 8292 ASSERT(Context::cast(frame->context()) == *context);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
8169 args.at<Object>(2), 8348 args.at<Object>(2),
8170 static_cast<StrictModeFlag>( 8349 static_cast<StrictModeFlag>(
8171 Smi::cast(args[3])->value())); 8350 Smi::cast(args[3])->value()));
8172 } 8351 }
8173 8352
8174 8353
8175 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup( 8354 static ObjectPair Runtime_ResolvePossiblyDirectEvalNoLookup(
8176 RUNTIME_CALLING_CONVENTION) { 8355 RUNTIME_CALLING_CONVENTION) {
8177 RUNTIME_GET_ISOLATE; 8356 RUNTIME_GET_ISOLATE;
8178 ASSERT(args.length() == 4); 8357 ASSERT(args.length() == 4);
8179 if (!args[0]->IsJSFunction()) {
8180 return MakePair(isolate->ThrowIllegalOperation(), NULL);
8181 }
8182 8358
8183 HandleScope scope(isolate); 8359 HandleScope scope(isolate);
8184 Handle<JSFunction> callee = args.at<JSFunction>(0); 8360 Handle<Object> callee = args.at<Object>(0);
8185 8361
8186 // 'eval' is bound in the global context, but it may have been overwritten. 8362 // 'eval' is bound in the global context, but it may have been overwritten.
8187 // Compare it to the builtin 'GlobalEval' function to make sure. 8363 // Compare it to the builtin 'GlobalEval' function to make sure.
8188 if (*callee != isolate->global_context()->global_eval_fun() || 8364 if (*callee != isolate->global_context()->global_eval_fun() ||
8189 !args[1]->IsString()) { 8365 !args[1]->IsString()) {
8190 return MakePair(*callee, 8366 return MakePair(*callee,
8191 isolate->context()->global()->global_receiver()); 8367 isolate->context()->global()->global_receiver());
8192 } 8368 }
8193 8369
8194 ASSERT(args[3]->IsSmi()); 8370 ASSERT(args[3]->IsSmi());
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
8270 * or a dictionary for sparse array. Since Dictionary is a subtype 8446 * or a dictionary for sparse array. Since Dictionary is a subtype
8271 * of FixedArray, the class can be used by both fast and slow cases. 8447 * of FixedArray, the class can be used by both fast and slow cases.
8272 * The second parameter of the constructor, fast_elements, specifies 8448 * The second parameter of the constructor, fast_elements, specifies
8273 * whether the storage is a FixedArray or Dictionary. 8449 * whether the storage is a FixedArray or Dictionary.
8274 * 8450 *
8275 * An index limit is used to deal with the situation that a result array 8451 * An index limit is used to deal with the situation that a result array
8276 * length overflows 32-bit non-negative integer. 8452 * length overflows 32-bit non-negative integer.
8277 */ 8453 */
8278 class ArrayConcatVisitor { 8454 class ArrayConcatVisitor {
8279 public: 8455 public:
8280 ArrayConcatVisitor(Handle<FixedArray> storage, 8456 ArrayConcatVisitor(Isolate* isolate,
8281 uint32_t index_limit, 8457 Handle<FixedArray> storage,
8282 bool fast_elements) : 8458 bool fast_elements) :
8283 storage_(storage), index_limit_(index_limit), 8459 isolate_(isolate),
8284 index_offset_(0), fast_elements_(fast_elements) { } 8460 storage_(Handle<FixedArray>::cast(
8461 isolate->global_handles()->Create(*storage))),
8462 index_offset_(0u),
8463 fast_elements_(fast_elements) { }
8464
8465 ~ArrayConcatVisitor() {
8466 clear_storage();
8467 }
8285 8468
8286 void visit(uint32_t i, Handle<Object> elm) { 8469 void visit(uint32_t i, Handle<Object> elm) {
8287 if (i >= index_limit_ - index_offset_) return; 8470 if (i >= JSObject::kMaxElementCount - index_offset_) return;
8288 uint32_t index = index_offset_ + i; 8471 uint32_t index = index_offset_ + i;
8289 8472
8290 if (fast_elements_) { 8473 if (fast_elements_) {
8291 ASSERT(index < static_cast<uint32_t>(storage_->length())); 8474 if (index < static_cast<uint32_t>(storage_->length())) {
8292 storage_->set(index, *elm); 8475 storage_->set(index, *elm);
8293 8476 return;
8294 } else { 8477 }
8295 Handle<NumberDictionary> dict = Handle<NumberDictionary>::cast(storage_); 8478 // Our initial estimate of length was foiled, possibly by
8296 Handle<NumberDictionary> result = 8479 // getters on the arrays increasing the length of later arrays
8297 storage_->GetIsolate()->factory()->DictionaryAtNumberPut(dict, 8480 // during iteration.
8298 index, 8481 // This shouldn't happen in anything but pathological cases.
8299 elm); 8482 SetDictionaryMode(index);
8300 if (!result.is_identical_to(dict)) 8483 // Fall-through to dictionary mode.
8301 storage_ = result; 8484 }
8302 } 8485 ASSERT(!fast_elements_);
8303 } 8486 Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_));
8487 Handle<NumberDictionary> result =
8488 isolate_->factory()->DictionaryAtNumberPut(dict, index, elm);
8489 if (!result.is_identical_to(dict)) {
8490 // Dictionary needed to grow.
8491 clear_storage();
8492 set_storage(*result);
8493 }
8494 }
8304 8495
8305 void increase_index_offset(uint32_t delta) { 8496 void increase_index_offset(uint32_t delta) {
8306 if (index_limit_ - index_offset_ < delta) { 8497 if (JSObject::kMaxElementCount - index_offset_ < delta) {
8307 index_offset_ = index_limit_; 8498 index_offset_ = JSObject::kMaxElementCount;
8308 } else { 8499 } else {
8309 index_offset_ += delta; 8500 index_offset_ += delta;
8310 } 8501 }
8311 } 8502 }
8312 8503
8313 Handle<FixedArray> storage() { return storage_; } 8504 Handle<JSArray> ToArray() {
8505 Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
8506 Handle<Object> length =
8507 isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
8508 Handle<Map> map;
8509 if (fast_elements_) {
8510 map = isolate_->factory()->GetFastElementsMap(Handle<Map>(array->map()));
8511 } else {
8512 map = isolate_->factory()->GetSlowElementsMap(Handle<Map>(array->map()));
8513 }
8514 array->set_map(*map);
8515 array->set_length(*length);
8516 array->set_elements(*storage_);
8517 return array;
8518 }
8314 8519
8315 private: 8520 private:
8316 Handle<FixedArray> storage_; 8521 // Convert storage to dictionary mode.
8317 // Limit on the accepted indices. Elements with indices larger than the 8522 void SetDictionaryMode(uint32_t index) {
8318 // limit are ignored by the visitor. 8523 ASSERT(fast_elements_);
8319 uint32_t index_limit_; 8524 Handle<FixedArray> current_storage(*storage_);
8320 // Index after last seen index. Always less than or equal to index_limit_. 8525 Handle<NumberDictionary> slow_storage(
8526 isolate_->factory()->NewNumberDictionary(current_storage->length()));
8527 uint32_t current_length = static_cast<uint32_t>(current_storage->length());
8528 for (uint32_t i = 0; i < current_length; i++) {
8529 HandleScope loop_scope;
8530 Handle<Object> element(current_storage->get(i));
8531 if (!element->IsTheHole()) {
8532 Handle<NumberDictionary> new_storage =
8533 isolate_->factory()->DictionaryAtNumberPut(slow_storage, i, element);
8534 if (!new_storage.is_identical_to(slow_storage)) {
8535 slow_storage = loop_scope.CloseAndEscape(new_storage);
8536 }
8537 }
8538 }
8539 clear_storage();
8540 set_storage(*slow_storage);
8541 fast_elements_ = false;
8542 }
8543
8544 inline void clear_storage() {
8545 isolate_->global_handles()->Destroy(
8546 Handle<Object>::cast(storage_).location());
8547 }
8548
8549 inline void set_storage(FixedArray* storage) {
8550 storage_ = Handle<FixedArray>::cast(
8551 isolate_->global_handles()->Create(storage));
8552 }
8553
8554 Isolate* isolate_;
8555 Handle<FixedArray> storage_; // Always a global handle.
8556 // Index after last seen index. Always less than or equal to
8557 // JSObject::kMaxElementCount.
8321 uint32_t index_offset_; 8558 uint32_t index_offset_;
8322 const bool fast_elements_; 8559 bool fast_elements_;
8323 }; 8560 };
8324 8561
8325 8562
8563 static uint32_t EstimateElementCount(Handle<JSArray> array) {
8564 uint32_t length = static_cast<uint32_t>(array->length()->Number());
8565 int element_count = 0;
8566 switch (array->GetElementsKind()) {
8567 case JSObject::FAST_ELEMENTS: {
8568 // Fast elements can't have lengths that are not representable by
8569 // a 32-bit signed integer.
8570 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
8571 int fast_length = static_cast<int>(length);
8572 Handle<FixedArray> elements(FixedArray::cast(array->elements()));
8573 for (int i = 0; i < fast_length; i++) {
8574 if (!elements->get(i)->IsTheHole()) element_count++;
8575 }
8576 break;
8577 }
8578 case JSObject::DICTIONARY_ELEMENTS: {
8579 Handle<NumberDictionary> dictionary(
8580 NumberDictionary::cast(array->elements()));
8581 int capacity = dictionary->Capacity();
8582 for (int i = 0; i < capacity; i++) {
8583 Handle<Object> key(dictionary->KeyAt(i));
8584 if (dictionary->IsKey(*key)) {
8585 element_count++;
8586 }
8587 }
8588 break;
8589 }
8590 default:
8591 // External arrays are always dense.
8592 return length;
8593 }
8594 // As an estimate, we assume that the prototype doesn't contain any
8595 // inherited elements.
8596 return element_count;
8597 }
8598
8599
8600
8326 template<class ExternalArrayClass, class ElementType> 8601 template<class ExternalArrayClass, class ElementType>
8327 static uint32_t IterateExternalArrayElements(Isolate* isolate, 8602 static void IterateExternalArrayElements(Isolate* isolate,
8328 Handle<JSObject> receiver, 8603 Handle<JSObject> receiver,
8329 bool elements_are_ints, 8604 bool elements_are_ints,
8330 bool elements_are_guaranteed_smis, 8605 bool elements_are_guaranteed_smis,
8331 uint32_t range, 8606 ArrayConcatVisitor* visitor) {
8332 ArrayConcatVisitor* visitor) {
8333 Handle<ExternalArrayClass> array( 8607 Handle<ExternalArrayClass> array(
8334 ExternalArrayClass::cast(receiver->elements())); 8608 ExternalArrayClass::cast(receiver->elements()));
8335 uint32_t len = Min(static_cast<uint32_t>(array->length()), range); 8609 uint32_t len = static_cast<uint32_t>(array->length());
8336 8610
8337 if (visitor != NULL) { 8611 ASSERT(visitor != NULL);
8338 if (elements_are_ints) { 8612 if (elements_are_ints) {
8339 if (elements_are_guaranteed_smis) { 8613 if (elements_are_guaranteed_smis) {
8340 for (uint32_t j = 0; j < len; j++) { 8614 for (uint32_t j = 0; j < len; j++) {
8341 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j)))); 8615 HandleScope loop_scope;
8342 visitor->visit(j, e); 8616 Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get(j))));
8343 } 8617 visitor->visit(j, e);
8344 } else {
8345 for (uint32_t j = 0; j < len; j++) {
8346 int64_t val = static_cast<int64_t>(array->get(j));
8347 if (Smi::IsValid(static_cast<intptr_t>(val))) {
8348 Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
8349 visitor->visit(j, e);
8350 } else {
8351 Handle<Object> e =
8352 isolate->factory()->NewNumber(static_cast<ElementType>(val));
8353 visitor->visit(j, e);
8354 }
8355 }
8356 } 8618 }
8357 } else { 8619 } else {
8358 for (uint32_t j = 0; j < len; j++) { 8620 for (uint32_t j = 0; j < len; j++) {
8359 Handle<Object> e = isolate->factory()->NewNumber(array->get(j)); 8621 HandleScope loop_scope;
8360 visitor->visit(j, e); 8622 int64_t val = static_cast<int64_t>(array->get(j));
8361 } 8623 if (Smi::IsValid(static_cast<intptr_t>(val))) {
8362 } 8624 Handle<Smi> e(Smi::FromInt(static_cast<int>(val)));
8363 } 8625 visitor->visit(j, e);
8364 8626 } else {
8365 return len; 8627 Handle<Object> e =
8366 } 8628 isolate->factory()->NewNumber(static_cast<ElementType>(val));
8367 8629 visitor->visit(j, e);
8368 /** 8630 }
8369 * A helper function that visits elements of a JSObject. Only elements 8631 }
8370 * whose index between 0 and range (exclusive) are visited. 8632 }
8371 * 8633 } else {
8372 * If the third parameter, visitor, is not NULL, the visitor is called 8634 for (uint32_t j = 0; j < len; j++) {
8373 * with parameters, 'visitor_index_offset + element index' and the element. 8635 HandleScope loop_scope(isolate);
8374 * 8636 Handle<Object> e = isolate->factory()->NewNumber(array->get(j));
8375 * It returns the number of visisted elements. 8637 visitor->visit(j, e);
8376 */ 8638 }
8377 static uint32_t IterateElements(Isolate* isolate, 8639 }
8378 Handle<JSObject> receiver, 8640 }
8379 uint32_t range, 8641
8380 ArrayConcatVisitor* visitor) { 8642
8381 uint32_t num_of_elements = 0; 8643 // Used for sorting indices in a List<uint32_t>.
8382 8644 static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
8383 switch (receiver->GetElementsKind()) { 8645 uint32_t a = *ap;
8646 uint32_t b = *bp;
8647 return (a == b) ? 0 : (a < b) ? -1 : 1;
8648 }
8649
8650
8651 static void CollectElementIndices(Handle<JSObject> object,
8652 uint32_t range,
8653 List<uint32_t>* indices) {
8654 JSObject::ElementsKind kind = object->GetElementsKind();
8655 switch (kind) {
8384 case JSObject::FAST_ELEMENTS: { 8656 case JSObject::FAST_ELEMENTS: {
8385 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 8657 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
8386 uint32_t len = elements->length(); 8658 uint32_t length = static_cast<uint32_t>(elements->length());
8387 if (range < len) { 8659 if (range < length) length = range;
8388 len = range; 8660 for (uint32_t i = 0; i < length; i++) {
8389 } 8661 if (!elements->get(i)->IsTheHole()) {
8390 8662 indices->Add(i);
8391 for (uint32_t j = 0; j < len; j++) { 8663 }
8392 Handle<Object> e(elements->get(j), isolate); 8664 }
8393 if (!e->IsTheHole()) {
8394 num_of_elements++;
8395 if (visitor) {
8396 visitor->visit(j, e);
8397 }
8398 }
8399 }
8400 break;
8401 }
8402 case JSObject::PIXEL_ELEMENTS: {
8403 Handle<PixelArray> pixels(PixelArray::cast(receiver->elements()));
8404 uint32_t len = pixels->length();
8405 if (range < len) {
8406 len = range;
8407 }
8408
8409 for (uint32_t j = 0; j < len; j++) {
8410 num_of_elements++;
8411 if (visitor != NULL) {
8412 Handle<Smi> e(Smi::FromInt(pixels->get(j)));
8413 visitor->visit(j, e);
8414 }
8415 }
8416 break;
8417 }
8418 case JSObject::EXTERNAL_BYTE_ELEMENTS: {
8419 num_of_elements =
8420 IterateExternalArrayElements<ExternalByteArray, int8_t>(
8421 isolate, receiver, true, true, range, visitor);
8422 break;
8423 }
8424 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
8425 num_of_elements =
8426 IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
8427 isolate, receiver, true, true, range, visitor);
8428 break;
8429 }
8430 case JSObject::EXTERNAL_SHORT_ELEMENTS: {
8431 num_of_elements =
8432 IterateExternalArrayElements<ExternalShortArray, int16_t>(
8433 isolate, receiver, true, true, range, visitor);
8434 break;
8435 }
8436 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
8437 num_of_elements =
8438 IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
8439 isolate, receiver, true, true, range, visitor);
8440 break;
8441 }
8442 case JSObject::EXTERNAL_INT_ELEMENTS: {
8443 num_of_elements =
8444 IterateExternalArrayElements<ExternalIntArray, int32_t>(
8445 isolate, receiver, true, false, range, visitor);
8446 break;
8447 }
8448 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: {
8449 num_of_elements =
8450 IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
8451 isolate, receiver, true, false, range, visitor);
8452 break;
8453 }
8454 case JSObject::EXTERNAL_FLOAT_ELEMENTS: {
8455 num_of_elements =
8456 IterateExternalArrayElements<ExternalFloatArray, float>(
8457 isolate, receiver, false, false, range, visitor);
8458 break; 8665 break;
8459 } 8666 }
8460 case JSObject::DICTIONARY_ELEMENTS: { 8667 case JSObject::DICTIONARY_ELEMENTS: {
8461 Handle<NumberDictionary> dict(receiver->element_dictionary()); 8668 Handle<NumberDictionary> dict(NumberDictionary::cast(object->elements()));
8462 uint32_t capacity = dict->Capacity(); 8669 uint32_t capacity = dict->Capacity();
8463 for (uint32_t j = 0; j < capacity; j++) { 8670 for (uint32_t j = 0; j < capacity; j++) {
8464 Handle<Object> k(dict->KeyAt(j), isolate); 8671 HandleScope loop_scope;
8672 Handle<Object> k(dict->KeyAt(j));
8465 if (dict->IsKey(*k)) { 8673 if (dict->IsKey(*k)) {
8466 ASSERT(k->IsNumber()); 8674 ASSERT(k->IsNumber());
8467 uint32_t index = static_cast<uint32_t>(k->Number()); 8675 uint32_t index = static_cast<uint32_t>(k->Number());
8468 if (index < range) { 8676 if (index < range) {
8469 num_of_elements++; 8677 indices->Add(index);
8470 if (visitor) {
8471 visitor->visit(index, Handle<Object>(dict->ValueAt(j), isolate));
8472 }
8473 } 8678 }
8474 } 8679 }
8475 } 8680 }
8476 break; 8681 break;
8477 } 8682 }
8683 default: {
8684 int dense_elements_length;
8685 switch (kind) {
8686 case JSObject::PIXEL_ELEMENTS: {
8687 dense_elements_length =
8688 PixelArray::cast(object->elements())->length();
8689 break;
8690 }
8691 case JSObject::EXTERNAL_BYTE_ELEMENTS: {
8692 dense_elements_length =
8693 ExternalByteArray::cast(object->elements())->length();
8694 break;
8695 }
8696 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
8697 dense_elements_length =
8698 ExternalUnsignedByteArray::cast(object->elements())->length();
8699 break;
8700 }
8701 case JSObject::EXTERNAL_SHORT_ELEMENTS: {
8702 dense_elements_length =
8703 ExternalShortArray::cast(object->elements())->length();
8704 break;
8705 }
8706 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
8707 dense_elements_length =
8708 ExternalUnsignedShortArray::cast(object->elements())->length();
8709 break;
8710 }
8711 case JSObject::EXTERNAL_INT_ELEMENTS: {
8712 dense_elements_length =
8713 ExternalIntArray::cast(object->elements())->length();
8714 break;
8715 }
8716 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: {
8717 dense_elements_length =
8718 ExternalUnsignedIntArray::cast(object->elements())->length();
8719 break;
8720 }
8721 case JSObject::EXTERNAL_FLOAT_ELEMENTS: {
8722 dense_elements_length =
8723 ExternalFloatArray::cast(object->elements())->length();
8724 break;
8725 }
8726 default:
8727 UNREACHABLE();
8728 dense_elements_length = 0;
8729 break;
8730 }
8731 uint32_t length = static_cast<uint32_t>(dense_elements_length);
8732 if (range <= length) {
8733 length = range;
8734 // We will add all indices, so we might as well clear it first
8735 // and avoid duplicates.
8736 indices->Clear();
8737 }
8738 for (uint32_t i = 0; i < length; i++) {
8739 indices->Add(i);
8740 }
8741 if (length == range) return; // All indices accounted for already.
8742 break;
8743 }
8744 }
8745
8746 Handle<Object> prototype(object->GetPrototype());
8747 if (prototype->IsJSObject()) {
8748 // The prototype will usually have no inherited element indices,
8749 // but we have to check.
8750 CollectElementIndices(Handle<JSObject>::cast(prototype), range, indices);
8751 }
8752 }
8753
8754
8755 /**
8756 * A helper function that visits elements of a JSArray in numerical
8757 * order.
8758 *
8759 * The visitor argument called for each existing element in the array
8760 * with the element index and the element's value.
8761 * Afterwards it increments the base-index of the visitor by the array
8762 * length.
8763 */
8764 static void IterateElements(Isolate* isolate,
8765 Handle<JSArray> receiver,
8766 ArrayConcatVisitor* visitor) {
8767 uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
8768 switch (receiver->GetElementsKind()) {
8769 case JSObject::FAST_ELEMENTS: {
8770 // Run through the elements FixedArray and use HasElement and GetElement
8771 // to check the prototype for missing elements.
8772 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
8773 int fast_length = static_cast<int>(length);
8774 ASSERT(fast_length <= elements->length());
8775 for (int j = 0; j < fast_length; j++) {
8776 HandleScope loop_scope(isolate);
8777 Handle<Object> element_value(elements->get(j), isolate);
8778 if (!element_value->IsTheHole()) {
8779 visitor->visit(j, element_value);
8780 } else if (receiver->HasElement(j)) {
8781 // Call GetElement on receiver, not its prototype, or getters won't
8782 // have the correct receiver.
8783 element_value = GetElement(receiver, j);
8784 visitor->visit(j, element_value);
8785 }
8786 }
8787 break;
8788 }
8789 case JSObject::DICTIONARY_ELEMENTS: {
8790 Handle<NumberDictionary> dict(receiver->element_dictionary());
8791 List<uint32_t> indices(dict->Capacity() / 2);
8792 // Collect all indices in the object and the prototypes less
8793 // than length. This might introduce duplicates in the indices list.
8794 CollectElementIndices(receiver, length, &indices);
8795 indices.Sort(&compareUInt32);
8796 int j = 0;
8797 int n = indices.length();
8798 while (j < n) {
8799 HandleScope loop_scope;
8800 uint32_t index = indices[j];
8801 Handle<Object> element = GetElement(receiver, index);
8802 visitor->visit(index, element);
8803 // Skip to next different index (i.e., omit duplicates).
8804 do {
8805 j++;
8806 } while (j < n && indices[j] == index);
8807 }
8808 break;
8809 }
8810 case JSObject::PIXEL_ELEMENTS: {
8811 Handle<PixelArray> pixels(PixelArray::cast(receiver->elements()));
8812 for (uint32_t j = 0; j < length; j++) {
8813 Handle<Smi> e(Smi::FromInt(pixels->get(j)));
8814 visitor->visit(j, e);
8815 }
8816 break;
8817 }
8818 case JSObject::EXTERNAL_BYTE_ELEMENTS: {
8819 IterateExternalArrayElements<ExternalByteArray, int8_t>(
8820 isolate, receiver, true, true, visitor);
8821 break;
8822 }
8823 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: {
8824 IterateExternalArrayElements<ExternalUnsignedByteArray, uint8_t>(
8825 isolate, receiver, true, true, visitor);
8826 break;
8827 }
8828 case JSObject::EXTERNAL_SHORT_ELEMENTS: {
8829 IterateExternalArrayElements<ExternalShortArray, int16_t>(
8830 isolate, receiver, true, true, visitor);
8831 break;
8832 }
8833 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: {
8834 IterateExternalArrayElements<ExternalUnsignedShortArray, uint16_t>(
8835 isolate, receiver, true, true, visitor);
8836 break;
8837 }
8838 case JSObject::EXTERNAL_INT_ELEMENTS: {
8839 IterateExternalArrayElements<ExternalIntArray, int32_t>(
8840 isolate, receiver, true, false, visitor);
8841 break;
8842 }
8843 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: {
8844 IterateExternalArrayElements<ExternalUnsignedIntArray, uint32_t>(
8845 isolate, receiver, true, false, visitor);
8846 break;
8847 }
8848 case JSObject::EXTERNAL_FLOAT_ELEMENTS: {
8849 IterateExternalArrayElements<ExternalFloatArray, float>(
8850 isolate, receiver, false, false, visitor);
8851 break;
8852 }
8478 default: 8853 default:
8479 UNREACHABLE(); 8854 UNREACHABLE();
8480 break; 8855 break;
8481 } 8856 }
8482 8857 visitor->increase_index_offset(length);
8483 return num_of_elements;
8484 }
8485
8486
8487 /**
8488 * A helper function that visits elements of an Array object, and elements
8489 * on its prototypes.
8490 *
8491 * Elements on prototypes are visited first, and only elements whose indices
8492 * less than Array length are visited.
8493 *
8494 * If a ArrayConcatVisitor object is given, the visitor is called with
8495 * parameters, element's index + visitor_index_offset and the element.
8496 *
8497 * The returned number of elements is an upper bound on the actual number
8498 * of elements added. If the same element occurs in more than one object
8499 * in the array's prototype chain, it will be counted more than once, but
8500 * will only occur once in the result.
8501 */
8502 static uint32_t IterateArrayAndPrototypeElements(Isolate* isolate,
8503 Handle<JSArray> array,
8504 ArrayConcatVisitor* visitor) {
8505 uint32_t range = static_cast<uint32_t>(array->length()->Number());
8506 Handle<Object> obj = array;
8507
8508 static const int kEstimatedPrototypes = 3;
8509 List< Handle<JSObject> > objects(kEstimatedPrototypes);
8510
8511 // Visit prototype first. If an element on the prototype is shadowed by
8512 // the inheritor using the same index, the ArrayConcatVisitor visits
8513 // the prototype element before the shadowing element.
8514 // The visitor can simply overwrite the old value by new value using
8515 // the same index. This follows Array::concat semantics.
8516 while (!obj->IsNull()) {
8517 objects.Add(Handle<JSObject>::cast(obj));
8518 obj = Handle<Object>(obj->GetPrototype(), isolate);
8519 }
8520
8521 uint32_t nof_elements = 0;
8522 for (int i = objects.length() - 1; i >= 0; i--) {
8523 Handle<JSObject> obj = objects[i];
8524 uint32_t encountered_elements =
8525 IterateElements(isolate, Handle<JSObject>::cast(obj), range, visitor);
8526
8527 if (encountered_elements > JSObject::kMaxElementCount - nof_elements) {
8528 nof_elements = JSObject::kMaxElementCount;
8529 } else {
8530 nof_elements += encountered_elements;
8531 }
8532 }
8533
8534 return nof_elements;
8535 }
8536
8537
8538 /**
8539 * A helper function of Runtime_ArrayConcat.
8540 *
8541 * The first argument is an Array of arrays and objects. It is the
8542 * same as the arguments array of Array::concat JS function.
8543 *
8544 * If an argument is an Array object, the function visits array
8545 * elements. If an argument is not an Array object, the function
8546 * visits the object as if it is an one-element array.
8547 *
8548 * If the result array index overflows 32-bit unsigned integer, the rounded
8549 * non-negative number is used as new length. For example, if one
8550 * array length is 2^32 - 1, second array length is 1, the
8551 * concatenated array length is 0.
8552 * TODO(lrn) Change length behavior to ECMAScript 5 specification (length
8553 * is one more than the last array index to get a value assigned).
8554 */
8555 static uint32_t IterateArguments(Isolate* isolate,
8556 Handle<JSArray> arguments,
8557 ArrayConcatVisitor* visitor) {
8558 uint32_t visited_elements = 0;
8559 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number());
8560
8561 for (uint32_t i = 0; i < num_of_args; i++) {
8562 Object* element;
8563 MaybeObject* maybe_element = arguments->GetElement(i);
8564 // This if() is not expected to fail, but we have the check in the
8565 // interest of hardening the runtime calls.
8566 if (maybe_element->ToObject(&element)) {
8567 Handle<Object> obj(element, isolate);
8568 if (obj->IsJSArray()) {
8569 Handle<JSArray> array = Handle<JSArray>::cast(obj);
8570 uint32_t len = static_cast<uint32_t>(array->length()->Number());
8571 uint32_t nof_elements =
8572 IterateArrayAndPrototypeElements(isolate, array, visitor);
8573 // Total elements of array and its prototype chain can be more than
8574 // the array length, but ArrayConcat can only concatenate at most
8575 // the array length number of elements. We use the length as an estimate
8576 // for the actual number of elements added.
8577 uint32_t added_elements = (nof_elements > len) ? len : nof_elements;
8578 if (JSArray::kMaxElementCount - visited_elements < added_elements) {
8579 visited_elements = JSArray::kMaxElementCount;
8580 } else {
8581 visited_elements += added_elements;
8582 }
8583 if (visitor) visitor->increase_index_offset(len);
8584 } else {
8585 if (visitor) {
8586 visitor->visit(0, obj);
8587 visitor->increase_index_offset(1);
8588 }
8589 if (visited_elements < JSArray::kMaxElementCount) {
8590 visited_elements++;
8591 }
8592 }
8593 }
8594 }
8595 return visited_elements;
8596 } 8858 }
8597 8859
8598 8860
8599 /** 8861 /**
8600 * Array::concat implementation. 8862 * Array::concat implementation.
8601 * See ECMAScript 262, 15.4.4.4. 8863 * See ECMAScript 262, 15.4.4.4.
8602 * TODO(lrn): Fix non-compliance for very large concatenations and update to 8864 * TODO(581): Fix non-compliance for very large concatenations and update to
8603 * following the ECMAScript 5 specification. 8865 * following the ECMAScript 5 specification.
8604 */ 8866 */
8605 static MaybeObject* Runtime_ArrayConcat(RUNTIME_CALLING_CONVENTION) { 8867 static MaybeObject* Runtime_ArrayConcat(RUNTIME_CALLING_CONVENTION) {
8606 RUNTIME_GET_ISOLATE; 8868 RUNTIME_GET_ISOLATE;
8607 ASSERT(args.length() == 1); 8869 ASSERT(args.length() == 1);
8608 HandleScope handle_scope(isolate); 8870 HandleScope handle_scope(isolate);
8609 8871
8610 CONVERT_CHECKED(JSArray, arg_arrays, args[0]); 8872 CONVERT_ARG_CHECKED(JSArray, arguments, 0);
8611 Handle<JSArray> arguments(arg_arrays); 8873 int argument_count = static_cast<int>(arguments->length()->Number());
8874 RUNTIME_ASSERT(arguments->HasFastElements());
8875 Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
8612 8876
8613 // Pass 1: estimate the number of elements of the result 8877 // Pass 1: estimate the length and number of elements of the result.
8614 // (it could be more than real numbers if prototype has elements). 8878 // The actual length can be larger if any of the arguments have getters
8615 uint32_t result_length = 0; 8879 // that mutate other arguments (but will otherwise be precise).
8616 uint32_t num_of_args = static_cast<uint32_t>(arguments->length()->Number()); 8880 // The number of elements is precise if there are no inherited elements.
8617 8881
8618 { AssertNoAllocation nogc; 8882 uint32_t estimate_result_length = 0;
8619 for (uint32_t i = 0; i < num_of_args; i++) { 8883 uint32_t estimate_nof_elements = 0;
8620 Object* obj; 8884 {
8621 MaybeObject* maybe_object = arguments->GetElement(i); 8885 for (int i = 0; i < argument_count; i++) {
8622 // This if() is not expected to fail, but we have the check in the 8886 HandleScope loop_scope;
8623 // interest of hardening the runtime calls. 8887 Handle<Object> obj(elements->get(i));
8624 if (maybe_object->ToObject(&obj)) { 8888 uint32_t length_estimate;
8625 uint32_t length_estimate; 8889 uint32_t element_estimate;
8626 if (obj->IsJSArray()) { 8890 if (obj->IsJSArray()) {
8627 length_estimate = 8891 Handle<JSArray> array(Handle<JSArray>::cast(obj));
8628 static_cast<uint32_t>(JSArray::cast(obj)->length()->Number()); 8892 length_estimate =
8629 } else { 8893 static_cast<uint32_t>(array->length()->Number());
8630 length_estimate = 1; 8894 element_estimate =
8631 } 8895 EstimateElementCount(array);
8632 if (JSObject::kMaxElementCount - result_length < length_estimate) { 8896 } else {
8633 result_length = JSObject::kMaxElementCount; 8897 length_estimate = 1;
8634 break; 8898 element_estimate = 1;
8635 } 8899 }
8636 result_length += length_estimate; 8900 // Avoid overflows by capping at kMaxElementCount.
8901 if (JSObject::kMaxElementCount - estimate_result_length <
8902 length_estimate) {
8903 estimate_result_length = JSObject::kMaxElementCount;
8904 } else {
8905 estimate_result_length += length_estimate;
8906 }
8907 if (JSObject::kMaxElementCount - estimate_nof_elements <
8908 element_estimate) {
8909 estimate_nof_elements = JSObject::kMaxElementCount;
8910 } else {
8911 estimate_nof_elements += element_estimate;
8637 } 8912 }
8638 } 8913 }
8639 } 8914 }
8640 8915
8641 // Allocate an empty array, will set length and content later.
8642 Handle<JSArray> result = isolate->factory()->NewJSArray(0);
8643
8644 uint32_t estimate_nof_elements = IterateArguments(isolate, arguments, NULL);
8645 // If estimated number of elements is more than half of length, a 8916 // If estimated number of elements is more than half of length, a
8646 // fixed array (fast case) is more time and space-efficient than a 8917 // fixed array (fast case) is more time and space-efficient than a
8647 // dictionary. 8918 // dictionary.
8648 bool fast_case = (estimate_nof_elements * 2) >= result_length; 8919 bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
8649 8920
8650 Handle<FixedArray> storage; 8921 Handle<FixedArray> storage;
8651 if (fast_case) { 8922 if (fast_case) {
8652 // The backing storage array must have non-existing elements to 8923 // The backing storage array must have non-existing elements to
8653 // preserve holes across concat operations. 8924 // preserve holes across concat operations.
8654 storage = isolate->factory()->NewFixedArrayWithHoles(result_length); 8925 storage = isolate->factory()->NewFixedArrayWithHoles(
8655 Handle<Map> fast_map = 8926 estimate_result_length);
8656 isolate->factory()->GetFastElementsMap(Handle<Map>(result->map()));
8657 result->set_map(*fast_map);
8658 } else { 8927 } else {
8659 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate 8928 // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
8660 uint32_t at_least_space_for = estimate_nof_elements + 8929 uint32_t at_least_space_for = estimate_nof_elements +
8661 (estimate_nof_elements >> 2); 8930 (estimate_nof_elements >> 2);
8662 storage = Handle<FixedArray>::cast( 8931 storage = Handle<FixedArray>::cast(
8663 isolate->factory()->NewNumberDictionary(at_least_space_for)); 8932 isolate->factory()->NewNumberDictionary(at_least_space_for));
8664 Handle<Map> slow_map =
8665 isolate->factory()->GetSlowElementsMap(Handle<Map>(result->map()));
8666 result->set_map(*slow_map);
8667 } 8933 }
8668 8934
8669 Handle<Object> len = 8935 ArrayConcatVisitor visitor(isolate, storage, fast_case);
8670 isolate->factory()->NewNumber(static_cast<double>(result_length));
8671 8936
8672 ArrayConcatVisitor visitor(storage, result_length, fast_case); 8937 for (int i = 0; i < argument_count; i++) {
8938 Handle<Object> obj(elements->get(i));
8939 if (obj->IsJSArray()) {
8940 Handle<JSArray> array = Handle<JSArray>::cast(obj);
8941 IterateElements(isolate, array, &visitor);
8942 } else {
8943 visitor.visit(0, obj);
8944 visitor.increase_index_offset(1);
8945 }
8946 }
8673 8947
8674 IterateArguments(isolate, arguments, &visitor); 8948 return *visitor.ToArray();
8675
8676 result->set_length(*len);
8677 // Please note the storage might have changed in the visitor.
8678 result->set_elements(*visitor.storage());
8679
8680 return *result;
8681 } 8949 }
8682 8950
8683 8951
8684 // This will not allocate (flatten the string), but it may run 8952 // This will not allocate (flatten the string), but it may run
8685 // very slowly for very deeply nested ConsStrings. For debugging use only. 8953 // very slowly for very deeply nested ConsStrings. For debugging use only.
8686 static MaybeObject* Runtime_GlobalPrint(RUNTIME_CALLING_CONVENTION) { 8954 static MaybeObject* Runtime_GlobalPrint(RUNTIME_CALLING_CONVENTION) {
8687 RUNTIME_GET_ISOLATE; 8955 RUNTIME_GET_ISOLATE;
8688 NoHandleAllocation ha; 8956 NoHandleAllocation ha;
8689 ASSERT(args.length() == 1); 8957 ASSERT(args.length() == 1);
8690 8958
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
9297 for (int i = 0; i < info.NumberOfLocals(); i++) { 9565 for (int i = 0; i < info.NumberOfLocals(); i++) {
9298 locals->set(i * 2, *info.LocalName(i)); 9566 locals->set(i * 2, *info.LocalName(i));
9299 } 9567 }
9300 9568
9301 // Fill in the values of the locals. 9569 // Fill in the values of the locals.
9302 for (int i = 0; i < info.NumberOfLocals(); i++) { 9570 for (int i = 0; i < info.NumberOfLocals(); i++) {
9303 if (is_optimized_frame) { 9571 if (is_optimized_frame) {
9304 // If we are inspecting an optimized frame use undefined as the 9572 // If we are inspecting an optimized frame use undefined as the
9305 // value for all locals. 9573 // value for all locals.
9306 // 9574 //
9307 // TODO(3141533): We should be able to get the correct values 9575 // TODO(1140): We should be able to get the correct values
9308 // for locals in optimized frames. 9576 // for locals in optimized frames.
9309 locals->set(i * 2 + 1, isolate->heap()->undefined_value()); 9577 locals->set(i * 2 + 1, isolate->heap()->undefined_value());
9310 } else if (i < info.number_of_stack_slots()) { 9578 } else if (i < info.number_of_stack_slots()) {
9311 // Get the value from the stack. 9579 // Get the value from the stack.
9312 locals->set(i * 2 + 1, it.frame()->GetExpression(i)); 9580 locals->set(i * 2 + 1, it.frame()->GetExpression(i));
9313 } else { 9581 } else {
9314 // Traverse the context chain to the function context as all local 9582 // Traverse the context chain to the function context as all local
9315 // variables stored in the context will be on the function context. 9583 // variables stored in the context will be on the function context.
9316 Handle<String> name = info.LocalName(i); 9584 Handle<String> name = info.LocalName(i);
9317 while (!context->is_function_context()) { 9585 while (!context->is_function_context()) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
9464 isolate->factory()->ToObject(receiver, calling_frames_global_context); 9732 isolate->factory()->ToObject(receiver, calling_frames_global_context);
9465 } 9733 }
9466 details->set(kFrameDetailsReceiverIndex, *receiver); 9734 details->set(kFrameDetailsReceiverIndex, *receiver);
9467 9735
9468 ASSERT_EQ(details_size, details_index); 9736 ASSERT_EQ(details_size, details_index);
9469 return *isolate->factory()->NewJSArrayWithElements(details); 9737 return *isolate->factory()->NewJSArrayWithElements(details);
9470 } 9738 }
9471 9739
9472 9740
9473 // Copy all the context locals into an object used to materialize a scope. 9741 // Copy all the context locals into an object used to materialize a scope.
9474 static void CopyContextLocalsToScopeObject( 9742 static bool CopyContextLocalsToScopeObject(
9475 Isolate* isolate, 9743 Isolate* isolate,
9476 Handle<SerializedScopeInfo> serialized_scope_info, 9744 Handle<SerializedScopeInfo> serialized_scope_info,
9477 ScopeInfo<>& scope_info, 9745 ScopeInfo<>& scope_info,
9478 Handle<Context> context, 9746 Handle<Context> context,
9479 Handle<JSObject> scope_object) { 9747 Handle<JSObject> scope_object) {
9480 // Fill all context locals to the context extension. 9748 // Fill all context locals to the context extension.
9481 for (int i = Context::MIN_CONTEXT_SLOTS; 9749 for (int i = Context::MIN_CONTEXT_SLOTS;
9482 i < scope_info.number_of_context_slots(); 9750 i < scope_info.number_of_context_slots();
9483 i++) { 9751 i++) {
9484 int context_index = serialized_scope_info->ContextSlotIndex( 9752 int context_index = serialized_scope_info->ContextSlotIndex(
9485 *scope_info.context_slot_name(i), NULL); 9753 *scope_info.context_slot_name(i), NULL);
9486 9754
9487 // Don't include the arguments shadow (.arguments) context variable. 9755 // Don't include the arguments shadow (.arguments) context variable.
9488 if (*scope_info.context_slot_name(i) != 9756 if (*scope_info.context_slot_name(i) !=
9489 isolate->heap()->arguments_shadow_symbol()) { 9757 isolate->heap()->arguments_shadow_symbol()) {
9490 SetProperty(scope_object, 9758 RETURN_IF_EMPTY_HANDLE_VALUE(
9491 scope_info.context_slot_name(i), 9759 isolate,
9492 Handle<Object>(context->get(context_index), isolate), NONE); 9760 SetProperty(scope_object,
9761 scope_info.context_slot_name(i),
9762 Handle<Object>(context->get(context_index), isolate),
9763 NONE,
9764 kNonStrictMode),
9765 false);
9493 } 9766 }
9494 } 9767 }
9768
9769 return true;
9495 } 9770 }
9496 9771
9497 9772
9498 // Create a plain JSObject which materializes the local scope for the specified 9773 // Create a plain JSObject which materializes the local scope for the specified
9499 // frame. 9774 // frame.
9500 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate, 9775 static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
9501 JavaScriptFrame* frame) { 9776 JavaScriptFrame* frame) {
9502 Handle<JSFunction> function(JSFunction::cast(frame->function())); 9777 Handle<JSFunction> function(JSFunction::cast(frame->function()));
9503 Handle<SharedFunctionInfo> shared(function->shared()); 9778 Handle<SharedFunctionInfo> shared(function->shared());
9504 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info()); 9779 Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
9505 ScopeInfo<> scope_info(*serialized_scope_info); 9780 ScopeInfo<> scope_info(*serialized_scope_info);
9506 9781
9507 // Allocate and initialize a JSObject with all the arguments, stack locals 9782 // Allocate and initialize a JSObject with all the arguments, stack locals
9508 // heap locals and extension properties of the debugged function. 9783 // heap locals and extension properties of the debugged function.
9509 Handle<JSObject> local_scope = 9784 Handle<JSObject> local_scope =
9510 isolate->factory()->NewJSObject(isolate->object_function()); 9785 isolate->factory()->NewJSObject(isolate->object_function());
9511 9786
9512 // First fill all parameters. 9787 // First fill all parameters.
9513 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { 9788 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
9514 SetProperty(local_scope, 9789 RETURN_IF_EMPTY_HANDLE_VALUE(
9515 scope_info.parameter_name(i), 9790 isolate,
9516 Handle<Object>(frame->GetParameter(i), isolate), NONE); 9791 SetProperty(local_scope,
9792 scope_info.parameter_name(i),
9793 Handle<Object>(frame->GetParameter(i), isolate),
9794 NONE,
9795 kNonStrictMode),
9796 Handle<JSObject>());
9517 } 9797 }
9518 9798
9519 // Second fill all stack locals. 9799 // Second fill all stack locals.
9520 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) { 9800 for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
9521 SetProperty(local_scope, 9801 RETURN_IF_EMPTY_HANDLE_VALUE(
9522 scope_info.stack_slot_name(i), 9802 isolate,
9523 Handle<Object>(frame->GetExpression(i), isolate), NONE); 9803 SetProperty(local_scope,
9804 scope_info.stack_slot_name(i),
9805 Handle<Object>(frame->GetExpression(i), isolate),
9806 NONE,
9807 kNonStrictMode),
9808 Handle<JSObject>());
9524 } 9809 }
9525 9810
9526 // Third fill all context locals. 9811 // Third fill all context locals.
9527 Handle<Context> frame_context(Context::cast(frame->context())); 9812 Handle<Context> frame_context(Context::cast(frame->context()));
9528 Handle<Context> function_context(frame_context->fcontext()); 9813 Handle<Context> function_context(frame_context->fcontext());
9529 CopyContextLocalsToScopeObject(isolate, serialized_scope_info, scope_info, 9814 if (!CopyContextLocalsToScopeObject(isolate,
9530 function_context, local_scope); 9815 serialized_scope_info, scope_info,
9816 function_context, local_scope)) {
9817 return Handle<JSObject>();
9818 }
9531 9819
9532 // Finally copy any properties from the function context extension. This will 9820 // Finally copy any properties from the function context extension. This will
9533 // be variables introduced by eval. 9821 // be variables introduced by eval.
9534 if (function_context->closure() == *function) { 9822 if (function_context->closure() == *function) {
9535 if (function_context->has_extension() && 9823 if (function_context->has_extension() &&
9536 !function_context->IsGlobalContext()) { 9824 !function_context->IsGlobalContext()) {
9537 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 9825 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
9538 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); 9826 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
9539 for (int i = 0; i < keys->length(); i++) { 9827 for (int i = 0; i < keys->length(); i++) {
9540 // Names of variables introduced by eval are strings. 9828 // Names of variables introduced by eval are strings.
9541 ASSERT(keys->get(i)->IsString()); 9829 ASSERT(keys->get(i)->IsString());
9542 Handle<String> key(String::cast(keys->get(i))); 9830 Handle<String> key(String::cast(keys->get(i)));
9543 SetProperty(local_scope, key, GetProperty(ext, key), NONE); 9831 RETURN_IF_EMPTY_HANDLE_VALUE(
9832 isolate,
9833 SetProperty(local_scope,
9834 key,
9835 GetProperty(ext, key),
9836 NONE,
9837 kNonStrictMode),
9838 Handle<JSObject>());
9544 } 9839 }
9545 } 9840 }
9546 } 9841 }
9547 return local_scope; 9842 return local_scope;
9548 } 9843 }
9549 9844
9550 9845
9551 // Create a plain JSObject which materializes the closure content for the 9846 // Create a plain JSObject which materializes the closure content for the
9552 // context. 9847 // context.
9553 static Handle<JSObject> MaterializeClosure(Isolate* isolate, 9848 static Handle<JSObject> MaterializeClosure(Isolate* isolate,
(...skipping 14 matching lines...) Expand all
9568 shared->scope_info()->ContextSlotIndex( 9863 shared->scope_info()->ContextSlotIndex(
9569 isolate->heap()->arguments_shadow_symbol(), NULL); 9864 isolate->heap()->arguments_shadow_symbol(), NULL);
9570 if (arguments_shadow_index >= 0) { 9865 if (arguments_shadow_index >= 0) {
9571 // In this case all the arguments are available in the arguments shadow 9866 // In this case all the arguments are available in the arguments shadow
9572 // object. 9867 // object.
9573 Handle<JSObject> arguments_shadow( 9868 Handle<JSObject> arguments_shadow(
9574 JSObject::cast(context->get(arguments_shadow_index))); 9869 JSObject::cast(context->get(arguments_shadow_index)));
9575 for (int i = 0; i < scope_info.number_of_parameters(); ++i) { 9870 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
9576 // We don't expect exception-throwing getters on the arguments shadow. 9871 // We don't expect exception-throwing getters on the arguments shadow.
9577 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked(); 9872 Object* element = arguments_shadow->GetElement(i)->ToObjectUnchecked();
9578 SetProperty(closure_scope, 9873 RETURN_IF_EMPTY_HANDLE_VALUE(
9579 scope_info.parameter_name(i), 9874 isolate,
9580 Handle<Object>(element, isolate), 9875 SetProperty(closure_scope,
9581 NONE); 9876 scope_info.parameter_name(i),
9877 Handle<Object>(element, isolate),
9878 NONE,
9879 kNonStrictMode),
9880 Handle<JSObject>());
9582 } 9881 }
9583 } 9882 }
9584 9883
9585 // Fill all context locals to the context extension. 9884 // Fill all context locals to the context extension.
9586 CopyContextLocalsToScopeObject(isolate, serialized_scope_info, scope_info, 9885 if (!CopyContextLocalsToScopeObject(isolate,
9587 context, closure_scope); 9886 serialized_scope_info, scope_info,
9887 context, closure_scope)) {
9888 return Handle<JSObject>();
9889 }
9588 9890
9589 // Finally copy any properties from the function context extension. This will 9891 // Finally copy any properties from the function context extension. This will
9590 // be variables introduced by eval. 9892 // be variables introduced by eval.
9591 if (context->has_extension()) { 9893 if (context->has_extension()) {
9592 Handle<JSObject> ext(JSObject::cast(context->extension())); 9894 Handle<JSObject> ext(JSObject::cast(context->extension()));
9593 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); 9895 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
9594 for (int i = 0; i < keys->length(); i++) { 9896 for (int i = 0; i < keys->length(); i++) {
9595 // Names of variables introduced by eval are strings. 9897 // Names of variables introduced by eval are strings.
9596 ASSERT(keys->get(i)->IsString()); 9898 ASSERT(keys->get(i)->IsString());
9597 Handle<String> key(String::cast(keys->get(i))); 9899 Handle<String> key(String::cast(keys->get(i)));
9598 SetProperty(closure_scope, key, GetProperty(ext, key), NONE); 9900 RETURN_IF_EMPTY_HANDLE_VALUE(
9901 isolate,
9902 SetProperty(closure_scope,
9903 key,
9904 GetProperty(ext, key),
9905 NONE,
9906 kNonStrictMode),
9907 Handle<JSObject>());
9599 } 9908 }
9600 } 9909 }
9601 9910
9602 return closure_scope; 9911 return closure_scope;
9603 } 9912 }
9604 9913
9605 9914
9606 // Iterate over the actual scopes visible from a stack frame. All scopes are 9915 // Iterate over the actual scopes visible from a stack frame. All scopes are
9607 // backed by an actual context except the local scope, which is inserted 9916 // backed by an actual context except the local scope, which is inserted
9608 // "artifically" in the context chain. 9917 // "artifically" in the context chain.
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
9879 return isolate->heap()->undefined_value(); 10188 return isolate->heap()->undefined_value();
9880 } 10189 }
9881 10190
9882 // Calculate the size of the result. 10191 // Calculate the size of the result.
9883 int details_size = kScopeDetailsSize; 10192 int details_size = kScopeDetailsSize;
9884 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size); 10193 Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
9885 10194
9886 // Fill in scope details. 10195 // Fill in scope details.
9887 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type())); 10196 details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
9888 Handle<JSObject> scope_object = it.ScopeObject(); 10197 Handle<JSObject> scope_object = it.ScopeObject();
10198 RETURN_IF_EMPTY_HANDLE(isolate, scope_object);
9889 details->set(kScopeDetailsObjectIndex, *scope_object); 10199 details->set(kScopeDetailsObjectIndex, *scope_object);
9890 10200
9891 return *isolate->factory()->NewJSArrayWithElements(details); 10201 return *isolate->factory()->NewJSArrayWithElements(details);
9892 } 10202 }
9893 10203
9894 10204
9895 static MaybeObject* Runtime_DebugPrintScopes(RUNTIME_CALLING_CONVENTION) { 10205 static MaybeObject* Runtime_DebugPrintScopes(RUNTIME_CALLING_CONVENTION) {
9896 RUNTIME_GET_ISOLATE; 10206 RUNTIME_GET_ISOLATE;
9897 HandleScope scope(isolate); 10207 HandleScope scope(isolate);
9898 ASSERT(args.length() == 0); 10208 ASSERT(args.length() == 0);
(...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
10390 isolate->factory()->undefined_value()); 10700 isolate->factory()->undefined_value());
10391 go_between->set_context(function->context()); 10701 go_between->set_context(function->context());
10392 #ifdef DEBUG 10702 #ifdef DEBUG
10393 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info()); 10703 ScopeInfo<> go_between_sinfo(go_between->shared()->scope_info());
10394 ASSERT(go_between_sinfo.number_of_parameters() == 0); 10704 ASSERT(go_between_sinfo.number_of_parameters() == 0);
10395 ASSERT(go_between_sinfo.number_of_context_slots() == 0); 10705 ASSERT(go_between_sinfo.number_of_context_slots() == 0);
10396 #endif 10706 #endif
10397 10707
10398 // Materialize the content of the local scope into a JSObject. 10708 // Materialize the content of the local scope into a JSObject.
10399 Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame); 10709 Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame);
10710 RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
10400 10711
10401 // Allocate a new context for the debug evaluation and set the extension 10712 // Allocate a new context for the debug evaluation and set the extension
10402 // object build. 10713 // object build.
10403 Handle<Context> context = 10714 Handle<Context> context =
10404 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, 10715 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
10405 go_between); 10716 go_between);
10406 context->set_extension(*local_scope); 10717 context->set_extension(*local_scope);
10407 // Copy any with contexts present and chain them in front of this context. 10718 // Copy any with contexts present and chain them in front of this context.
10408 Handle<Context> frame_context(Context::cast(frame->context())); 10719 Handle<Context> frame_context(Context::cast(frame->context()));
10409 Handle<Context> function_context(frame_context->fcontext()); 10720 Handle<Context> function_context(frame_context->fcontext());
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
11136 11447
11137 // Gets the current heap usage. 11448 // Gets the current heap usage.
11138 static MaybeObject* Runtime_GetHeapUsage(RUNTIME_CALLING_CONVENTION) { 11449 static MaybeObject* Runtime_GetHeapUsage(RUNTIME_CALLING_CONVENTION) {
11139 RUNTIME_GET_ISOLATE; 11450 RUNTIME_GET_ISOLATE;
11140 int usage = static_cast<int>(isolate->heap()->SizeOfObjects()); 11451 int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
11141 if (!Smi::IsValid(usage)) { 11452 if (!Smi::IsValid(usage)) {
11142 return *isolate->factory()->NewNumberFromInt(usage); 11453 return *isolate->factory()->NewNumberFromInt(usage);
11143 } 11454 }
11144 return Smi::FromInt(usage); 11455 return Smi::FromInt(usage);
11145 } 11456 }
11457
11458
11459 // Captures a live object list from the present heap.
11460 static MaybeObject* Runtime_HasLOLEnabled(RUNTIME_CALLING_CONVENTION) {
11461 RUNTIME_GET_ISOLATE;
11462 #ifdef LIVE_OBJECT_LIST
11463 return isolate->heap()->true_value();
11464 #else
11465 return isolate->heap()->false_value();
11466 #endif
11467 }
11468
11469
11470 // Captures a live object list from the present heap.
11471 static MaybeObject* Runtime_CaptureLOL(RUNTIME_CALLING_CONVENTION) {
11472 RUNTIME_GET_ISOLATE;
11473 #ifdef LIVE_OBJECT_LIST
11474 return LiveObjectList::Capture();
11475 #else
11476 return isolate->heap()->undefined_value();
11477 #endif
11478 }
11479
11480
11481 // Deletes the specified live object list.
11482 static MaybeObject* Runtime_DeleteLOL(RUNTIME_CALLING_CONVENTION) {
11483 RUNTIME_GET_ISOLATE;
11484 #ifdef LIVE_OBJECT_LIST
11485 CONVERT_SMI_CHECKED(id, args[0]);
11486 bool success = LiveObjectList::Delete(id);
11487 return success ? isolate->heap()->true_value() :
11488 isolate->heap()->false_value();
11489 #else
11490 return isolate->heap()->undefined_value();
11491 #endif
11492 }
11493
11494
11495 // Generates the response to a debugger request for a dump of the objects
11496 // contained in the difference between the captured live object lists
11497 // specified by id1 and id2.
11498 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
11499 // dumped.
11500 static MaybeObject* Runtime_DumpLOL(RUNTIME_CALLING_CONVENTION) {
11501 RUNTIME_GET_ISOLATE;
11502 #ifdef LIVE_OBJECT_LIST
11503 HandleScope scope;
11504 CONVERT_SMI_CHECKED(id1, args[0]);
11505 CONVERT_SMI_CHECKED(id2, args[1]);
11506 CONVERT_SMI_CHECKED(start, args[2]);
11507 CONVERT_SMI_CHECKED(count, args[3]);
11508 CONVERT_ARG_CHECKED(JSObject, filter_obj, 4);
11509 EnterDebugger enter_debugger;
11510 return LiveObjectList::Dump(id1, id2, start, count, filter_obj);
11511 #else
11512 return isolate->heap()->undefined_value();
11513 #endif
11514 }
11515
11516
11517 // Gets the specified object as requested by the debugger.
11518 // This is only used for obj ids shown in live object lists.
11519 static MaybeObject* Runtime_GetLOLObj(RUNTIME_CALLING_CONVENTION) {
11520 RUNTIME_GET_ISOLATE;
11521 #ifdef LIVE_OBJECT_LIST
11522 CONVERT_SMI_CHECKED(obj_id, args[0]);
11523 Object* result = LiveObjectList::GetObj(obj_id);
11524 return result;
11525 #else
11526 return isolate->heap()->undefined_value();
11527 #endif
11528 }
11529
11530
11531 // Gets the obj id for the specified address if valid.
11532 // This is only used for obj ids shown in live object lists.
11533 static MaybeObject* Runtime_GetLOLObjId(RUNTIME_CALLING_CONVENTION) {
11534 RUNTIME_GET_ISOLATE;
11535 #ifdef LIVE_OBJECT_LIST
11536 HandleScope scope;
11537 CONVERT_ARG_CHECKED(String, address, 0);
11538 Object* result = LiveObjectList::GetObjId(address);
11539 return result;
11540 #else
11541 return isolate->heap()->undefined_value();
11542 #endif
11543 }
11544
11545
11546 // Gets the retainers that references the specified object alive.
11547 static MaybeObject* Runtime_GetLOLObjRetainers(RUNTIME_CALLING_CONVENTION) {
11548 RUNTIME_GET_ISOLATE;
11549 #ifdef LIVE_OBJECT_LIST
11550 HandleScope scope;
11551 CONVERT_SMI_CHECKED(obj_id, args[0]);
11552 RUNTIME_ASSERT(args[1]->IsUndefined() || args[1]->IsJSObject());
11553 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsBoolean());
11554 RUNTIME_ASSERT(args[3]->IsUndefined() || args[3]->IsSmi());
11555 RUNTIME_ASSERT(args[4]->IsUndefined() || args[4]->IsSmi());
11556 CONVERT_ARG_CHECKED(JSObject, filter_obj, 5);
11557
11558 Handle<JSObject> instance_filter;
11559 if (args[1]->IsJSObject()) {
11560 instance_filter = args.at<JSObject>(1);
11561 }
11562 bool verbose = false;
11563 if (args[2]->IsBoolean()) {
11564 verbose = args[2]->IsTrue();
11565 }
11566 int start = 0;
11567 if (args[3]->IsSmi()) {
11568 start = Smi::cast(args[3])->value();
11569 }
11570 int limit = Smi::kMaxValue;
11571 if (args[4]->IsSmi()) {
11572 limit = Smi::cast(args[4])->value();
11573 }
11574
11575 return LiveObjectList::GetObjRetainers(obj_id,
11576 instance_filter,
11577 verbose,
11578 start,
11579 limit,
11580 filter_obj);
11581 #else
11582 return isolate->heap()->undefined_value();
11583 #endif
11584 }
11585
11586
11587 // Gets the reference path between 2 objects.
11588 static MaybeObject* Runtime_GetLOLPath(RUNTIME_CALLING_CONVENTION) {
11589 RUNTIME_GET_ISOLATE;
11590 #ifdef LIVE_OBJECT_LIST
11591 HandleScope scope;
11592 CONVERT_SMI_CHECKED(obj_id1, args[0]);
11593 CONVERT_SMI_CHECKED(obj_id2, args[1]);
11594 RUNTIME_ASSERT(args[2]->IsUndefined() || args[2]->IsJSObject());
11595
11596 Handle<JSObject> instance_filter;
11597 if (args[2]->IsJSObject()) {
11598 instance_filter = args.at<JSObject>(2);
11599 }
11600
11601 Object* result =
11602 LiveObjectList::GetPath(obj_id1, obj_id2, instance_filter);
11603 return result;
11604 #else
11605 return isolate->heap()->undefined_value();
11606 #endif
11607 }
11608
11609
11610 // Generates the response to a debugger request for a list of all
11611 // previously captured live object lists.
11612 static MaybeObject* Runtime_InfoLOL(RUNTIME_CALLING_CONVENTION) {
11613 RUNTIME_GET_ISOLATE;
11614 #ifdef LIVE_OBJECT_LIST
11615 CONVERT_SMI_CHECKED(start, args[0]);
11616 CONVERT_SMI_CHECKED(count, args[1]);
11617 return LiveObjectList::Info(start, count);
11618 #else
11619 return isolate->heap()->undefined_value();
11620 #endif
11621 }
11622
11623
11624 // Gets a dump of the specified object as requested by the debugger.
11625 // This is only used for obj ids shown in live object lists.
11626 static MaybeObject* Runtime_PrintLOLObj(RUNTIME_CALLING_CONVENTION) {
11627 RUNTIME_GET_ISOLATE;
11628 #ifdef LIVE_OBJECT_LIST
11629 HandleScope scope;
11630 CONVERT_SMI_CHECKED(obj_id, args[0]);
11631 Object* result = LiveObjectList::PrintObj(obj_id);
11632 return result;
11633 #else
11634 return isolate->heap()->undefined_value();
11635 #endif
11636 }
11637
11638
11639 // Resets and releases all previously captured live object lists.
11640 static MaybeObject* Runtime_ResetLOL(RUNTIME_CALLING_CONVENTION) {
11641 RUNTIME_GET_ISOLATE;
11642 #ifdef LIVE_OBJECT_LIST
11643 LiveObjectList::Reset();
11644 return isolate->heap()->undefined_value();
11645 #else
11646 return isolate->heap()->undefined_value();
11647 #endif
11648 }
11649
11650
11651 // Generates the response to a debugger request for a summary of the types
11652 // of objects in the difference between the captured live object lists
11653 // specified by id1 and id2.
11654 // If id1 is 0 (i.e. not a valid lol), then the whole of lol id2 will be
11655 // summarized.
11656 static MaybeObject* Runtime_SummarizeLOL(RUNTIME_CALLING_CONVENTION) {
11657 RUNTIME_GET_ISOLATE;
11658 #ifdef LIVE_OBJECT_LIST
11659 HandleScope scope;
11660 CONVERT_SMI_CHECKED(id1, args[0]);
11661 CONVERT_SMI_CHECKED(id2, args[1]);
11662 CONVERT_ARG_CHECKED(JSObject, filter_obj, 2);
11663
11664 EnterDebugger enter_debugger;
11665 return LiveObjectList::Summarize(id1, id2, filter_obj);
11666 #else
11667 return isolate->heap()->undefined_value();
11668 #endif
11669 }
11670
11146 #endif // ENABLE_DEBUGGER_SUPPORT 11671 #endif // ENABLE_DEBUGGER_SUPPORT
11147 11672
11148 11673
11149 #ifdef ENABLE_LOGGING_AND_PROFILING 11674 #ifdef ENABLE_LOGGING_AND_PROFILING
11150 static MaybeObject* Runtime_ProfilerResume(RUNTIME_CALLING_CONVENTION) { 11675 static MaybeObject* Runtime_ProfilerResume(RUNTIME_CALLING_CONVENTION) {
11151 RUNTIME_GET_ISOLATE; 11676 RUNTIME_GET_ISOLATE;
11152 NoHandleAllocation ha; 11677 NoHandleAllocation ha;
11153 ASSERT(args.length() == 2); 11678 ASSERT(args.length() == 2);
11154 11679
11155 CONVERT_CHECKED(Smi, smi_modules, args[0]); 11680 CONVERT_CHECKED(Smi, smi_modules, args[0]);
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
11596 } else { 12121 } else {
11597 // Handle last resort GC and make sure to allow future allocations 12122 // Handle last resort GC and make sure to allow future allocations
11598 // to grow the heap without causing GCs (if possible). 12123 // to grow the heap without causing GCs (if possible).
11599 COUNTERS->gc_last_resort_from_js()->Increment(); 12124 COUNTERS->gc_last_resort_from_js()->Increment();
11600 HEAP->CollectAllGarbage(false); 12125 HEAP->CollectAllGarbage(false);
11601 } 12126 }
11602 } 12127 }
11603 12128
11604 12129
11605 } } // namespace v8::internal 12130 } } // 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