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

Side by Side Diff: src/runtime.cc

Issue 12330012: ES6 symbols: Allow symbols as property names (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platform ports Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/proxy.js ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
1038 return ACCESS_ALLOWED; 1038 return ACCESS_ALLOWED;
1039 } 1039 }
1040 1040
1041 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type); 1041 obj->GetIsolate()->ReportFailedAccessCheck(obj, access_type);
1042 return ACCESS_FORBIDDEN; 1042 return ACCESS_FORBIDDEN;
1043 } 1043 }
1044 1044
1045 1045
1046 static AccessCheckResult CheckPropertyAccess( 1046 static AccessCheckResult CheckPropertyAccess(
1047 JSObject* obj, 1047 JSObject* obj,
1048 String* name, 1048 Name* name,
1049 v8::AccessType access_type) { 1049 v8::AccessType access_type) {
1050 uint32_t index; 1050 uint32_t index;
1051 if (name->AsArrayIndex(&index)) { 1051 if (name->AsArrayIndex(&index)) {
1052 return CheckElementAccess(obj, index, access_type); 1052 return CheckElementAccess(obj, index, access_type);
1053 } 1053 }
1054 1054
1055 LookupResult lookup(obj->GetIsolate()); 1055 LookupResult lookup(obj->GetIsolate());
1056 obj->LocalLookup(name, &lookup, true); 1056 obj->LocalLookup(name, &lookup, true);
1057 1057
1058 if (!lookup.IsProperty()) return ACCESS_ABSENT; 1058 if (!lookup.IsProperty()) return ACCESS_ABSENT;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 SETTER_INDEX, 1098 SETTER_INDEX,
1099 WRITABLE_INDEX, 1099 WRITABLE_INDEX,
1100 ENUMERABLE_INDEX, 1100 ENUMERABLE_INDEX,
1101 CONFIGURABLE_INDEX, 1101 CONFIGURABLE_INDEX,
1102 DESCRIPTOR_SIZE 1102 DESCRIPTOR_SIZE
1103 }; 1103 };
1104 1104
1105 1105
1106 static MaybeObject* GetOwnProperty(Isolate* isolate, 1106 static MaybeObject* GetOwnProperty(Isolate* isolate,
1107 Handle<JSObject> obj, 1107 Handle<JSObject> obj,
1108 Handle<String> name) { 1108 Handle<Name> name) {
1109 Heap* heap = isolate->heap(); 1109 Heap* heap = isolate->heap();
1110 // Due to some WebKit tests, we want to make sure that we do not log 1110 // Due to some WebKit tests, we want to make sure that we do not log
1111 // more than one access failure here. 1111 // more than one access failure here.
1112 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) { 1112 switch (CheckPropertyAccess(*obj, *name, v8::ACCESS_HAS)) {
1113 case ACCESS_FORBIDDEN: return heap->false_value(); 1113 case ACCESS_FORBIDDEN: return heap->false_value();
1114 case ACCESS_ALLOWED: break; 1114 case ACCESS_ALLOWED: break;
1115 case ACCESS_ABSENT: return heap->undefined_value(); 1115 case ACCESS_ABSENT: return heap->undefined_value();
1116 } 1116 }
1117 1117
1118 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name); 1118 PropertyAttributes attrs = obj->GetLocalPropertyAttribute(*name);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 // if args[1] is not a property on args[0] 1152 // if args[1] is not a property on args[0]
1153 // returns undefined 1153 // returns undefined
1154 // if args[1] is a data property on args[0] 1154 // if args[1] is a data property on args[0]
1155 // [false, value, Writeable, Enumerable, Configurable] 1155 // [false, value, Writeable, Enumerable, Configurable]
1156 // if args[1] is an accessor on args[0] 1156 // if args[1] is an accessor on args[0]
1157 // [true, GetFunction, SetFunction, Enumerable, Configurable] 1157 // [true, GetFunction, SetFunction, Enumerable, Configurable]
1158 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) { 1158 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
1159 ASSERT(args.length() == 2); 1159 ASSERT(args.length() == 2);
1160 HandleScope scope(isolate); 1160 HandleScope scope(isolate);
1161 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 1161 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1162 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 1162 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
1163 return GetOwnProperty(isolate, obj, name); 1163 return GetOwnProperty(isolate, obj, name);
1164 } 1164 }
1165 1165
1166 1166
1167 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { 1167 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
1168 ASSERT(args.length() == 1); 1168 ASSERT(args.length() == 1);
1169 CONVERT_ARG_CHECKED(JSObject, obj, 0); 1169 CONVERT_ARG_CHECKED(JSObject, obj, 0);
1170 return obj->PreventExtensions(); 1170 return obj->PreventExtensions();
1171 } 1171 }
1172 1172
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after
2109 Map* new_map; 2109 Map* new_map;
2110 MaybeObject* maybe_map = 2110 MaybeObject* maybe_map =
2111 function->map()->CopyReplaceDescriptor( 2111 function->map()->CopyReplaceDescriptor(
2112 instance_desc, &new_desc, index, OMIT_TRANSITION); 2112 instance_desc, &new_desc, index, OMIT_TRANSITION);
2113 if (!maybe_map->To(&new_map)) return maybe_map; 2113 if (!maybe_map->To(&new_map)) return maybe_map;
2114 2114
2115 function->set_map(new_map); 2115 function->set_map(new_map);
2116 } else { // Dictionary properties. 2116 } else { // Dictionary properties.
2117 // Directly manipulate the property details. 2117 // Directly manipulate the property details.
2118 int entry = function->property_dictionary()->FindEntry(name); 2118 int entry = function->property_dictionary()->FindEntry(name);
2119 ASSERT(entry != StringDictionary::kNotFound); 2119 ASSERT(entry != NameDictionary::kNotFound);
2120 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); 2120 PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
2121 PropertyDetails new_details( 2121 PropertyDetails new_details(
2122 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), 2122 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2123 details.type(), 2123 details.type(),
2124 details.dictionary_index()); 2124 details.dictionary_index());
2125 function->property_dictionary()->DetailsAtPut(entry, new_details); 2125 function->property_dictionary()->DetailsAtPut(entry, new_details);
2126 } 2126 }
2127 return function; 2127 return function;
2128 } 2128 }
2129 2129
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after
3922 HandleVector(args, 2)); 3922 HandleVector(args, 2));
3923 return isolate->Throw(*error); 3923 return isolate->Throw(*error);
3924 } 3924 }
3925 3925
3926 // Check if the given key is an array index. 3926 // Check if the given key is an array index.
3927 uint32_t index; 3927 uint32_t index;
3928 if (key->ToArrayIndex(&index)) { 3928 if (key->ToArrayIndex(&index)) {
3929 return GetElementOrCharAt(isolate, object, index); 3929 return GetElementOrCharAt(isolate, object, index);
3930 } 3930 }
3931 3931
3932 // Convert the key to a string - possibly by calling back into JavaScript. 3932 // Convert the key to a name - possibly by calling back into JavaScript.
3933 Handle<String> name; 3933 Handle<Name> name;
3934 if (key->IsString()) { 3934 if (key->IsName()) {
3935 name = Handle<String>::cast(key); 3935 name = Handle<Name>::cast(key);
3936 } else { 3936 } else {
3937 bool has_pending_exception = false; 3937 bool has_pending_exception = false;
3938 Handle<Object> converted = 3938 Handle<Object> converted =
3939 Execution::ToString(key, &has_pending_exception); 3939 Execution::ToString(key, &has_pending_exception);
3940 if (has_pending_exception) return Failure::Exception(); 3940 if (has_pending_exception) return Failure::Exception();
3941 name = Handle<String>::cast(converted); 3941 name = Handle<Name>::cast(converted);
3942 } 3942 }
3943 3943
3944 // Check if the name is trivially convertible to an index and get 3944 // Check if the name is trivially convertible to an index and get
3945 // the element if so. 3945 // the element if so.
3946 if (name->AsArrayIndex(&index)) { 3946 if (name->AsArrayIndex(&index)) {
3947 return GetElementOrCharAt(isolate, object, index); 3947 return GetElementOrCharAt(isolate, object, index);
3948 } else { 3948 } else {
3949 return object->GetProperty(*name); 3949 return object->GetProperty(*name);
3950 } 3950 }
3951 } 3951 }
3952 3952
3953 3953
3954 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) { 3954 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
3955 NoHandleAllocation ha; 3955 NoHandleAllocation ha;
3956 ASSERT(args.length() == 2); 3956 ASSERT(args.length() == 2);
3957 3957
3958 Handle<Object> object = args.at<Object>(0); 3958 Handle<Object> object = args.at<Object>(0);
3959 Handle<Object> key = args.at<Object>(1); 3959 Handle<Object> key = args.at<Object>(1);
3960 3960
3961 return Runtime::GetObjectProperty(isolate, object, key); 3961 return Runtime::GetObjectProperty(isolate, object, key);
3962 } 3962 }
3963 3963
3964 3964
3965 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. 3965 // KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
3966 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { 3966 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
3967 NoHandleAllocation ha; 3967 NoHandleAllocation ha;
3968 ASSERT(args.length() == 2); 3968 ASSERT(args.length() == 2);
3969 3969
3970 // Fast cases for getting named properties of the receiver JSObject 3970 // Fast cases for getting named properties of the receiver JSObject
3971 // itself. 3971 // itself.
3972 // 3972 //
3973 // The global proxy objects has to be excluded since LocalLookup on 3973 // The global proxy objects has to be excluded since LocalLookup on
3974 // the global proxy object can return a valid result even though the 3974 // the global proxy object can return a valid result even though the
3975 // global proxy object never has properties. This is the case 3975 // global proxy object never has properties. This is the case
3976 // because the global proxy object forwards everything to its hidden 3976 // because the global proxy object forwards everything to its hidden
3977 // prototype including local lookups. 3977 // prototype including local lookups.
3978 // 3978 //
3979 // Additionally, we need to make sure that we do not cache results 3979 // Additionally, we need to make sure that we do not cache results
3980 // for objects that require access checks. 3980 // for objects that require access checks.
3981 if (args[0]->IsJSObject()) { 3981 if (args[0]->IsJSObject()) {
3982 if (!args[0]->IsJSGlobalProxy() && 3982 if (!args[0]->IsJSGlobalProxy() &&
3983 !args[0]->IsAccessCheckNeeded() && 3983 !args[0]->IsAccessCheckNeeded() &&
3984 args[1]->IsString()) { 3984 args[1]->IsName()) {
3985 JSObject* receiver = JSObject::cast(args[0]); 3985 JSObject* receiver = JSObject::cast(args[0]);
3986 String* key = String::cast(args[1]); 3986 Name* key = Name::cast(args[1]);
3987 if (receiver->HasFastProperties()) { 3987 if (receiver->HasFastProperties()) {
3988 // Attempt to use lookup cache. 3988 // Attempt to use lookup cache.
3989 Map* receiver_map = receiver->map(); 3989 Map* receiver_map = receiver->map();
3990 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache(); 3990 KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
3991 int offset = keyed_lookup_cache->Lookup(receiver_map, key); 3991 int offset = keyed_lookup_cache->Lookup(receiver_map, key);
3992 if (offset != -1) { 3992 if (offset != -1) {
3993 Object* value = receiver->FastPropertyAt(offset); 3993 Object* value = receiver->FastPropertyAt(offset);
3994 return value->IsTheHole() 3994 return value->IsTheHole()
3995 ? isolate->heap()->undefined_value() 3995 ? isolate->heap()->undefined_value()
3996 : value; 3996 : value;
3997 } 3997 }
3998 // Lookup cache miss. Perform lookup and update the cache if 3998 // Lookup cache miss. Perform lookup and update the cache if
3999 // appropriate. 3999 // appropriate.
4000 LookupResult result(isolate); 4000 LookupResult result(isolate);
4001 receiver->LocalLookup(key, &result); 4001 receiver->LocalLookup(key, &result);
4002 if (result.IsField()) { 4002 if (result.IsField()) {
4003 int offset = result.GetFieldIndex().field_index(); 4003 int offset = result.GetFieldIndex().field_index();
4004 keyed_lookup_cache->Update(receiver_map, key, offset); 4004 keyed_lookup_cache->Update(receiver_map, key, offset);
4005 return receiver->FastPropertyAt(offset); 4005 return receiver->FastPropertyAt(offset);
4006 } 4006 }
4007 } else { 4007 } else {
4008 // Attempt dictionary lookup. 4008 // Attempt dictionary lookup.
4009 StringDictionary* dictionary = receiver->property_dictionary(); 4009 NameDictionary* dictionary = receiver->property_dictionary();
4010 int entry = dictionary->FindEntry(key); 4010 int entry = dictionary->FindEntry(key);
4011 if ((entry != StringDictionary::kNotFound) && 4011 if ((entry != NameDictionary::kNotFound) &&
4012 (dictionary->DetailsAt(entry).type() == NORMAL)) { 4012 (dictionary->DetailsAt(entry).type() == NORMAL)) {
4013 Object* value = dictionary->ValueAt(entry); 4013 Object* value = dictionary->ValueAt(entry);
4014 if (!receiver->IsGlobalObject()) return value; 4014 if (!receiver->IsGlobalObject()) return value;
4015 value = JSGlobalPropertyCell::cast(value)->value(); 4015 value = JSGlobalPropertyCell::cast(value)->value();
4016 if (!value->IsTheHole()) return value; 4016 if (!value->IsTheHole()) return value;
4017 // If value is the hole do the general lookup. 4017 // If value is the hole do the general lookup.
4018 } 4018 }
4019 } 4019 }
4020 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { 4020 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
4021 // JSObject without a string key. If the key is a Smi, check for a 4021 // JSObject without a name key. If the key is a Smi, check for a
4022 // definite out-of-bounds access to elements, which is a strong indicator 4022 // definite out-of-bounds access to elements, which is a strong indicator
4023 // that subsequent accesses will also call the runtime. Proactively 4023 // that subsequent accesses will also call the runtime. Proactively
4024 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of 4024 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
4025 // doubles for those future calls in the case that the elements would 4025 // doubles for those future calls in the case that the elements would
4026 // become FAST_DOUBLE_ELEMENTS. 4026 // become FAST_DOUBLE_ELEMENTS.
4027 Handle<JSObject> js_object(args.at<JSObject>(0)); 4027 Handle<JSObject> js_object(args.at<JSObject>(0));
4028 ElementsKind elements_kind = js_object->GetElementsKind(); 4028 ElementsKind elements_kind = js_object->GetElementsKind();
4029 if (IsFastDoubleElementsKind(elements_kind)) { 4029 if (IsFastDoubleElementsKind(elements_kind)) {
4030 FixedArrayBase* elements = js_object->elements(); 4030 FixedArrayBase* elements = js_object->elements();
4031 if (args.at<Smi>(1)->value() >= elements->length()) { 4031 if (args.at<Smi>(1)->value() >= elements->length()) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4071 // There are 3 cases that lead here: 4071 // There are 3 cases that lead here:
4072 // Step 4b - define a new accessor property. 4072 // Step 4b - define a new accessor property.
4073 // Steps 9c & 12 - replace an existing data property with an accessor property. 4073 // Steps 9c & 12 - replace an existing data property with an accessor property.
4074 // Step 12 - update an existing accessor property with an accessor or generic 4074 // Step 12 - update an existing accessor property with an accessor or generic
4075 // descriptor. 4075 // descriptor.
4076 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { 4076 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
4077 ASSERT(args.length() == 5); 4077 ASSERT(args.length() == 5);
4078 HandleScope scope(isolate); 4078 HandleScope scope(isolate);
4079 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 4079 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
4080 RUNTIME_ASSERT(!obj->IsNull()); 4080 RUNTIME_ASSERT(!obj->IsNull());
4081 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 4081 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4082 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); 4082 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4083 RUNTIME_ASSERT(IsValidAccessor(getter)); 4083 RUNTIME_ASSERT(IsValidAccessor(getter));
4084 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); 4084 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4085 RUNTIME_ASSERT(IsValidAccessor(setter)); 4085 RUNTIME_ASSERT(IsValidAccessor(setter));
4086 CONVERT_SMI_ARG_CHECKED(unchecked, 4); 4086 CONVERT_SMI_ARG_CHECKED(unchecked, 4);
4087 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4087 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4088 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4088 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4089 4089
4090 bool fast = obj->HasFastProperties(); 4090 bool fast = obj->HasFastProperties();
4091 JSObject::DefineAccessor(obj, name, getter, setter, attr); 4091 JSObject::DefineAccessor(obj, name, getter, setter, attr);
4092 if (fast) JSObject::TransformToFastProperties(obj, 0); 4092 if (fast) JSObject::TransformToFastProperties(obj, 0);
4093 return isolate->heap()->undefined_value(); 4093 return isolate->heap()->undefined_value();
4094 } 4094 }
4095 4095
4096 // Implements part of 8.12.9 DefineOwnProperty. 4096 // Implements part of 8.12.9 DefineOwnProperty.
4097 // There are 3 cases that lead here: 4097 // There are 3 cases that lead here:
4098 // Step 4a - define a new data property. 4098 // Step 4a - define a new data property.
4099 // Steps 9b & 12 - replace an existing accessor property with a data property. 4099 // Steps 9b & 12 - replace an existing accessor property with a data property.
4100 // Step 12 - update an existing data property with a data or generic 4100 // Step 12 - update an existing data property with a data or generic
4101 // descriptor. 4101 // descriptor.
4102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { 4102 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
4103 ASSERT(args.length() == 4); 4103 ASSERT(args.length() == 4);
4104 HandleScope scope(isolate); 4104 HandleScope scope(isolate);
4105 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); 4105 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
4106 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 4106 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4107 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); 4107 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
4108 CONVERT_SMI_ARG_CHECKED(unchecked, 3); 4108 CONVERT_SMI_ARG_CHECKED(unchecked, 3);
4109 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4109 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4110 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4110 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4111 4111
4112 LookupResult result(isolate); 4112 LookupResult result(isolate);
4113 js_object->LocalLookupRealNamedProperty(*name, &result); 4113 js_object->LocalLookupRealNamedProperty(*name, &result);
4114 4114
4115 // Special case for callback properties. 4115 // Special case for callback properties.
4116 if (result.IsPropertyCallbacks()) { 4116 if (result.IsPropertyCallbacks()) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
4161 name, 4161 name,
4162 obj_value, 4162 obj_value,
4163 attr); 4163 attr);
4164 } 4164 }
4165 4165
4166 4166
4167 // Return property without being observable by accessors or interceptors. 4167 // Return property without being observable by accessors or interceptors.
4168 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { 4168 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
4169 ASSERT(args.length() == 2); 4169 ASSERT(args.length() == 2);
4170 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 4170 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
4171 CONVERT_ARG_HANDLE_CHECKED(String, key, 1); 4171 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
4172 LookupResult lookup(isolate); 4172 LookupResult lookup(isolate);
4173 object->LookupRealNamedProperty(*key, &lookup); 4173 object->LookupRealNamedProperty(*key, &lookup);
4174 if (!lookup.IsFound()) return isolate->heap()->undefined_value(); 4174 if (!lookup.IsFound()) return isolate->heap()->undefined_value();
4175 switch (lookup.type()) { 4175 switch (lookup.type()) {
4176 case NORMAL: 4176 case NORMAL:
4177 return lookup.holder()->GetNormalizedProperty(&lookup); 4177 return lookup.holder()->GetNormalizedProperty(&lookup);
4178 case FIELD: 4178 case FIELD:
4179 return lookup.holder()->FastPropertyAt( 4179 return lookup.holder()->FastPropertyAt(
4180 lookup.GetFieldIndex().field_index()); 4180 lookup.GetFieldIndex().field_index());
4181 case CONSTANT_FUNCTION: 4181 case CONSTANT_FUNCTION:
(...skipping 22 matching lines...) Expand all
4204 if (object->IsUndefined() || object->IsNull()) { 4204 if (object->IsUndefined() || object->IsNull()) {
4205 Handle<Object> args[2] = { key, object }; 4205 Handle<Object> args[2] = { key, object };
4206 Handle<Object> error = 4206 Handle<Object> error =
4207 isolate->factory()->NewTypeError("non_object_property_store", 4207 isolate->factory()->NewTypeError("non_object_property_store",
4208 HandleVector(args, 2)); 4208 HandleVector(args, 2));
4209 return isolate->Throw(*error); 4209 return isolate->Throw(*error);
4210 } 4210 }
4211 4211
4212 if (object->IsJSProxy()) { 4212 if (object->IsJSProxy()) {
4213 bool has_pending_exception = false; 4213 bool has_pending_exception = false;
4214 Handle<Object> name = Execution::ToString(key, &has_pending_exception); 4214 Handle<Object> name = key->IsSymbol()
4215 ? key : Execution::ToString(key, &has_pending_exception);
4215 if (has_pending_exception) return Failure::Exception(); 4216 if (has_pending_exception) return Failure::Exception();
4216 return JSProxy::cast(*object)->SetProperty( 4217 return JSProxy::cast(*object)->SetProperty(
4217 String::cast(*name), *value, attr, strict_mode); 4218 Name::cast(*name), *value, attr, strict_mode);
4218 } 4219 }
4219 4220
4220 // If the object isn't a JavaScript object, we ignore the store. 4221 // If the object isn't a JavaScript object, we ignore the store.
4221 if (!object->IsJSObject()) return *value; 4222 if (!object->IsJSObject()) return *value;
4222 4223
4223 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 4224 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
4224 4225
4225 // Check if the given key is an array index. 4226 // Check if the given key is an array index.
4226 uint32_t index; 4227 uint32_t index;
4227 if (key->ToArrayIndex(&index)) { 4228 if (key->ToArrayIndex(&index)) {
4228 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 4229 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
4229 // of a string using [] notation. We need to support this too in 4230 // of a string using [] notation. We need to support this too in
4230 // JavaScript. 4231 // JavaScript.
4231 // In the case of a String object we just need to redirect the assignment to 4232 // In the case of a String object we just need to redirect the assignment to
4232 // the underlying string if the index is in range. Since the underlying 4233 // the underlying string if the index is in range. Since the underlying
4233 // string does nothing with the assignment then we can ignore such 4234 // string does nothing with the assignment then we can ignore such
4234 // assignments. 4235 // assignments.
4235 if (js_object->IsStringObjectWithCharacterAt(index)) { 4236 if (js_object->IsStringObjectWithCharacterAt(index)) {
4236 return *value; 4237 return *value;
4237 } 4238 }
4238 4239
4239 js_object->ValidateElements(); 4240 js_object->ValidateElements();
4240 Handle<Object> result = JSObject::SetElement( 4241 Handle<Object> result = JSObject::SetElement(
4241 js_object, index, value, attr, strict_mode, set_mode); 4242 js_object, index, value, attr, strict_mode, set_mode);
4242 js_object->ValidateElements(); 4243 js_object->ValidateElements();
4243 if (result.is_null()) return Failure::Exception(); 4244 if (result.is_null()) return Failure::Exception();
4244 return *value; 4245 return *value;
4245 } 4246 }
4246 4247
4247 if (key->IsString()) { 4248 if (key->IsName()) {
4248 Handle<Object> result; 4249 Handle<Object> result;
4249 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 4250 Handle<Name> name = Handle<Name>::cast(key);
4251 if (name->AsArrayIndex(&index)) {
4250 result = JSObject::SetElement( 4252 result = JSObject::SetElement(
4251 js_object, index, value, attr, strict_mode, set_mode); 4253 js_object, index, value, attr, strict_mode, set_mode);
4252 } else { 4254 } else {
4253 Handle<String> key_string = Handle<String>::cast(key); 4255 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
4254 key_string->TryFlatten();
4255 result = JSReceiver::SetProperty( 4256 result = JSReceiver::SetProperty(
4256 js_object, key_string, value, attr, strict_mode); 4257 js_object, name, value, attr, strict_mode);
4257 } 4258 }
4258 if (result.is_null()) return Failure::Exception(); 4259 if (result.is_null()) return Failure::Exception();
4259 return *value; 4260 return *value;
4260 } 4261 }
4261 4262
4262 // Call-back into JavaScript to convert the key to a string. 4263 // Call-back into JavaScript to convert the key to a string.
4263 bool has_pending_exception = false; 4264 bool has_pending_exception = false;
4264 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4265 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
4265 if (has_pending_exception) return Failure::Exception(); 4266 if (has_pending_exception) return Failure::Exception();
4266 Handle<String> name = Handle<String>::cast(converted); 4267 Handle<String> name = Handle<String>::cast(converted);
(...skipping 25 matching lines...) Expand all
4292 // string does nothing with the assignment then we can ignore such 4293 // string does nothing with the assignment then we can ignore such
4293 // assignments. 4294 // assignments.
4294 if (js_object->IsStringObjectWithCharacterAt(index)) { 4295 if (js_object->IsStringObjectWithCharacterAt(index)) {
4295 return *value; 4296 return *value;
4296 } 4297 }
4297 4298
4298 return js_object->SetElement( 4299 return js_object->SetElement(
4299 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 4300 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
4300 } 4301 }
4301 4302
4302 if (key->IsString()) { 4303 if (key->IsName()) {
4303 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 4304 Handle<Name> name = Handle<Name>::cast(key);
4305 if (name->AsArrayIndex(&index)) {
4304 return js_object->SetElement( 4306 return js_object->SetElement(
4305 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 4307 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY);
4306 } else { 4308 } else {
4307 Handle<String> key_string = Handle<String>::cast(key); 4309 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
4308 key_string->TryFlatten(); 4310 return js_object->SetLocalPropertyIgnoreAttributes(*name, *value, attr);
4309 return js_object->SetLocalPropertyIgnoreAttributes(*key_string,
4310 *value,
4311 attr);
4312 } 4311 }
4313 } 4312 }
4314 4313
4315 // Call-back into JavaScript to convert the key to a string. 4314 // Call-back into JavaScript to convert the key to a string.
4316 bool has_pending_exception = false; 4315 bool has_pending_exception = false;
4317 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4316 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
4318 if (has_pending_exception) return Failure::Exception(); 4317 if (has_pending_exception) return Failure::Exception();
4319 Handle<String> name = Handle<String>::cast(converted); 4318 Handle<String> name = Handle<String>::cast(converted);
4320 4319
4321 if (name->AsArrayIndex(&index)) { 4320 if (name->AsArrayIndex(&index)) {
(...skipping 19 matching lines...) Expand all
4341 // underlying string if the index is in range. Since the 4340 // underlying string if the index is in range. Since the
4342 // underlying string does nothing with the deletion, we can ignore 4341 // underlying string does nothing with the deletion, we can ignore
4343 // such deletions. 4342 // such deletions.
4344 if (receiver->IsStringObjectWithCharacterAt(index)) { 4343 if (receiver->IsStringObjectWithCharacterAt(index)) {
4345 return isolate->heap()->true_value(); 4344 return isolate->heap()->true_value();
4346 } 4345 }
4347 4346
4348 return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION); 4347 return receiver->DeleteElement(index, JSReceiver::FORCE_DELETION);
4349 } 4348 }
4350 4349
4351 Handle<String> key_string; 4350 Handle<Name> name;
4352 if (key->IsString()) { 4351 if (key->IsName()) {
4353 key_string = Handle<String>::cast(key); 4352 name = Handle<Name>::cast(key);
4354 } else { 4353 } else {
4355 // Call-back into JavaScript to convert the key to a string. 4354 // Call-back into JavaScript to convert the key to a string.
4356 bool has_pending_exception = false; 4355 bool has_pending_exception = false;
4357 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); 4356 Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
4358 if (has_pending_exception) return Failure::Exception(); 4357 if (has_pending_exception) return Failure::Exception();
4359 key_string = Handle<String>::cast(converted); 4358 name = Handle<String>::cast(converted);
4360 } 4359 }
4361 4360
4362 key_string->TryFlatten(); 4361 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
4363 return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION); 4362 return receiver->DeleteProperty(*name, JSReceiver::FORCE_DELETION);
4364 } 4363 }
4365 4364
4366 4365
4367 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) { 4366 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetProperty) {
4368 NoHandleAllocation ha; 4367 NoHandleAllocation ha;
4369 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); 4368 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5);
4370 4369
4371 Handle<Object> object = args.at<Object>(0); 4370 Handle<Object> object = args.at<Object>(0);
4372 Handle<Object> key = args.at<Object>(1); 4371 Handle<Object> key = args.at<Object>(1);
4373 Handle<Object> value = args.at<Object>(2); 4372 Handle<Object> value = args.at<Object>(2);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4540 return isolate->heap()->undefined_value(); 4539 return isolate->heap()->undefined_value();
4541 } 4540 }
4542 4541
4543 4542
4544 // Set a local property, even if it is READ_ONLY. If the property does not 4543 // Set a local property, even if it is READ_ONLY. If the property does not
4545 // exist, it will be added with attributes NONE. 4544 // exist, it will be added with attributes NONE.
4546 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) { 4545 RUNTIME_FUNCTION(MaybeObject*, Runtime_IgnoreAttributesAndSetProperty) {
4547 NoHandleAllocation ha; 4546 NoHandleAllocation ha;
4548 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4); 4547 RUNTIME_ASSERT(args.length() == 3 || args.length() == 4);
4549 CONVERT_ARG_CHECKED(JSObject, object, 0); 4548 CONVERT_ARG_CHECKED(JSObject, object, 0);
4550 CONVERT_ARG_CHECKED(String, name, 1); 4549 CONVERT_ARG_CHECKED(Name, name, 1);
4551 // Compute attributes. 4550 // Compute attributes.
4552 PropertyAttributes attributes = NONE; 4551 PropertyAttributes attributes = NONE;
4553 if (args.length() == 4) { 4552 if (args.length() == 4) {
4554 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3); 4553 CONVERT_SMI_ARG_CHECKED(unchecked_value, 3);
4555 // Only attribute bits should be set. 4554 // Only attribute bits should be set.
4556 RUNTIME_ASSERT( 4555 RUNTIME_ASSERT(
4557 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4556 (unchecked_value & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4558 attributes = static_cast<PropertyAttributes>(unchecked_value); 4557 attributes = static_cast<PropertyAttributes>(unchecked_value);
4559 } 4558 }
4560 4559
4561 return object-> 4560 return object->
4562 SetLocalPropertyIgnoreAttributes(name, args[2], attributes); 4561 SetLocalPropertyIgnoreAttributes(name, args[2], attributes);
4563 } 4562 }
4564 4563
4565 4564
4566 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) { 4565 RUNTIME_FUNCTION(MaybeObject*, Runtime_DeleteProperty) {
4567 NoHandleAllocation ha; 4566 NoHandleAllocation ha;
4568 ASSERT(args.length() == 3); 4567 ASSERT(args.length() == 3);
4569 4568
4570 CONVERT_ARG_CHECKED(JSReceiver, object, 0); 4569 CONVERT_ARG_CHECKED(JSReceiver, object, 0);
4571 CONVERT_ARG_CHECKED(String, key, 1); 4570 CONVERT_ARG_CHECKED(Name, key, 1);
4572 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2); 4571 CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
4573 return object->DeleteProperty(key, (strict_mode == kStrictMode) 4572 return object->DeleteProperty(key, (strict_mode == kStrictMode)
4574 ? JSReceiver::STRICT_DELETION 4573 ? JSReceiver::STRICT_DELETION
4575 : JSReceiver::NORMAL_DELETION); 4574 : JSReceiver::NORMAL_DELETION);
4576 } 4575 }
4577 4576
4578 4577
4579 static Object* HasLocalPropertyImplementation(Isolate* isolate, 4578 static Object* HasLocalPropertyImplementation(Isolate* isolate,
4580 Handle<JSObject> object, 4579 Handle<JSObject> object,
4581 Handle<String> key) { 4580 Handle<Name> key) {
4582 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); 4581 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value();
4583 // Handle hidden prototypes. If there's a hidden prototype above this thing 4582 // Handle hidden prototypes. If there's a hidden prototype above this thing
4584 // then we have to check it for properties, because they are supposed to 4583 // then we have to check it for properties, because they are supposed to
4585 // look like they are on this object. 4584 // look like they are on this object.
4586 Handle<Object> proto(object->GetPrototype()); 4585 Handle<Object> proto(object->GetPrototype());
4587 if (proto->IsJSObject() && 4586 if (proto->IsJSObject() &&
4588 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { 4587 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
4589 return HasLocalPropertyImplementation(isolate, 4588 return HasLocalPropertyImplementation(isolate,
4590 Handle<JSObject>::cast(proto), 4589 Handle<JSObject>::cast(proto),
4591 key); 4590 key);
4592 } 4591 }
4593 return isolate->heap()->false_value(); 4592 return isolate->heap()->false_value();
4594 } 4593 }
4595 4594
4596 4595
4597 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) { 4596 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasLocalProperty) {
4598 NoHandleAllocation ha; 4597 NoHandleAllocation ha;
4599 ASSERT(args.length() == 2); 4598 ASSERT(args.length() == 2);
4600 CONVERT_ARG_CHECKED(String, key, 1); 4599 CONVERT_ARG_CHECKED(Name, key, 1);
4601 4600
4602 uint32_t index; 4601 uint32_t index;
4603 const bool key_is_array_index = key->AsArrayIndex(&index); 4602 const bool key_is_array_index = key->AsArrayIndex(&index);
4604 4603
4605 Object* obj = args[0]; 4604 Object* obj = args[0];
4606 // Only JS objects can have properties. 4605 // Only JS objects can have properties.
4607 if (obj->IsJSObject()) { 4606 if (obj->IsJSObject()) {
4608 JSObject* object = JSObject::cast(obj); 4607 JSObject* object = JSObject::cast(obj);
4609 // Fast case: either the key is a real named property or it is not 4608 // Fast case: either the key is a real named property or it is not
4610 // an array index and there are no interceptors or hidden 4609 // an array index and there are no interceptors or hidden
4611 // prototypes. 4610 // prototypes.
4612 if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value(); 4611 if (object->HasRealNamedProperty(key)) return isolate->heap()->true_value();
4613 Map* map = object->map(); 4612 Map* map = object->map();
4614 if (!key_is_array_index && 4613 if (!key_is_array_index &&
4615 !map->has_named_interceptor() && 4614 !map->has_named_interceptor() &&
4616 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { 4615 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
4617 return isolate->heap()->false_value(); 4616 return isolate->heap()->false_value();
4618 } 4617 }
4619 // Slow case. 4618 // Slow case.
4620 HandleScope scope(isolate); 4619 HandleScope scope(isolate);
4621 return HasLocalPropertyImplementation(isolate, 4620 return HasLocalPropertyImplementation(isolate,
4622 Handle<JSObject>(object), 4621 Handle<JSObject>(object),
4623 Handle<String>(key)); 4622 Handle<Name>(key));
4624 } else if (obj->IsString() && key_is_array_index) { 4623 } else if (obj->IsString() && key_is_array_index) {
4625 // Well, there is one exception: Handle [] on strings. 4624 // Well, there is one exception: Handle [] on strings.
4626 String* string = String::cast(obj); 4625 String* string = String::cast(obj);
4627 if (index < static_cast<uint32_t>(string->length())) { 4626 if (index < static_cast<uint32_t>(string->length())) {
4628 return isolate->heap()->true_value(); 4627 return isolate->heap()->true_value();
4629 } 4628 }
4630 } 4629 }
4631 return isolate->heap()->false_value(); 4630 return isolate->heap()->false_value();
4632 } 4631 }
4633 4632
4634 4633
4635 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { 4634 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
4636 NoHandleAllocation na; 4635 NoHandleAllocation na;
4637 ASSERT(args.length() == 2); 4636 ASSERT(args.length() == 2);
4638 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); 4637 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
4639 CONVERT_ARG_CHECKED(String, key, 1); 4638 CONVERT_ARG_CHECKED(Name, key, 1);
4640 4639
4641 bool result = receiver->HasProperty(key); 4640 bool result = receiver->HasProperty(key);
4642 if (isolate->has_pending_exception()) return Failure::Exception(); 4641 if (isolate->has_pending_exception()) return Failure::Exception();
4643 return isolate->heap()->ToBoolean(result); 4642 return isolate->heap()->ToBoolean(result);
4644 } 4643 }
4645 4644
4646 4645
4647 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { 4646 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
4648 NoHandleAllocation na; 4647 NoHandleAllocation na;
4649 ASSERT(args.length() == 2); 4648 ASSERT(args.length() == 2);
4650 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); 4649 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
4651 CONVERT_SMI_ARG_CHECKED(index, 1); 4650 CONVERT_SMI_ARG_CHECKED(index, 1);
4652 4651
4653 bool result = receiver->HasElement(index); 4652 bool result = receiver->HasElement(index);
4654 if (isolate->has_pending_exception()) return Failure::Exception(); 4653 if (isolate->has_pending_exception()) return Failure::Exception();
4655 return isolate->heap()->ToBoolean(result); 4654 return isolate->heap()->ToBoolean(result);
4656 } 4655 }
4657 4656
4658 4657
4659 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { 4658 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
4660 NoHandleAllocation ha; 4659 NoHandleAllocation ha;
4661 ASSERT(args.length() == 2); 4660 ASSERT(args.length() == 2);
4662 4661
4663 CONVERT_ARG_CHECKED(JSObject, object, 0); 4662 CONVERT_ARG_CHECKED(JSObject, object, 0);
4664 CONVERT_ARG_CHECKED(String, key, 1); 4663 CONVERT_ARG_CHECKED(Name, key, 1);
4665 4664
4666 PropertyAttributes att = object->GetLocalPropertyAttribute(key); 4665 PropertyAttributes att = object->GetLocalPropertyAttribute(key);
4667 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0); 4666 return isolate->heap()->ToBoolean(att != ABSENT && (att & DONT_ENUM) == 0);
4668 } 4667 }
4669 4668
4670 4669
4671 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) { 4670 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetPropertyNames) {
4672 HandleScope scope(isolate); 4671 HandleScope scope(isolate);
4673 ASSERT(args.length() == 1); 4672 ASSERT(args.length() == 1);
4674 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 4673 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
4898 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw); 4897 GetKeysInFixedArrayFor(object, LOCAL_ONLY, &threw);
4899 if (threw) return Failure::Exception(); 4898 if (threw) return Failure::Exception();
4900 4899
4901 // Some fast paths through GetKeysInFixedArrayFor reuse a cached 4900 // Some fast paths through GetKeysInFixedArrayFor reuse a cached
4902 // property array and since the result is mutable we have to create 4901 // property array and since the result is mutable we have to create
4903 // a fresh clone on each invocation. 4902 // a fresh clone on each invocation.
4904 int length = contents->length(); 4903 int length = contents->length();
4905 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length); 4904 Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
4906 for (int i = 0; i < length; i++) { 4905 for (int i = 0; i < length; i++) {
4907 Object* entry = contents->get(i); 4906 Object* entry = contents->get(i);
4908 if (entry->IsString()) { 4907 if (entry->IsName()) {
4909 copy->set(i, entry); 4908 copy->set(i, entry);
4910 } else { 4909 } else {
4911 ASSERT(entry->IsNumber()); 4910 ASSERT(entry->IsNumber());
4912 HandleScope scope(isolate); 4911 HandleScope scope(isolate);
4913 Handle<Object> entry_handle(entry, isolate); 4912 Handle<Object> entry_handle(entry, isolate);
4914 Handle<Object> entry_str = 4913 Handle<Object> entry_str =
4915 isolate->factory()->NumberToString(entry_handle); 4914 isolate->factory()->NumberToString(entry_handle);
4916 copy->set(i, *entry_str); 4915 copy->set(i, *entry_str);
4917 } 4916 }
4918 } 4917 }
(...skipping 13 matching lines...) Expand all
4932 // Get the actual number of provided arguments. 4931 // Get the actual number of provided arguments.
4933 const uint32_t n = frame->ComputeParametersCount(); 4932 const uint32_t n = frame->ComputeParametersCount();
4934 4933
4935 // Try to convert the key to an index. If successful and within 4934 // Try to convert the key to an index. If successful and within
4936 // index return the the argument from the frame. 4935 // index return the the argument from the frame.
4937 uint32_t index; 4936 uint32_t index;
4938 if (args[0]->ToArrayIndex(&index) && index < n) { 4937 if (args[0]->ToArrayIndex(&index) && index < n) {
4939 return frame->GetParameter(index); 4938 return frame->GetParameter(index);
4940 } 4939 }
4941 4940
4941 if (args[0]->IsSymbol()) {
4942 // Lookup in the initial Object.prototype object.
4943 return isolate->initial_object_prototype()->GetProperty(
4944 Symbol::cast(args[0]));
4945 }
4946
4942 // Convert the key to a string. 4947 // Convert the key to a string.
4943 HandleScope scope(isolate); 4948 HandleScope scope(isolate);
4944 bool exception = false; 4949 bool exception = false;
4945 Handle<Object> converted = 4950 Handle<Object> converted =
4946 Execution::ToString(args.at<Object>(0), &exception); 4951 Execution::ToString(args.at<Object>(0), &exception);
4947 if (exception) return Failure::Exception(); 4952 if (exception) return Failure::Exception();
4948 Handle<String> key = Handle<String>::cast(converted); 4953 Handle<String> key = Handle<String>::cast(converted);
4949 4954
4950 // Try to convert the string key into an array index. 4955 // Try to convert the string key into an array index.
4951 if (key->AsArrayIndex(&index)) { 4956 if (key->AsArrayIndex(&index)) {
(...skipping 5120 matching lines...) Expand 10 before | Expand all | Expand 10 after
10072 isolate->factory()->NewNumber(static_cast<double>(min_length)); 10077 isolate->factory()->NewNumber(static_cast<double>(min_length));
10073 single_interval->set(1, *length_object); 10078 single_interval->set(1, *length_object);
10074 return *isolate->factory()->NewJSArrayWithElements(single_interval); 10079 return *isolate->factory()->NewJSArrayWithElements(single_interval);
10075 } 10080 }
10076 } 10081 }
10077 10082
10078 10083
10079 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) { 10084 RUNTIME_FUNCTION(MaybeObject*, Runtime_LookupAccessor) {
10080 ASSERT(args.length() == 3); 10085 ASSERT(args.length() == 3);
10081 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); 10086 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0);
10082 CONVERT_ARG_CHECKED(String, name, 1); 10087 CONVERT_ARG_CHECKED(Name, name, 1);
10083 CONVERT_SMI_ARG_CHECKED(flag, 2); 10088 CONVERT_SMI_ARG_CHECKED(flag, 2);
10084 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; 10089 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
10085 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value(); 10090 if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
10086 return JSObject::cast(receiver)->LookupAccessor(name, component); 10091 return JSObject::cast(receiver)->LookupAccessor(name, component);
10087 } 10092 }
10088 10093
10089 10094
10090 #ifdef ENABLE_DEBUGGER_SUPPORT 10095 #ifdef ENABLE_DEBUGGER_SUPPORT
10091 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) { 10096 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugBreak) {
10092 ASSERT(args.length() == 0); 10097 ASSERT(args.length() == 0);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
10125 10130
10126 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) { 10131 RUNTIME_FUNCTION(MaybeObject*, Runtime_Break) {
10127 ASSERT(args.length() == 0); 10132 ASSERT(args.length() == 0);
10128 isolate->stack_guard()->DebugBreak(); 10133 isolate->stack_guard()->DebugBreak();
10129 return isolate->heap()->undefined_value(); 10134 return isolate->heap()->undefined_value();
10130 } 10135 }
10131 10136
10132 10137
10133 static MaybeObject* DebugLookupResultValue(Heap* heap, 10138 static MaybeObject* DebugLookupResultValue(Heap* heap,
10134 Object* receiver, 10139 Object* receiver,
10135 String* name, 10140 Name* name,
10136 LookupResult* result, 10141 LookupResult* result,
10137 bool* caught_exception) { 10142 bool* caught_exception) {
10138 Object* value; 10143 Object* value;
10139 switch (result->type()) { 10144 switch (result->type()) {
10140 case NORMAL: 10145 case NORMAL:
10141 value = result->holder()->GetNormalizedProperty(result); 10146 value = result->holder()->GetNormalizedProperty(result);
10142 if (value->IsTheHole()) { 10147 if (value->IsTheHole()) {
10143 return heap->undefined_value(); 10148 return heap->undefined_value();
10144 } 10149 }
10145 return value; 10150 return value;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
10197 // 3: Getter function if defined 10202 // 3: Getter function if defined
10198 // 4: Setter function if defined 10203 // 4: Setter function if defined
10199 // Items 2-4 are only filled if the property has either a getter or a setter 10204 // Items 2-4 are only filled if the property has either a getter or a setter
10200 // defined through __defineGetter__ and/or __defineSetter__. 10205 // defined through __defineGetter__ and/or __defineSetter__.
10201 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) { 10206 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPropertyDetails) {
10202 HandleScope scope(isolate); 10207 HandleScope scope(isolate);
10203 10208
10204 ASSERT(args.length() == 2); 10209 ASSERT(args.length() == 2);
10205 10210
10206 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 10211 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10207 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 10212 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10208 10213
10209 // Make sure to set the current context to the context before the debugger was 10214 // Make sure to set the current context to the context before the debugger was
10210 // entered (if the debugger is entered). The reason for switching context here 10215 // entered (if the debugger is entered). The reason for switching context here
10211 // is that for some property lookups (accessors and interceptors) callbacks 10216 // is that for some property lookups (accessors and interceptors) callbacks
10212 // into the embedding application can occour, and the embedding application 10217 // into the embedding application can occour, and the embedding application
10213 // could have the assumption that its own native context is the current 10218 // could have the assumption that its own native context is the current
10214 // context and not some internal debugger context. 10219 // context and not some internal debugger context.
10215 SaveContext save(isolate); 10220 SaveContext save(isolate);
10216 if (isolate->debug()->InDebugger()) { 10221 if (isolate->debug()->InDebugger()) {
10217 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext()); 10222 isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
10295 return isolate->heap()->undefined_value(); 10300 return isolate->heap()->undefined_value();
10296 } 10301 }
10297 10302
10298 10303
10299 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) { 10304 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetProperty) {
10300 HandleScope scope(isolate); 10305 HandleScope scope(isolate);
10301 10306
10302 ASSERT(args.length() == 2); 10307 ASSERT(args.length() == 2);
10303 10308
10304 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 10309 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10305 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 10310 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10306 10311
10307 LookupResult result(isolate); 10312 LookupResult result(isolate);
10308 obj->Lookup(*name, &result); 10313 obj->Lookup(*name, &result);
10309 if (result.IsFound()) { 10314 if (result.IsFound()) {
10310 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL); 10315 return DebugLookupResultValue(isolate->heap(), *obj, *name, &result, NULL);
10311 } 10316 }
10312 return isolate->heap()->undefined_value(); 10317 return isolate->heap()->undefined_value();
10313 } 10318 }
10314 10319
10315 10320
(...skipping 26 matching lines...) Expand all
10342 10347
10343 10348
10344 // Return property value from named interceptor. 10349 // Return property value from named interceptor.
10345 // args[0]: object 10350 // args[0]: object
10346 // args[1]: property name 10351 // args[1]: property name
10347 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) { 10352 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugNamedInterceptorPropertyValue) {
10348 HandleScope scope(isolate); 10353 HandleScope scope(isolate);
10349 ASSERT(args.length() == 2); 10354 ASSERT(args.length() == 2);
10350 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 10355 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
10351 RUNTIME_ASSERT(obj->HasNamedInterceptor()); 10356 RUNTIME_ASSERT(obj->HasNamedInterceptor());
10352 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 10357 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
10353 10358
10354 PropertyAttributes attributes; 10359 PropertyAttributes attributes;
10355 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes); 10360 return obj->GetPropertyWithInterceptor(*obj, *name, &attributes);
10356 } 10361 }
10357 10362
10358 10363
10359 // Return element value from indexed interceptor. 10364 // Return element value from indexed interceptor.
10360 // args[0]: object 10365 // args[0]: object
10361 // args[1]: index 10366 // args[1]: index
10362 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) { 10367 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugIndexedInterceptorElementValue) {
(...skipping 3108 matching lines...) Expand 10 before | Expand all | Expand 10 after
13471 RUNTIME_FUNCTION_LIST(F) 13476 RUNTIME_FUNCTION_LIST(F)
13472 INLINE_FUNCTION_LIST(I) 13477 INLINE_FUNCTION_LIST(I)
13473 INLINE_RUNTIME_FUNCTION_LIST(I) 13478 INLINE_RUNTIME_FUNCTION_LIST(I)
13474 }; 13479 };
13475 13480
13476 13481
13477 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, 13482 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap,
13478 Object* dictionary) { 13483 Object* dictionary) {
13479 ASSERT(Isolate::Current()->heap() == heap); 13484 ASSERT(Isolate::Current()->heap() == heap);
13480 ASSERT(dictionary != NULL); 13485 ASSERT(dictionary != NULL);
13481 ASSERT(StringDictionary::cast(dictionary)->NumberOfElements() == 0); 13486 ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0);
13482 for (int i = 0; i < kNumFunctions; ++i) { 13487 for (int i = 0; i < kNumFunctions; ++i) {
13483 Object* name_string; 13488 Object* name_string;
13484 { MaybeObject* maybe_name_string = 13489 { MaybeObject* maybe_name_string =
13485 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); 13490 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
13486 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; 13491 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
13487 } 13492 }
13488 StringDictionary* string_dictionary = StringDictionary::cast(dictionary); 13493 NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
13489 { MaybeObject* maybe_dictionary = string_dictionary->Add( 13494 { MaybeObject* maybe_dictionary = name_dictionary->Add(
13490 String::cast(name_string), 13495 String::cast(name_string),
13491 Smi::FromInt(i), 13496 Smi::FromInt(i),
13492 PropertyDetails(NONE, NORMAL)); 13497 PropertyDetails(NONE, NORMAL));
13493 if (!maybe_dictionary->ToObject(&dictionary)) { 13498 if (!maybe_dictionary->ToObject(&dictionary)) {
13494 // Non-recoverable failure. Calling code must restart heap 13499 // Non-recoverable failure. Calling code must restart heap
13495 // initialization. 13500 // initialization.
13496 return maybe_dictionary; 13501 return maybe_dictionary;
13497 } 13502 }
13498 } 13503 }
13499 } 13504 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
13534 // Handle last resort GC and make sure to allow future allocations 13539 // Handle last resort GC and make sure to allow future allocations
13535 // to grow the heap without causing GCs (if possible). 13540 // to grow the heap without causing GCs (if possible).
13536 isolate->counters()->gc_last_resort_from_js()->Increment(); 13541 isolate->counters()->gc_last_resort_from_js()->Increment();
13537 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13542 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13538 "Runtime::PerformGC"); 13543 "Runtime::PerformGC");
13539 } 13544 }
13540 } 13545 }
13541 13546
13542 13547
13543 } } // namespace v8::internal 13548 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/proxy.js ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698