OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 #include <limits> | 6 #include <limits> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 ASSERT(index == number_of_string_keys); | 193 ASSERT(index == number_of_string_keys); |
194 } | 194 } |
195 *is_result_from_cache = true; | 195 *is_result_from_cache = true; |
196 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); | 196 return isolate->factory()->ObjectLiteralMapFromCache(context, keys); |
197 } | 197 } |
198 *is_result_from_cache = false; | 198 *is_result_from_cache = false; |
199 return Map::Create(handle(context->object_function()), number_of_properties); | 199 return Map::Create(handle(context->object_function()), number_of_properties); |
200 } | 200 } |
201 | 201 |
202 | 202 |
| 203 MUST_USE_RESULT static MaybeHandle<Object> DefineOrRedefineDataProperty( |
| 204 Isolate* isolate, |
| 205 Handle<JSObject> object, |
| 206 Handle<Name> name, |
| 207 Handle<Object> value, |
| 208 PropertyAttributes attr); |
| 209 |
| 210 |
203 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( | 211 MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( |
204 Isolate* isolate, | 212 Isolate* isolate, |
205 Handle<FixedArray> literals, | 213 Handle<FixedArray> literals, |
206 Handle<FixedArray> constant_properties); | 214 Handle<FixedArray> constant_properties); |
207 | 215 |
208 | 216 |
209 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( | 217 MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( |
210 Isolate* isolate, | 218 Isolate* isolate, |
211 Handle<FixedArray> literals, | 219 Handle<FixedArray> literals, |
212 Handle<FixedArray> constant_properties, | 220 Handle<FixedArray> constant_properties, |
(...skipping 4949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5162 | 5170 |
5163 bool fast = obj->HasFastProperties(); | 5171 bool fast = obj->HasFastProperties(); |
5164 // DefineAccessor checks access rights. | 5172 // DefineAccessor checks access rights. |
5165 JSObject::DefineAccessor(obj, name, getter, setter, attr); | 5173 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
5166 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 5174 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
5167 if (fast) JSObject::TransformToFastProperties(obj, 0); | 5175 if (fast) JSObject::TransformToFastProperties(obj, 0); |
5168 return isolate->heap()->undefined_value(); | 5176 return isolate->heap()->undefined_value(); |
5169 } | 5177 } |
5170 | 5178 |
5171 | 5179 |
5172 // Implements part of 8.12.9 DefineOwnProperty. | 5180 static MaybeHandle<Object> DefineOrRedefineDataProperty( |
5173 // There are 3 cases that lead here: | 5181 Isolate* isolate, |
5174 // Step 4a - define a new data property. | 5182 Handle<JSObject> js_object, |
5175 // Steps 9b & 12 - replace an existing accessor property with a data property. | 5183 Handle<Name> name, |
5176 // Step 12 - update an existing data property with a data or generic | 5184 Handle<Object> obj_value, |
5177 // descriptor. | 5185 PropertyAttributes attr) { |
5178 RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) { | |
5179 HandleScope scope(isolate); | |
5180 ASSERT(args.length() == 4); | |
5181 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); | |
5182 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | |
5183 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); | |
5184 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | |
5185 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | |
5186 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | |
5187 | |
5188 // Check access rights if needed. | |
5189 if (js_object->IsAccessCheckNeeded() && | |
5190 !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { | |
5191 return isolate->heap()->undefined_value(); | |
5192 } | |
5193 | |
5194 LookupResult lookup(isolate); | 5186 LookupResult lookup(isolate); |
5195 js_object->LookupOwnRealNamedProperty(name, &lookup); | 5187 js_object->LookupOwnRealNamedProperty(name, &lookup); |
5196 | 5188 |
5197 // Take special care when attributes are different and there is already | 5189 // Take special care when attributes are different and there is already |
5198 // a property. For simplicity we normalize the property which enables us | 5190 // a property. For simplicity we normalize the property which enables us |
5199 // to not worry about changing the instance_descriptor and creating a new | 5191 // to not worry about changing the instance_descriptor and creating a new |
5200 // map. The current version of SetObjectProperty does not handle attributes | 5192 // map. The current version of SetObjectProperty does not handle attributes |
5201 // correctly in the case where a property is a field and is reset with | 5193 // correctly in the case where a property is a field and is reset with |
5202 // new attributes. | 5194 // new attributes. |
5203 if (lookup.IsFound() && | 5195 if (lookup.IsFound() && |
5204 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { | 5196 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) { |
5205 // New attributes - normalize to avoid writing to instance descriptor | 5197 // New attributes - normalize to avoid writing to instance descriptor |
5206 if (js_object->IsJSGlobalProxy()) { | 5198 if (js_object->IsJSGlobalProxy()) { |
5207 // Since the result is a property, the prototype will exist so | 5199 // Since the result is a property, the prototype will exist so |
5208 // we don't have to check for null. | 5200 // we don't have to check for null. |
5209 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 5201 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
5210 } | 5202 } |
5211 | 5203 |
5212 if (attr != lookup.GetAttributes() || | 5204 if (attr != lookup.GetAttributes() || |
5213 (lookup.IsPropertyCallbacks() && | 5205 (lookup.IsPropertyCallbacks() && |
5214 !lookup.GetCallbackObject()->IsAccessorInfo())) { | 5206 !lookup.GetCallbackObject()->IsAccessorInfo())) { |
5215 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 5207 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
5216 } | 5208 } |
5217 | 5209 |
5218 // Use IgnoreAttributes version since a readonly property may be | 5210 // Use IgnoreAttributes version since a readonly property may be |
5219 // overridden and SetProperty does not allow this. | 5211 // overridden and SetProperty does not allow this. |
5220 Handle<Object> result; | 5212 return JSObject::SetOwnPropertyIgnoreAttributes( |
5221 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5213 js_object, name, obj_value, attr, |
5222 isolate, result, | 5214 Object::OPTIMAL_REPRESENTATION, |
5223 JSObject::SetOwnPropertyIgnoreAttributes( | 5215 ALLOW_AS_CONSTANT, |
5224 js_object, name, obj_value, attr, | 5216 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, |
5225 Object::OPTIMAL_REPRESENTATION, | 5217 JSReceiver::MAY_BE_STORE_FROM_KEYED, |
5226 ALLOW_AS_CONSTANT, | 5218 JSObject::DONT_FORCE_FIELD); |
5227 JSReceiver::PERFORM_EXTENSIBILITY_CHECK, | 5219 } |
5228 JSReceiver::MAY_BE_STORE_FROM_KEYED, | 5220 |
5229 JSObject::DONT_FORCE_FIELD)); | 5221 return Runtime::ForceSetObjectProperty( |
5230 return *result; | 5222 js_object, name, obj_value, attr, |
| 5223 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); |
| 5224 } |
| 5225 |
| 5226 |
| 5227 // Implements part of 8.12.9 DefineOwnProperty. |
| 5228 // There are 3 cases that lead here: |
| 5229 // Step 4a - define a new data property. |
| 5230 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 5231 // Step 12 - update an existing data property with a data or generic |
| 5232 // descriptor. |
| 5233 RUNTIME_FUNCTION(Runtime_DefineOrRedefineDataProperty) { |
| 5234 HandleScope scope(isolate); |
| 5235 ASSERT(args.length() == 4); |
| 5236 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
| 5237 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
| 5238 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
| 5239 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
| 5240 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
| 5241 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
| 5242 |
| 5243 // Check access rights if needed. |
| 5244 if (js_object->IsAccessCheckNeeded() && |
| 5245 !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
| 5246 return isolate->heap()->undefined_value(); |
5231 } | 5247 } |
5232 | 5248 |
5233 Handle<Object> result; | 5249 Handle<Object> result; |
5234 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5250 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
5235 isolate, result, | 5251 DefineOrRedefineDataProperty(isolate, js_object, name, obj_value, attr)); |
5236 Runtime::ForceSetObjectProperty( | |
5237 js_object, name, obj_value, attr, | |
5238 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED)); | |
5239 return *result; | 5252 return *result; |
5240 } | 5253 } |
5241 | 5254 |
5242 | 5255 |
5243 // Return property without being observable by accessors or interceptors. | 5256 // Return property without being observable by accessors or interceptors. |
5244 RUNTIME_FUNCTION(Runtime_GetDataProperty) { | 5257 RUNTIME_FUNCTION(Runtime_GetDataProperty) { |
5245 HandleScope scope(isolate); | 5258 HandleScope scope(isolate); |
5246 ASSERT(args.length() == 2); | 5259 ASSERT(args.length() == 2); |
5247 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5260 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
5248 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); | 5261 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5474 | 5487 |
5475 Handle<Object> result; | 5488 Handle<Object> result; |
5476 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5489 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5477 isolate, result, | 5490 isolate, result, |
5478 Runtime::SetObjectProperty( | 5491 Runtime::SetObjectProperty( |
5479 isolate, object, key, value, attributes, strict_mode)); | 5492 isolate, object, key, value, attributes, strict_mode)); |
5480 return *result; | 5493 return *result; |
5481 } | 5494 } |
5482 | 5495 |
5483 | 5496 |
| 5497 // This function is only used on object literals. |
| 5498 static MaybeHandle<Object> SetOwnElement(Isolate* isolate, |
| 5499 Handle<JSObject> object, |
| 5500 uint32_t index, |
| 5501 Handle<Object> value) { |
| 5502 StrictMode strict_mode = SLOPPY; |
| 5503 |
| 5504 JSObject::ValidateElements(object); |
| 5505 |
| 5506 // Object literals don't have these. |
| 5507 ASSERT(!object->HasExternalArrayElements()); |
| 5508 ASSERT(!object->HasFixedTypedArrayElements()); |
| 5509 |
| 5510 // It is currently impossible for an object literal to have a getter or a |
| 5511 // setter for an element, though this may change when we have computed |
| 5512 // accessor property names. |
| 5513 MaybeHandle<Object> result = JSObject::SetOwnElement( |
| 5514 object, index, value, strict_mode); |
| 5515 JSObject::ValidateElements(object); |
| 5516 |
| 5517 return result.is_null() ? result : value; |
| 5518 } |
| 5519 |
| 5520 |
| 5521 static MaybeHandle<Object> SetOwnProperty(Isolate* isolate, |
| 5522 Handle<JSObject> object, |
| 5523 Handle<Object> key, |
| 5524 Handle<Object> value) { |
| 5525 PropertyAttributes attr = NONE; |
| 5526 |
| 5527 // Check if the given key is an array index. |
| 5528 uint32_t index; |
| 5529 if (key->ToArrayIndex(&index)) { |
| 5530 return SetOwnElement(isolate, object, index, value); |
| 5531 } |
| 5532 |
| 5533 if (!key->IsName()) { |
| 5534 // Call back into JavaScript to convert the key to a string. |
| 5535 ASSIGN_RETURN_ON_EXCEPTION( |
| 5536 isolate, key, Execution::ToString(isolate, key), Object); |
| 5537 } |
| 5538 |
| 5539 Handle<Name> name = Handle<Name>::cast(key); |
| 5540 if (name->AsArrayIndex(&index)) { |
| 5541 return SetOwnElement(isolate, object, index, value); |
| 5542 } |
| 5543 |
| 5544 return DefineOrRedefineDataProperty(isolate, object, name, value, attr); |
| 5545 } |
| 5546 |
| 5547 |
| 5548 // Used to initialize data properties on object literals. We know that the |
| 5549 // attributes will be NONE. |
| 5550 RUNTIME_FUNCTION(Runtime_SetOwnProperty) { |
| 5551 HandleScope scope(isolate); |
| 5552 RUNTIME_ASSERT(args.length() == 3); |
| 5553 |
| 5554 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
| 5555 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
| 5556 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
| 5557 |
| 5558 Handle<Object> result; |
| 5559 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 5560 SetOwnProperty(isolate, object, key, value)); |
| 5561 return *result; |
| 5562 } |
| 5563 |
| 5564 |
5484 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { | 5565 RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { |
5485 HandleScope scope(isolate); | 5566 HandleScope scope(isolate); |
5486 RUNTIME_ASSERT(args.length() == 2); | 5567 RUNTIME_ASSERT(args.length() == 2); |
5487 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); | 5568 CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0); |
5488 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); | 5569 CONVERT_ARG_HANDLE_CHECKED(Map, map, 1); |
5489 JSObject::TransitionElementsKind(array, map->elements_kind()); | 5570 JSObject::TransitionElementsKind(array, map->elements_kind()); |
5490 return *array; | 5571 return *array; |
5491 } | 5572 } |
5492 | 5573 |
5493 | 5574 |
(...skipping 9650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15144 } | 15225 } |
15145 return NULL; | 15226 return NULL; |
15146 } | 15227 } |
15147 | 15228 |
15148 | 15229 |
15149 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15230 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15150 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15231 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15151 } | 15232 } |
15152 | 15233 |
15153 } } // namespace v8::internal | 15234 } } // namespace v8::internal |
OLD | NEW |