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

Side by Side Diff: src/runtime.cc

Issue 23601031: Handlify JSReceiver::SetProperty and friends. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Toon Verwaest. Created 7 years, 3 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/objects-inl.h ('k') | src/stub-cache.cc » ('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 2183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 RETURN_IF_EMPTY_HANDLE(isolate, 2194 RETURN_IF_EMPTY_HANDLE(isolate,
2195 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); 2195 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
2196 } 2196 }
2197 } 2197 }
2198 2198
2199 return isolate->heap()->undefined_value(); 2199 return isolate->heap()->undefined_value();
2200 } 2200 }
2201 2201
2202 2202
2203 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { 2203 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
2204 SealHandleScope shs(isolate); 2204 HandleScope scope(isolate);
2205 // args[0] == name 2205 // args[0] == name
2206 // args[1] == language_mode 2206 // args[1] == language_mode
2207 // args[2] == value (optional) 2207 // args[2] == value (optional)
2208 2208
2209 // Determine if we need to assign to the variable if it already 2209 // Determine if we need to assign to the variable if it already
2210 // exists (based on the number of arguments). 2210 // exists (based on the number of arguments).
2211 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); 2211 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
2212 bool assign = args.length() == 3; 2212 bool assign = args.length() == 3;
2213 2213
2214 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 2214 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2215 GlobalObject* global = isolate->context()->global_object();
2216 RUNTIME_ASSERT(args[1]->IsSmi()); 2215 RUNTIME_ASSERT(args[1]->IsSmi());
2217 CONVERT_LANGUAGE_MODE_ARG(language_mode, 1); 2216 CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
2218 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE) 2217 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
2219 ? kNonStrictMode : kStrictMode; 2218 ? kNonStrictMode : kStrictMode;
2220 2219
2221 // According to ECMA-262, section 12.2, page 62, the property must 2220 // According to ECMA-262, section 12.2, page 62, the property must
2222 // not be deletable. 2221 // not be deletable.
2223 PropertyAttributes attributes = DONT_DELETE; 2222 PropertyAttributes attributes = DONT_DELETE;
2224 2223
2225 // Lookup the property locally in the global object. If it isn't 2224 // Lookup the property locally in the global object. If it isn't
2226 // there, there is a property with this name in the prototype chain. 2225 // there, there is a property with this name in the prototype chain.
2227 // We follow Safari and Firefox behavior and only set the property 2226 // We follow Safari and Firefox behavior and only set the property
2228 // locally if there is an explicit initialization value that we have 2227 // locally if there is an explicit initialization value that we have
2229 // to assign to the property. 2228 // to assign to the property.
2230 // Note that objects can have hidden prototypes, so we need to traverse 2229 // Note that objects can have hidden prototypes, so we need to traverse
2231 // the whole chain of hidden prototypes to do a 'local' lookup. 2230 // the whole chain of hidden prototypes to do a 'local' lookup.
2232 Object* object = global;
2233 LookupResult lookup(isolate); 2231 LookupResult lookup(isolate);
2234 JSObject::cast(object)->LocalLookup(*name, &lookup, true); 2232 isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
2235 if (lookup.IsInterceptor()) { 2233 if (lookup.IsInterceptor()) {
2236 HandleScope handle_scope(isolate);
2237 PropertyAttributes intercepted = 2234 PropertyAttributes intercepted =
2238 lookup.holder()->GetPropertyAttribute(*name); 2235 lookup.holder()->GetPropertyAttribute(*name);
2239 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { 2236 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
2240 // Found an interceptor that's not read only. 2237 // Found an interceptor that's not read only.
2241 if (assign) { 2238 if (assign) {
2242 return lookup.holder()->SetProperty( 2239 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2243 &lookup, *name, args[2], attributes, strict_mode_flag); 2240 Handle<Object> result = JSObject::SetPropertyForResult(
2241 handle(lookup.holder()), &lookup, name, value, attributes,
2242 strict_mode_flag);
2243 RETURN_IF_EMPTY_HANDLE(isolate, result);
2244 return *result;
2244 } else { 2245 } else {
2245 return isolate->heap()->undefined_value(); 2246 return isolate->heap()->undefined_value();
2246 } 2247 }
2247 } 2248 }
2248 } 2249 }
2249 2250
2250 // Reload global in case the loop above performed a GC.
2251 global = isolate->context()->global_object();
2252 if (assign) { 2251 if (assign) {
2253 return global->SetProperty(*name, args[2], attributes, strict_mode_flag); 2252 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2253 Handle<GlobalObject> global(isolate->context()->global_object());
2254 Handle<Object> result = JSReceiver::SetProperty(
2255 global, name, value, attributes, strict_mode_flag);
2256 RETURN_IF_EMPTY_HANDLE(isolate, result);
2257 return *result;
2254 } 2258 }
2255 return isolate->heap()->undefined_value(); 2259 return isolate->heap()->undefined_value();
2256 } 2260 }
2257 2261
2258 2262
2259 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) { 2263 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
2260 SealHandleScope shs(isolate); 2264 SealHandleScope shs(isolate);
2261 // All constants are declared with an initial value. The name 2265 // All constants are declared with an initial value. The name
2262 // of the constant is the first argument and the initial value 2266 // of the constant is the first argument and the initial value
2263 // is the second. 2267 // is the second.
(...skipping 2862 matching lines...) Expand 10 before | Expand all | Expand 10 after
5126 if (object->IsUndefined() || object->IsNull()) { 5130 if (object->IsUndefined() || object->IsNull()) {
5127 Handle<Object> args[2] = { key, object }; 5131 Handle<Object> args[2] = { key, object };
5128 Handle<Object> error = 5132 Handle<Object> error =
5129 isolate->factory()->NewTypeError("non_object_property_store", 5133 isolate->factory()->NewTypeError("non_object_property_store",
5130 HandleVector(args, 2)); 5134 HandleVector(args, 2));
5131 return isolate->Throw(*error); 5135 return isolate->Throw(*error);
5132 } 5136 }
5133 5137
5134 if (object->IsJSProxy()) { 5138 if (object->IsJSProxy()) {
5135 bool has_pending_exception = false; 5139 bool has_pending_exception = false;
5136 Handle<Object> name = key->IsSymbol() 5140 Handle<Object> name_object = key->IsSymbol()
5137 ? key : Execution::ToString(isolate, key, &has_pending_exception); 5141 ? key : Execution::ToString(isolate, key, &has_pending_exception);
5138 if (has_pending_exception) return Failure::Exception(); 5142 if (has_pending_exception) return Failure::Exception();
5139 return JSProxy::cast(*object)->SetProperty( 5143 Handle<Name> name = Handle<Name>::cast(name_object);
5140 Name::cast(*name), *value, attr, strict_mode); 5144 Handle<Object> result = JSReceiver::SetProperty(
5145 Handle<JSProxy>::cast(object), name, value, attr, strict_mode);
5146 RETURN_IF_EMPTY_HANDLE(isolate, result);
5147 return *result;
5141 } 5148 }
5142 5149
5143 // If the object isn't a JavaScript object, we ignore the store. 5150 // If the object isn't a JavaScript object, we ignore the store.
5144 if (!object->IsJSObject()) return *value; 5151 if (!object->IsJSObject()) return *value;
5145 5152
5146 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 5153 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5147 5154
5148 // Check if the given key is an array index. 5155 // Check if the given key is an array index.
5149 uint32_t index; 5156 uint32_t index;
5150 if (key->ToArrayIndex(&index)) { 5157 if (key->ToArrayIndex(&index)) {
(...skipping 19 matching lines...) Expand all
5170 } 5177 }
5171 } 5178 }
5172 MaybeObject* result = js_object->SetElement( 5179 MaybeObject* result = js_object->SetElement(
5173 index, *value, attr, strict_mode, true, set_mode); 5180 index, *value, attr, strict_mode, true, set_mode);
5174 js_object->ValidateElements(); 5181 js_object->ValidateElements();
5175 if (result->IsFailure()) return result; 5182 if (result->IsFailure()) return result;
5176 return *value; 5183 return *value;
5177 } 5184 }
5178 5185
5179 if (key->IsName()) { 5186 if (key->IsName()) {
5180 MaybeObject* result;
5181 Handle<Name> name = Handle<Name>::cast(key); 5187 Handle<Name> name = Handle<Name>::cast(key);
5182 if (name->AsArrayIndex(&index)) { 5188 if (name->AsArrayIndex(&index)) {
5183 if (js_object->HasExternalArrayElements()) { 5189 if (js_object->HasExternalArrayElements()) {
5184 if (!value->IsNumber() && !value->IsUndefined()) { 5190 if (!value->IsNumber() && !value->IsUndefined()) {
5185 bool has_exception; 5191 bool has_exception;
5186 Handle<Object> number = 5192 Handle<Object> number =
5187 Execution::ToNumber(isolate, value, &has_exception); 5193 Execution::ToNumber(isolate, value, &has_exception);
5188 if (has_exception) return Failure::Exception(); 5194 if (has_exception) return Failure::Exception();
5189 value = number; 5195 value = number;
5190 } 5196 }
5191 } 5197 }
5192 result = js_object->SetElement( 5198 MaybeObject* result = js_object->SetElement(
5193 index, *value, attr, strict_mode, true, set_mode); 5199 index, *value, attr, strict_mode, true, set_mode);
5200 if (result->IsFailure()) return result;
5194 } else { 5201 } else {
5195 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5202 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5196 result = js_object->SetProperty(*name, *value, attr, strict_mode); 5203 Handle<Object> result =
5204 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5205 RETURN_IF_EMPTY_HANDLE(isolate, result);
5197 } 5206 }
5198 if (result->IsFailure()) return result;
5199 return *value; 5207 return *value;
5200 } 5208 }
5201 5209
5202 // Call-back into JavaScript to convert the key to a string. 5210 // Call-back into JavaScript to convert the key to a string.
5203 bool has_pending_exception = false; 5211 bool has_pending_exception = false;
5204 Handle<Object> converted = 5212 Handle<Object> converted =
5205 Execution::ToString(isolate, key, &has_pending_exception); 5213 Execution::ToString(isolate, key, &has_pending_exception);
5206 if (has_pending_exception) return Failure::Exception(); 5214 if (has_pending_exception) return Failure::Exception();
5207 Handle<String> name = Handle<String>::cast(converted); 5215 Handle<String> name = Handle<String>::cast(converted);
5208 5216
5209 if (name->AsArrayIndex(&index)) { 5217 if (name->AsArrayIndex(&index)) {
5210 return js_object->SetElement( 5218 return js_object->SetElement(
5211 index, *value, attr, strict_mode, true, set_mode); 5219 index, *value, attr, strict_mode, true, set_mode);
5212 } else { 5220 } else {
5213 return js_object->SetProperty(*name, *value, attr, strict_mode); 5221 Handle<Object> result =
5222 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5223 RETURN_IF_EMPTY_HANDLE(isolate, result);
5224 return *result;
5214 } 5225 }
5215 } 5226 }
5216 5227
5217 5228
5218 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 5229 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
5219 Handle<JSObject> js_object, 5230 Handle<JSObject> js_object,
5220 Handle<Object> key, 5231 Handle<Object> key,
5221 Handle<Object> value, 5232 Handle<Object> value,
5222 PropertyAttributes attr) { 5233 PropertyAttributes attr) {
5223 HandleScope scope(isolate); 5234 HandleScope scope(isolate);
(...skipping 9582 matching lines...) Expand 10 before | Expand all | Expand 10 after
14806 // Handle last resort GC and make sure to allow future allocations 14817 // Handle last resort GC and make sure to allow future allocations
14807 // to grow the heap without causing GCs (if possible). 14818 // to grow the heap without causing GCs (if possible).
14808 isolate->counters()->gc_last_resort_from_js()->Increment(); 14819 isolate->counters()->gc_last_resort_from_js()->Increment();
14809 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14820 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14810 "Runtime::PerformGC"); 14821 "Runtime::PerformGC");
14811 } 14822 }
14812 } 14823 }
14813 14824
14814 14825
14815 } } // namespace v8::internal 14826 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects-inl.h ('k') | src/stub-cache.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698