Chromium Code Reviews| 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> PutOwnElement(Isolate* isolate, | |
|
rossberg
2014/06/13 15:19:24
Nit: SetOwnElement
wingo
2014/06/16 08:32:27
Done.
| |
| 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> PutOwnProperty(Isolate* isolate, | |
|
rossberg
2014/06/13 15:19:24
Nit: SetOwnProperty
wingo
2014/06/16 08:32:27
Done.
| |
| 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 PutOwnElement(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 PutOwnElement(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_PutOwnProperty) { | |
| 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 PutOwnProperty(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 |