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 2162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); | 2173 isolate, NewTypeError("var_redeclaration", HandleVector(args, 1))); |
2174 } | 2174 } |
2175 | 2175 |
2176 | 2176 |
2177 // May throw a RedeclarationError. | 2177 // May throw a RedeclarationError. |
2178 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, | 2178 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, |
2179 Handle<String> name, Handle<Object> value, | 2179 Handle<String> name, Handle<Object> value, |
2180 PropertyAttributes attr, bool is_var, | 2180 PropertyAttributes attr, bool is_var, |
2181 bool is_const, bool is_function) { | 2181 bool is_const, bool is_function) { |
2182 // Do the lookup own properties only, see ES5 erratum. | 2182 // Do the lookup own properties only, see ES5 erratum. |
2183 LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY); | 2183 LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
2184 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2184 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2185 DCHECK(maybe.has_value); | 2185 if (!maybe.has_value) return isolate->heap()->exception(); |
2186 PropertyAttributes old_attributes = maybe.value; | |
2187 | 2186 |
2188 if (old_attributes != ABSENT) { | 2187 if (it.IsFound()) { |
| 2188 PropertyAttributes old_attributes = maybe.value; |
2189 // The name was declared before; check for conflicting re-declarations. | 2189 // The name was declared before; check for conflicting re-declarations. |
2190 if (is_const) return ThrowRedeclarationError(isolate, name); | 2190 if (is_const) return ThrowRedeclarationError(isolate, name); |
2191 | 2191 |
2192 // Skip var re-declarations. | 2192 // Skip var re-declarations. |
2193 if (is_var) return isolate->heap()->undefined_value(); | 2193 if (is_var) return isolate->heap()->undefined_value(); |
2194 | 2194 |
2195 DCHECK(is_function); | 2195 DCHECK(is_function); |
2196 if ((old_attributes & DONT_DELETE) != 0) { | 2196 if ((old_attributes & DONT_DELETE) != 0) { |
2197 // Only allow reconfiguring globals to functions in user code (no | 2197 // Only allow reconfiguring globals to functions in user code (no |
2198 // natives, which are marked as read-only). | 2198 // natives, which are marked as read-only). |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 // All constants are declared with an initial value. The name | 2303 // All constants are declared with an initial value. The name |
2304 // of the constant is the first argument and the initial value | 2304 // of the constant is the first argument and the initial value |
2305 // is the second. | 2305 // is the second. |
2306 RUNTIME_ASSERT(args.length() == 2); | 2306 RUNTIME_ASSERT(args.length() == 2); |
2307 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 2307 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
2308 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 2308 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
2309 | 2309 |
2310 Handle<GlobalObject> global = isolate->global_object(); | 2310 Handle<GlobalObject> global = isolate->global_object(); |
2311 | 2311 |
2312 // Lookup the property as own on the global object. | 2312 // Lookup the property as own on the global object. |
2313 LookupIterator it(global, name, LookupIterator::HIDDEN_PROPERTY); | 2313 LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
2314 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2314 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2315 DCHECK(maybe.has_value); | 2315 DCHECK(maybe.has_value); |
2316 PropertyAttributes old_attributes = maybe.value; | 2316 PropertyAttributes old_attributes = maybe.value; |
2317 | 2317 |
2318 PropertyAttributes attr = | 2318 PropertyAttributes attr = |
2319 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 2319 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
2320 // Set the value if the property is either missing, or the property attributes | 2320 // Set the value if the property is either missing, or the property attributes |
2321 // allow setting the value without invoking an accessor. | 2321 // allow setting the value without invoking an accessor. |
2322 if (it.IsFound()) { | 2322 if (it.IsFound()) { |
2323 // Ignore if we can't reconfigure the value. | 2323 // Ignore if we can't reconfigure the value. |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2453 DCHECK(context_arg->has_extension()); | 2453 DCHECK(context_arg->has_extension()); |
2454 if (attributes == ABSENT) { | 2454 if (attributes == ABSENT) { |
2455 holder = handle(context_arg->extension(), isolate); | 2455 holder = handle(context_arg->extension(), isolate); |
2456 } else { | 2456 } else { |
2457 // For JSContextExtensionObjects, the initializer can be run multiple times | 2457 // For JSContextExtensionObjects, the initializer can be run multiple times |
2458 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the | 2458 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the |
2459 // first assignment should go through. For JSGlobalObjects, additionally any | 2459 // first assignment should go through. For JSGlobalObjects, additionally any |
2460 // code can run in between that modifies the declared property. | 2460 // code can run in between that modifies the declared property. |
2461 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); | 2461 DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); |
2462 | 2462 |
2463 LookupIterator it(holder, name, LookupIterator::HIDDEN_PROPERTY); | 2463 LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR); |
2464 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 2464 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
2465 if (!maybe.has_value) return isolate->heap()->exception(); | 2465 if (!maybe.has_value) return isolate->heap()->exception(); |
2466 PropertyAttributes old_attributes = maybe.value; | 2466 PropertyAttributes old_attributes = maybe.value; |
2467 | 2467 |
2468 // Ignore if we can't reconfigure the value. | 2468 // Ignore if we can't reconfigure the value. |
2469 if ((old_attributes & DONT_DELETE) != 0) { | 2469 if ((old_attributes & DONT_DELETE) != 0) { |
2470 if ((old_attributes & READ_ONLY) != 0 || | 2470 if ((old_attributes & READ_ONLY) != 0 || |
2471 it.property_kind() == LookupIterator::ACCESSOR) { | 2471 it.property_kind() == LookupIterator::ACCESSOR) { |
2472 return *value; | 2472 return *value; |
2473 } | 2473 } |
(...skipping 2559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5033 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) { | 5033 RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) { |
5034 HandleScope scope(isolate); | 5034 HandleScope scope(isolate); |
5035 DCHECK(args.length() == 4); | 5035 DCHECK(args.length() == 4); |
5036 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); | 5036 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); |
5037 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); | 5037 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); |
5038 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); | 5038 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); |
5039 CONVERT_SMI_ARG_CHECKED(unchecked, 3); | 5039 CONVERT_SMI_ARG_CHECKED(unchecked, 3); |
5040 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5040 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5041 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 5041 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
5042 | 5042 |
5043 // Check access rights if needed. | 5043 LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
5044 if (js_object->IsAccessCheckNeeded() && | 5044 if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) { |
5045 !isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { | 5045 if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) { |
5046 return isolate->heap()->undefined_value(); | 5046 return isolate->heap()->undefined_value(); |
| 5047 } |
| 5048 it.Next(); |
5047 } | 5049 } |
5048 | 5050 |
5049 LookupIterator it(js_object, name, LookupIterator::OWN_PROPERTY); | |
5050 | |
5051 // Take special care when attributes are different and there is already | 5051 // Take special care when attributes are different and there is already |
5052 // a property. | 5052 // a property. |
5053 if (it.IsFound() && it.HasProperty() && | 5053 if (it.IsFound() && it.HasProperty() && |
5054 it.property_kind() == LookupIterator::ACCESSOR) { | 5054 it.property_kind() == LookupIterator::ACCESSOR) { |
5055 // Use IgnoreAttributes version since a readonly property may be | 5055 // Use IgnoreAttributes version since a readonly property may be |
5056 // overridden and SetProperty does not allow this. | 5056 // overridden and SetProperty does not allow this. |
5057 Handle<Object> result; | 5057 Handle<Object> result; |
5058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5058 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5059 isolate, result, | 5059 isolate, result, |
5060 JSObject::SetOwnPropertyIgnoreAttributes( | 5060 JSObject::SetOwnPropertyIgnoreAttributes( |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5286 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); | 5286 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); |
5287 RUNTIME_ASSERT( | 5287 RUNTIME_ASSERT( |
5288 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5288 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5289 // Compute attributes. | 5289 // Compute attributes. |
5290 PropertyAttributes attributes = | 5290 PropertyAttributes attributes = |
5291 static_cast<PropertyAttributes>(unchecked_attributes); | 5291 static_cast<PropertyAttributes>(unchecked_attributes); |
5292 | 5292 |
5293 #ifdef DEBUG | 5293 #ifdef DEBUG |
5294 uint32_t index = 0; | 5294 uint32_t index = 0; |
5295 DCHECK(!key->ToArrayIndex(&index)); | 5295 DCHECK(!key->ToArrayIndex(&index)); |
5296 LookupIterator it(object, key, LookupIterator::OWN_PROPERTY); | 5296 LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR); |
5297 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 5297 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
5298 DCHECK(maybe.has_value); | 5298 if (!maybe.has_value) return isolate->heap()->exception(); |
5299 RUNTIME_ASSERT(!it.IsFound()); | 5299 RUNTIME_ASSERT(!it.IsFound()); |
5300 #endif | 5300 #endif |
5301 | 5301 |
5302 Handle<Object> result; | 5302 Handle<Object> result; |
5303 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 5303 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
5304 isolate, result, | 5304 isolate, result, |
5305 JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes)); | 5305 JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes)); |
5306 return *result; | 5306 return *result; |
5307 } | 5307 } |
5308 | 5308 |
5309 | 5309 |
5310 RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) { | 5310 RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) { |
5311 HandleScope scope(isolate); | 5311 HandleScope scope(isolate); |
5312 RUNTIME_ASSERT(args.length() == 4); | 5312 RUNTIME_ASSERT(args.length() == 4); |
5313 | 5313 |
5314 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 5314 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
5315 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); | 5315 CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); |
5316 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); | 5316 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
5317 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); | 5317 CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3); |
5318 RUNTIME_ASSERT( | 5318 RUNTIME_ASSERT( |
5319 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 5319 (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
5320 // Compute attributes. | 5320 // Compute attributes. |
5321 PropertyAttributes attributes = | 5321 PropertyAttributes attributes = |
5322 static_cast<PropertyAttributes>(unchecked_attributes); | 5322 static_cast<PropertyAttributes>(unchecked_attributes); |
5323 | 5323 |
5324 #ifdef DEBUG | 5324 #ifdef DEBUG |
5325 bool duplicate; | 5325 bool duplicate; |
5326 if (key->IsName()) { | 5326 if (key->IsName()) { |
5327 LookupIterator it(object, Handle<Name>::cast(key), | 5327 LookupIterator it(object, Handle<Name>::cast(key), |
5328 LookupIterator::OWN_PROPERTY); | 5328 LookupIterator::OWN_SKIP_INTERCEPTOR); |
5329 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 5329 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
5330 DCHECK(maybe.has_value); | 5330 DCHECK(maybe.has_value); |
5331 duplicate = it.IsFound(); | 5331 duplicate = it.IsFound(); |
5332 } else { | 5332 } else { |
5333 uint32_t index = 0; | 5333 uint32_t index = 0; |
5334 RUNTIME_ASSERT(key->ToArrayIndex(&index)); | 5334 RUNTIME_ASSERT(key->ToArrayIndex(&index)); |
5335 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); | 5335 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index); |
5336 if (!maybe.has_value) return isolate->heap()->exception(); | 5336 if (!maybe.has_value) return isolate->heap()->exception(); |
5337 duplicate = maybe.value; | 5337 duplicate = maybe.value; |
5338 } | 5338 } |
(...skipping 10318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15657 } | 15657 } |
15658 return NULL; | 15658 return NULL; |
15659 } | 15659 } |
15660 | 15660 |
15661 | 15661 |
15662 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { | 15662 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { |
15663 return &(kIntrinsicFunctions[static_cast<int>(id)]); | 15663 return &(kIntrinsicFunctions[static_cast<int>(id)]); |
15664 } | 15664 } |
15665 | 15665 |
15666 } } // namespace v8::internal | 15666 } } // namespace v8::internal |
OLD | NEW |