OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |