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

Side by Side Diff: src/runtime.cc

Issue 418383002: Change Has* and Get*Attributes to return Maybe<*>, indicating possible exceptions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 5 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
OLDNEW
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 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after
1939 Factory* factory = isolate->factory(); 1939 Factory* factory = isolate->factory();
1940 1940
1941 PropertyAttributes attrs; 1941 PropertyAttributes attrs;
1942 uint32_t index = 0; 1942 uint32_t index = 0;
1943 Handle<Object> value; 1943 Handle<Object> value;
1944 MaybeHandle<AccessorPair> maybe_accessors; 1944 MaybeHandle<AccessorPair> maybe_accessors;
1945 // TODO(verwaest): Unify once indexed properties can be handled by the 1945 // TODO(verwaest): Unify once indexed properties can be handled by the
1946 // LookupIterator. 1946 // LookupIterator.
1947 if (name->AsArrayIndex(&index)) { 1947 if (name->AsArrayIndex(&index)) {
1948 // Get attributes. 1948 // Get attributes.
1949 attrs = JSReceiver::GetOwnElementAttribute(obj, index); 1949 Maybe<PropertyAttributes> maybe =
1950 if (attrs == ABSENT) { 1950 JSReceiver::GetOwnElementAttribute(obj, index);
1951 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 1951 if (!maybe.has_value) return MaybeHandle<Object>();
1952 return factory->undefined_value(); 1952 attrs = maybe.value;
1953 } 1953 if (attrs == ABSENT) return factory->undefined_value();
1954 1954
1955 // Get AccessorPair if present. 1955 // Get AccessorPair if present.
1956 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index); 1956 maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
1957 1957
1958 // Get value if not an AccessorPair. 1958 // Get value if not an AccessorPair.
1959 if (maybe_accessors.is_null()) { 1959 if (maybe_accessors.is_null()) {
1960 ASSIGN_RETURN_ON_EXCEPTION(isolate, value, 1960 ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
1961 Runtime::GetElementOrCharAt(isolate, obj, index), Object); 1961 Runtime::GetElementOrCharAt(isolate, obj, index), Object);
1962 } 1962 }
1963 } else { 1963 } else {
1964 // Get attributes. 1964 // Get attributes.
1965 LookupIterator it(obj, name, LookupIterator::CHECK_OWN); 1965 LookupIterator it(obj, name, LookupIterator::CHECK_OWN);
1966 attrs = JSObject::GetPropertyAttributes(&it); 1966 Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
1967 if (attrs == ABSENT) { 1967 if (!maybe.has_value) return MaybeHandle<Object>();
1968 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 1968 attrs = maybe.value;
1969 return factory->undefined_value(); 1969 if (attrs == ABSENT) return factory->undefined_value();
1970 }
1971 1970
1972 // Get AccessorPair if present. 1971 // Get AccessorPair if present.
1973 if (it.state() == LookupIterator::PROPERTY && 1972 if (it.state() == LookupIterator::PROPERTY &&
1974 it.property_kind() == LookupIterator::ACCESSOR && 1973 it.property_kind() == LookupIterator::ACCESSOR &&
1975 it.GetAccessors()->IsAccessorPair()) { 1974 it.GetAccessors()->IsAccessorPair()) {
1976 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors()); 1975 maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
1977 } 1976 }
1978 1977
1979 // Get value if not an AccessorPair. 1978 // Get value if not an AccessorPair.
1980 if (maybe_accessors.is_null()) { 1979 if (maybe_accessors.is_null()) {
1981 ASSIGN_RETURN_ON_EXCEPTION( 1980 ASSIGN_RETURN_ON_EXCEPTION(
1982 isolate, value, Object::GetProperty(&it), Object); 1981 isolate, value, Object::GetProperty(&it), Object);
1983 } 1982 }
1984 } 1983 }
1985 ASSERT(!isolate->has_scheduled_exception()); 1984 ASSERT(!isolate->has_pending_exception());
1986 Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE); 1985 Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
1987 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0)); 1986 elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
1988 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0)); 1987 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
1989 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null())); 1988 elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
1990 1989
1991 Handle<AccessorPair> accessors; 1990 Handle<AccessorPair> accessors;
1992 if (maybe_accessors.ToHandle(&accessors)) { 1991 if (maybe_accessors.ToHandle(&accessors)) {
1993 Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate); 1992 Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
1994 Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate); 1993 Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
1995 elms->set(GETTER_INDEX, *getter); 1994 elms->set(GETTER_INDEX, *getter);
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2136 } 2135 }
2137 2136
2138 2137
2139 // May throw a RedeclarationError. 2138 // May throw a RedeclarationError.
2140 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global, 2139 static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
2141 Handle<String> name, Handle<Object> value, 2140 Handle<String> name, Handle<Object> value,
2142 PropertyAttributes attr, bool is_var, 2141 PropertyAttributes attr, bool is_var,
2143 bool is_const, bool is_function) { 2142 bool is_const, bool is_function) {
2144 // Do the lookup own properties only, see ES5 erratum. 2143 // Do the lookup own properties only, see ES5 erratum.
2145 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN); 2144 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
2146 PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it); 2145 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2146 ASSERT(maybe.has_value);
2147 PropertyAttributes old_attributes = maybe.value;
2147 2148
2148 if (old_attributes != ABSENT) { 2149 if (old_attributes != ABSENT) {
2149 // The name was declared before; check for conflicting re-declarations. 2150 // The name was declared before; check for conflicting re-declarations.
2150 if (is_const) return ThrowRedeclarationError(isolate, name); 2151 if (is_const) return ThrowRedeclarationError(isolate, name);
2151 2152
2152 // Skip var re-declarations. 2153 // Skip var re-declarations.
2153 if (is_var) return isolate->heap()->undefined_value(); 2154 if (is_var) return isolate->heap()->undefined_value();
2154 2155
2155 ASSERT(is_function); 2156 ASSERT(is_function);
2156 if ((old_attributes & DONT_DELETE) != 0) { 2157 if ((old_attributes & DONT_DELETE) != 0) {
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 // of the constant is the first argument and the initial value 2265 // of the constant is the first argument and the initial value
2265 // is the second. 2266 // is the second.
2266 RUNTIME_ASSERT(args.length() == 2); 2267 RUNTIME_ASSERT(args.length() == 2);
2267 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 2268 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2268 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 2269 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
2269 2270
2270 Handle<GlobalObject> global = isolate->global_object(); 2271 Handle<GlobalObject> global = isolate->global_object();
2271 2272
2272 // Lookup the property as own on the global object. 2273 // Lookup the property as own on the global object.
2273 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN); 2274 LookupIterator it(global, name, LookupIterator::CHECK_HIDDEN);
2274 PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it); 2275 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2276 ASSERT(maybe.has_value);
2277 PropertyAttributes old_attributes = maybe.value;
2275 2278
2276 PropertyAttributes attr = 2279 PropertyAttributes attr =
2277 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); 2280 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
2278 // Set the value if the property is either missing, or the property attributes 2281 // Set the value if the property is either missing, or the property attributes
2279 // allow setting the value without invoking an accessor. 2282 // allow setting the value without invoking an accessor.
2280 if (it.IsFound()) { 2283 if (it.IsFound()) {
2281 // Ignore if we can't reconfigure the value. 2284 // Ignore if we can't reconfigure the value.
2282 if ((old_attributes & DONT_DELETE) != 0) { 2285 if ((old_attributes & DONT_DELETE) != 0) {
2283 if ((old_attributes & READ_ONLY) != 0 || 2286 if ((old_attributes & READ_ONLY) != 0 ||
2284 it.property_kind() == LookupIterator::ACCESSOR) { 2287 it.property_kind() == LookupIterator::ACCESSOR) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2412 if (attributes == ABSENT) { 2415 if (attributes == ABSENT) {
2413 holder = handle(context_arg->extension(), isolate); 2416 holder = handle(context_arg->extension(), isolate);
2414 } else { 2417 } else {
2415 // For JSContextExtensionObjects, the initializer can be run multiple times 2418 // For JSContextExtensionObjects, the initializer can be run multiple times
2416 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the 2419 // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
2417 // first assignment should go through. For JSGlobalObjects, additionally any 2420 // first assignment should go through. For JSGlobalObjects, additionally any
2418 // code can run in between that modifies the declared property. 2421 // code can run in between that modifies the declared property.
2419 ASSERT(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject()); 2422 ASSERT(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
2420 2423
2421 LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN); 2424 LookupIterator it(holder, name, LookupIterator::CHECK_HIDDEN);
2422 PropertyAttributes old_attributes = JSReceiver::GetPropertyAttributes(&it); 2425 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
2426 if (!maybe.has_value) return isolate->heap()->exception();
2427 PropertyAttributes old_attributes = maybe.value;
2423 2428
2424 // Ignore if we can't reconfigure the value. 2429 // Ignore if we can't reconfigure the value.
2425 if ((old_attributes & DONT_DELETE) != 0) { 2430 if ((old_attributes & DONT_DELETE) != 0) {
2426 if ((old_attributes & READ_ONLY) != 0 || 2431 if ((old_attributes & READ_ONLY) != 0 ||
2427 it.property_kind() == LookupIterator::ACCESSOR) { 2432 it.property_kind() == LookupIterator::ACCESSOR) {
2428 return *value; 2433 return *value;
2429 } 2434 }
2430 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY); 2435 attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
2431 } 2436 }
2432 } 2437 }
(...skipping 2307 matching lines...) Expand 10 before | Expand all | Expand 10 after
4740 ASSIGN_RETURN_ON_EXCEPTION( 4745 ASSIGN_RETURN_ON_EXCEPTION(
4741 isolate, converted, Execution::ToString(isolate, key), Name); 4746 isolate, converted, Execution::ToString(isolate, key), Name);
4742 return Handle<Name>::cast(converted); 4747 return Handle<Name>::cast(converted);
4743 } 4748 }
4744 } 4749 }
4745 4750
4746 4751
4747 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate, 4752 MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
4748 Handle<JSReceiver> object, 4753 Handle<JSReceiver> object,
4749 Handle<Object> key) { 4754 Handle<Object> key) {
4755 Maybe<bool> maybe;
4750 // Check if the given key is an array index. 4756 // Check if the given key is an array index.
4751 uint32_t index; 4757 uint32_t index;
4752 if (key->ToArrayIndex(&index)) { 4758 if (key->ToArrayIndex(&index)) {
4753 return isolate->factory()->ToBoolean(JSReceiver::HasElement(object, index)); 4759 maybe = JSReceiver::HasElement(object, index);
4760 } else {
4761 // Convert the key to a name - possibly by calling back into JavaScript.
4762 Handle<Name> name;
4763 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4764
4765 maybe = JSReceiver::HasProperty(object, name);
4754 } 4766 }
4755 4767
4756 // Convert the key to a name - possibly by calling back into JavaScript. 4768 if (!maybe.has_value) return MaybeHandle<Object>();
4757 Handle<Name> name; 4769 return isolate->factory()->ToBoolean(maybe.value);
4758 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
4759
4760 return isolate->factory()->ToBoolean(JSReceiver::HasProperty(object, name));
4761 } 4770 }
4762 4771
4763 4772
4764 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate, 4773 MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
4765 Handle<Object> object, 4774 Handle<Object> object,
4766 Handle<Object> key) { 4775 Handle<Object> key) {
4767 if (object->IsUndefined() || object->IsNull()) { 4776 if (object->IsUndefined() || object->IsNull()) {
4768 Handle<Object> args[2] = { key, object }; 4777 Handle<Object> args[2] = { key, object };
4769 return isolate->Throw<Object>( 4778 return isolate->Throw<Object>(
4770 isolate->factory()->NewTypeError("non_object_property_load", 4779 isolate->factory()->NewTypeError("non_object_property_load",
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
4932 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 4941 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
4933 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); 4942 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4934 RUNTIME_ASSERT(IsValidAccessor(getter)); 4943 RUNTIME_ASSERT(IsValidAccessor(getter));
4935 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); 4944 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4936 RUNTIME_ASSERT(IsValidAccessor(setter)); 4945 RUNTIME_ASSERT(IsValidAccessor(setter));
4937 CONVERT_SMI_ARG_CHECKED(unchecked, 4); 4946 CONVERT_SMI_ARG_CHECKED(unchecked, 4);
4938 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4947 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4939 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4948 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4940 4949
4941 bool fast = obj->HasFastProperties(); 4950 bool fast = obj->HasFastProperties();
4942 // DefineAccessor checks access rights. 4951 RETURN_FAILURE_ON_EXCEPTION(
4943 JSObject::DefineAccessor(obj, name, getter, setter, attr); 4952 isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
4944 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
4945 if (fast) JSObject::MigrateSlowToFast(obj, 0); 4953 if (fast) JSObject::MigrateSlowToFast(obj, 0);
4946 return isolate->heap()->undefined_value(); 4954 return isolate->heap()->undefined_value();
4947 } 4955 }
4948 4956
4949 4957
4950 // Implements part of 8.12.9 DefineOwnProperty. 4958 // Implements part of 8.12.9 DefineOwnProperty.
4951 // There are 3 cases that lead here: 4959 // There are 3 cases that lead here:
4952 // Step 4a - define a new data property. 4960 // Step 4a - define a new data property.
4953 // Steps 9b & 12 - replace an existing accessor property with a data property. 4961 // Steps 9b & 12 - replace an existing accessor property with a data property.
4954 // Step 12 - update an existing data property with a data or generic 4962 // Step 12 - update an existing data property with a data or generic
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
5272 #ifdef DEBUG 5280 #ifdef DEBUG
5273 bool duplicate; 5281 bool duplicate;
5274 if (key->IsName()) { 5282 if (key->IsName()) {
5275 LookupIterator it(object, Handle<Name>::cast(key), 5283 LookupIterator it(object, Handle<Name>::cast(key),
5276 LookupIterator::CHECK_OWN_REAL); 5284 LookupIterator::CHECK_OWN_REAL);
5277 JSReceiver::GetPropertyAttributes(&it); 5285 JSReceiver::GetPropertyAttributes(&it);
5278 duplicate = it.IsFound(); 5286 duplicate = it.IsFound();
5279 } else { 5287 } else {
5280 uint32_t index = 0; 5288 uint32_t index = 0;
5281 RUNTIME_ASSERT(key->ToArrayIndex(&index)); 5289 RUNTIME_ASSERT(key->ToArrayIndex(&index));
5282 duplicate = JSReceiver::HasOwnElement(object, index); 5290 Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
5291 if (!maybe.has_value) return isolate->heap()->exception();
5292 duplicate = maybe.value;
5283 } 5293 }
5284 if (duplicate) { 5294 if (duplicate) {
5285 Handle<Object> args[1] = { key }; 5295 Handle<Object> args[1] = { key };
5286 Handle<Object> error = isolate->factory()->NewTypeError( 5296 Handle<Object> error = isolate->factory()->NewTypeError(
5287 "duplicate_template_property", HandleVector(args, 1)); 5297 "duplicate_template_property", HandleVector(args, 1));
5288 return isolate->Throw(*error); 5298 return isolate->Throw(*error);
5289 } 5299 }
5290 #endif 5300 #endif
5291 5301
5292 Handle<Object> result; 5302 Handle<Object> result;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
5494 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 5504 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
5495 isolate, result, 5505 isolate, result,
5496 JSReceiver::DeleteProperty(object, key, delete_mode)); 5506 JSReceiver::DeleteProperty(object, key, delete_mode));
5497 return *result; 5507 return *result;
5498 } 5508 }
5499 5509
5500 5510
5501 static Object* HasOwnPropertyImplementation(Isolate* isolate, 5511 static Object* HasOwnPropertyImplementation(Isolate* isolate,
5502 Handle<JSObject> object, 5512 Handle<JSObject> object,
5503 Handle<Name> key) { 5513 Handle<Name> key) {
5504 if (JSReceiver::HasOwnProperty(object, key)) { 5514 Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
5505 return isolate->heap()->true_value(); 5515 if (!maybe.has_value) return isolate->heap()->exception();
5506 } 5516 if (maybe.value) return isolate->heap()->true_value();
5507 // Handle hidden prototypes. If there's a hidden prototype above this thing 5517 // Handle hidden prototypes. If there's a hidden prototype above this thing
5508 // then we have to check it for properties, because they are supposed to 5518 // then we have to check it for properties, because they are supposed to
5509 // look like they are on this object. 5519 // look like they are on this object.
5510 PrototypeIterator iter(isolate, object); 5520 PrototypeIterator iter(isolate, object);
5511 if (!iter.IsAtEnd() && 5521 if (!iter.IsAtEnd() &&
5512 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)) 5522 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
5513 ->map() 5523 ->map()
5514 ->is_hidden_prototype()) { 5524 ->is_hidden_prototype()) {
5515 // TODO(verwaest): The recursion is not necessary for keys that are array 5525 // TODO(verwaest): The recursion is not necessary for keys that are array
5516 // indicies. Removing this. 5526 // indicies. Removing this.
(...skipping 14 matching lines...) Expand all
5531 5541
5532 uint32_t index; 5542 uint32_t index;
5533 const bool key_is_array_index = key->AsArrayIndex(&index); 5543 const bool key_is_array_index = key->AsArrayIndex(&index);
5534 5544
5535 // Only JS objects can have properties. 5545 // Only JS objects can have properties.
5536 if (object->IsJSObject()) { 5546 if (object->IsJSObject()) {
5537 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); 5547 Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
5538 // Fast case: either the key is a real named property or it is not 5548 // Fast case: either the key is a real named property or it is not
5539 // an array index and there are no interceptors or hidden 5549 // an array index and there are no interceptors or hidden
5540 // prototypes. 5550 // prototypes.
5541 if (JSObject::HasRealNamedProperty(js_obj, key)) { 5551 Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
5542 ASSERT(!isolate->has_scheduled_exception()); 5552 if (!maybe.has_value) return isolate->heap()->exception();
5553 ASSERT(!isolate->has_pending_exception());
5554 if (maybe.value) {
5543 return isolate->heap()->true_value(); 5555 return isolate->heap()->true_value();
5544 } else {
5545 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
5546 } 5556 }
5547 Map* map = js_obj->map(); 5557 Map* map = js_obj->map();
5548 if (!key_is_array_index && 5558 if (!key_is_array_index &&
5549 !map->has_named_interceptor() && 5559 !map->has_named_interceptor() &&
5550 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) { 5560 !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
5551 return isolate->heap()->false_value(); 5561 return isolate->heap()->false_value();
5552 } 5562 }
5553 // Slow case. 5563 // Slow case.
5554 return HasOwnPropertyImplementation(isolate, 5564 return HasOwnPropertyImplementation(isolate,
5555 Handle<JSObject>(js_obj), 5565 Handle<JSObject>(js_obj),
5556 Handle<Name>(key)); 5566 Handle<Name>(key));
5557 } else if (object->IsString() && key_is_array_index) { 5567 } else if (object->IsString() && key_is_array_index) {
5558 // Well, there is one exception: Handle [] on strings. 5568 // Well, there is one exception: Handle [] on strings.
5559 Handle<String> string = Handle<String>::cast(object); 5569 Handle<String> string = Handle<String>::cast(object);
5560 if (index < static_cast<uint32_t>(string->length())) { 5570 if (index < static_cast<uint32_t>(string->length())) {
5561 return isolate->heap()->true_value(); 5571 return isolate->heap()->true_value();
5562 } 5572 }
5563 } 5573 }
5564 return isolate->heap()->false_value(); 5574 return isolate->heap()->false_value();
5565 } 5575 }
5566 5576
5567 5577
5568 RUNTIME_FUNCTION(Runtime_HasProperty) { 5578 RUNTIME_FUNCTION(Runtime_HasProperty) {
5569 HandleScope scope(isolate); 5579 HandleScope scope(isolate);
5570 ASSERT(args.length() == 2); 5580 ASSERT(args.length() == 2);
5571 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); 5581 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5572 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 5582 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5573 5583
5574 bool result = JSReceiver::HasProperty(receiver, key); 5584 Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
5575 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 5585 if (!maybe.has_value) return isolate->heap()->exception();
5576 if (isolate->has_pending_exception()) return isolate->heap()->exception(); 5586 return isolate->heap()->ToBoolean(maybe.value);
5577 return isolate->heap()->ToBoolean(result);
5578 } 5587 }
5579 5588
5580 5589
5581 RUNTIME_FUNCTION(Runtime_HasElement) { 5590 RUNTIME_FUNCTION(Runtime_HasElement) {
5582 HandleScope scope(isolate); 5591 HandleScope scope(isolate);
5583 ASSERT(args.length() == 2); 5592 ASSERT(args.length() == 2);
5584 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); 5593 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5585 CONVERT_SMI_ARG_CHECKED(index, 1); 5594 CONVERT_SMI_ARG_CHECKED(index, 1);
5586 5595
5587 bool result = JSReceiver::HasElement(receiver, index); 5596 Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
5588 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 5597 if (!maybe.has_value) return isolate->heap()->exception();
5589 return isolate->heap()->ToBoolean(result); 5598 return isolate->heap()->ToBoolean(maybe.value);
5590 } 5599 }
5591 5600
5592 5601
5593 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) { 5602 RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
5594 HandleScope scope(isolate); 5603 HandleScope scope(isolate);
5595 ASSERT(args.length() == 2); 5604 ASSERT(args.length() == 2);
5596 5605
5597 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5606 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5598 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 5607 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5599 5608
5600 PropertyAttributes att = JSReceiver::GetOwnPropertyAttributes(object, key); 5609 Maybe<PropertyAttributes> maybe =
5601 if (att == ABSENT || (att & DONT_ENUM) != 0) { 5610 JSReceiver::GetOwnPropertyAttributes(object, key);
5602 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 5611 if (!maybe.has_value) return isolate->heap()->exception();
5603 return isolate->heap()->false_value(); 5612 if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
5604 } 5613 return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
5605 ASSERT(!isolate->has_scheduled_exception());
5606 return isolate->heap()->true_value();
5607 } 5614 }
5608 5615
5609 5616
5610 RUNTIME_FUNCTION(Runtime_GetPropertyNames) { 5617 RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
5611 HandleScope scope(isolate); 5618 HandleScope scope(isolate);
5612 ASSERT(args.length() == 1); 5619 ASSERT(args.length() == 1);
5613 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); 5620 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
5614 Handle<JSArray> result; 5621 Handle<JSArray> result;
5615 5622
5616 isolate->counters()->for_in()->Increment(); 5623 isolate->counters()->for_in()->Increment();
(...skipping 3572 matching lines...) Expand 10 before | Expand all | Expand 10 after
9189 UNREACHABLE(); 9196 UNREACHABLE();
9190 return MakePair(NULL, NULL); 9197 return MakePair(NULL, NULL);
9191 } 9198 }
9192 } 9199 }
9193 9200
9194 // Otherwise, if the slot was found the holder is a context extension 9201 // Otherwise, if the slot was found the holder is a context extension
9195 // object, subject of a with, or a global object. We read the named 9202 // object, subject of a with, or a global object. We read the named
9196 // property from it. 9203 // property from it.
9197 if (!holder.is_null()) { 9204 if (!holder.is_null()) {
9198 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); 9205 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9199 ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name)); 9206 #ifdef DEBUG
9207 if (!object->IsJSProxy()) {
9208 Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
9209 ASSERT(maybe.has_value);
9210 ASSERT(maybe.value);
9211 }
9212 #endif
9200 // GetProperty below can cause GC. 9213 // GetProperty below can cause GC.
9201 Handle<Object> receiver_handle( 9214 Handle<Object> receiver_handle(
9202 object->IsGlobalObject() 9215 object->IsGlobalObject()
9203 ? Object::cast(isolate->heap()->undefined_value()) 9216 ? Object::cast(isolate->heap()->undefined_value())
9204 : object->IsJSProxy() ? static_cast<Object*>(*object) 9217 : object->IsJSProxy() ? static_cast<Object*>(*object)
9205 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)), 9218 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
9206 isolate); 9219 isolate);
9207 9220
9208 // No need to unhole the value here. This is taken care of by the 9221 // No need to unhole the value here. This is taken care of by the
9209 // GetProperty function. 9222 // GetProperty function.
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
10176 // Run through the elements FixedArray and use HasElement and GetElement 10189 // Run through the elements FixedArray and use HasElement and GetElement
10177 // to check the prototype for missing elements. 10190 // to check the prototype for missing elements.
10178 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 10191 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10179 int fast_length = static_cast<int>(length); 10192 int fast_length = static_cast<int>(length);
10180 ASSERT(fast_length <= elements->length()); 10193 ASSERT(fast_length <= elements->length());
10181 for (int j = 0; j < fast_length; j++) { 10194 for (int j = 0; j < fast_length; j++) {
10182 HandleScope loop_scope(isolate); 10195 HandleScope loop_scope(isolate);
10183 Handle<Object> element_value(elements->get(j), isolate); 10196 Handle<Object> element_value(elements->get(j), isolate);
10184 if (!element_value->IsTheHole()) { 10197 if (!element_value->IsTheHole()) {
10185 visitor->visit(j, element_value); 10198 visitor->visit(j, element_value);
10186 } else if (JSReceiver::HasElement(receiver, j)) { 10199 } else {
10187 // Call GetElement on receiver, not its prototype, or getters won't 10200 Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10188 // have the correct receiver. 10201 if (!maybe.has_value) return false;
10189 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 10202 if (maybe.value) {
10190 isolate, element_value, 10203 // Call GetElement on receiver, not its prototype, or getters won't
10191 Object::GetElement(isolate, receiver, j), 10204 // have the correct receiver.
10192 false); 10205 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10193 visitor->visit(j, element_value); 10206 isolate, element_value,
10207 Object::GetElement(isolate, receiver, j), false);
10208 visitor->visit(j, element_value);
10209 }
10194 } 10210 }
10195 } 10211 }
10196 break; 10212 break;
10197 } 10213 }
10198 case FAST_HOLEY_DOUBLE_ELEMENTS: 10214 case FAST_HOLEY_DOUBLE_ELEMENTS:
10199 case FAST_DOUBLE_ELEMENTS: { 10215 case FAST_DOUBLE_ELEMENTS: {
10200 // Empty array is FixedArray but not FixedDoubleArray. 10216 // Empty array is FixedArray but not FixedDoubleArray.
10201 if (length == 0) break; 10217 if (length == 0) break;
10202 // Run through the elements FixedArray and use HasElement and GetElement 10218 // Run through the elements FixedArray and use HasElement and GetElement
10203 // to check the prototype for missing elements. 10219 // to check the prototype for missing elements.
10204 if (receiver->elements()->IsFixedArray()) { 10220 if (receiver->elements()->IsFixedArray()) {
10205 ASSERT(receiver->elements()->length() == 0); 10221 ASSERT(receiver->elements()->length() == 0);
10206 break; 10222 break;
10207 } 10223 }
10208 Handle<FixedDoubleArray> elements( 10224 Handle<FixedDoubleArray> elements(
10209 FixedDoubleArray::cast(receiver->elements())); 10225 FixedDoubleArray::cast(receiver->elements()));
10210 int fast_length = static_cast<int>(length); 10226 int fast_length = static_cast<int>(length);
10211 ASSERT(fast_length <= elements->length()); 10227 ASSERT(fast_length <= elements->length());
10212 for (int j = 0; j < fast_length; j++) { 10228 for (int j = 0; j < fast_length; j++) {
10213 HandleScope loop_scope(isolate); 10229 HandleScope loop_scope(isolate);
10214 if (!elements->is_the_hole(j)) { 10230 if (!elements->is_the_hole(j)) {
10215 double double_value = elements->get_scalar(j); 10231 double double_value = elements->get_scalar(j);
10216 Handle<Object> element_value = 10232 Handle<Object> element_value =
10217 isolate->factory()->NewNumber(double_value); 10233 isolate->factory()->NewNumber(double_value);
10218 visitor->visit(j, element_value); 10234 visitor->visit(j, element_value);
10219 } else if (JSReceiver::HasElement(receiver, j)) { 10235 } else {
10220 // Call GetElement on receiver, not its prototype, or getters won't 10236 Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
10221 // have the correct receiver. 10237 if (!maybe.has_value) return false;
10222 Handle<Object> element_value; 10238 if (maybe.value) {
10223 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 10239 // Call GetElement on receiver, not its prototype, or getters won't
10224 isolate, element_value, 10240 // have the correct receiver.
10225 Object::GetElement(isolate, receiver, j), 10241 Handle<Object> element_value;
10226 false); 10242 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
10227 visitor->visit(j, element_value); 10243 isolate, element_value,
10244 Object::GetElement(isolate, receiver, j), false);
10245 visitor->visit(j, element_value);
10246 }
10228 } 10247 }
10229 } 10248 }
10230 break; 10249 break;
10231 } 10250 }
10232 case DICTIONARY_ELEMENTS: { 10251 case DICTIONARY_ELEMENTS: {
10233 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); 10252 Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
10234 List<uint32_t> indices(dict->Capacity() / 2); 10253 List<uint32_t> indices(dict->Capacity() / 2);
10235 // Collect all indices in the object and the prototypes less 10254 // Collect all indices in the object and the prototypes less
10236 // than length. This might introduce duplicates in the indices list. 10255 // than length. This might introduce duplicates in the indices list.
10237 CollectElementIndices(receiver, length, &indices); 10256 CollectElementIndices(receiver, length, &indices);
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
11532 isolate, scope_info, function_context, variable_name, new_value)) { 11551 isolate, scope_info, function_context, variable_name, new_value)) {
11533 return true; 11552 return true;
11534 } 11553 }
11535 11554
11536 // Function context extension. These are variables introduced by eval. 11555 // Function context extension. These are variables introduced by eval.
11537 if (function_context->closure() == *function) { 11556 if (function_context->closure() == *function) {
11538 if (function_context->has_extension() && 11557 if (function_context->has_extension() &&
11539 !function_context->IsNativeContext()) { 11558 !function_context->IsNativeContext()) {
11540 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 11559 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11541 11560
11542 if (JSReceiver::HasProperty(ext, variable_name)) { 11561 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11562 ASSERT(maybe.has_value);
11563 if (maybe.value) {
11543 // We don't expect this to do anything except replacing 11564 // We don't expect this to do anything except replacing
11544 // property value. 11565 // property value.
11545 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value, 11566 Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
11546 SLOPPY).Assert(); 11567 SLOPPY).Assert();
11547 return true; 11568 return true;
11548 } 11569 }
11549 } 11570 }
11550 } 11571 }
11551 } 11572 }
11552 11573
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
11616 // Context locals to the context extension. 11637 // Context locals to the context extension.
11617 if (SetContextLocalValue( 11638 if (SetContextLocalValue(
11618 isolate, scope_info, context, variable_name, new_value)) { 11639 isolate, scope_info, context, variable_name, new_value)) {
11619 return true; 11640 return true;
11620 } 11641 }
11621 11642
11622 // Properties from the function context extension. This will 11643 // Properties from the function context extension. This will
11623 // be variables introduced by eval. 11644 // be variables introduced by eval.
11624 if (context->has_extension()) { 11645 if (context->has_extension()) {
11625 Handle<JSObject> ext(JSObject::cast(context->extension())); 11646 Handle<JSObject> ext(JSObject::cast(context->extension()));
11626 if (JSReceiver::HasProperty(ext, variable_name)) { 11647 Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
11648 ASSERT(maybe.has_value);
11649 if (maybe.value) {
11627 // We don't expect this to do anything except replacing property value. 11650 // We don't expect this to do anything except replacing property value.
11628 Runtime::DefineObjectProperty( 11651 Runtime::DefineObjectProperty(
11629 ext, variable_name, new_value, NONE).Assert(); 11652 ext, variable_name, new_value, NONE).Assert();
11630 return true; 11653 return true;
11631 } 11654 }
11632 } 11655 }
11633 11656
11634 return false; 11657 return false;
11635 } 11658 }
11636 11659
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
12693 12716
12694 12717
12695 // Helper function to find or create the arguments object for 12718 // Helper function to find or create the arguments object for
12696 // Runtime_DebugEvaluate. 12719 // Runtime_DebugEvaluate.
12697 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject( 12720 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
12698 Isolate* isolate, 12721 Isolate* isolate,
12699 Handle<JSObject> target, 12722 Handle<JSObject> target,
12700 Handle<JSFunction> function) { 12723 Handle<JSFunction> function) {
12701 // Do not materialize the arguments object for eval or top-level code. 12724 // Do not materialize the arguments object for eval or top-level code.
12702 // Skip if "arguments" is already taken. 12725 // Skip if "arguments" is already taken.
12703 if (!function->shared()->is_function() || 12726 if (!function->shared()->is_function()) return target;
12704 JSReceiver::HasOwnProperty( 12727 Maybe<bool> maybe = JSReceiver::HasOwnProperty(
12705 target, isolate->factory()->arguments_string())) { 12728 target, isolate->factory()->arguments_string());
12706 return target; 12729 if (!maybe.has_value) return MaybeHandle<JSObject>();
12707 } 12730 if (maybe.value) return target;
12708 12731
12709 // FunctionGetArguments can't throw an exception. 12732 // FunctionGetArguments can't throw an exception.
12710 Handle<JSObject> arguments = Handle<JSObject>::cast( 12733 Handle<JSObject> arguments = Handle<JSObject>::cast(
12711 Accessors::FunctionGetArguments(function)); 12734 Accessors::FunctionGetArguments(function));
12712 Handle<String> arguments_str = isolate->factory()->arguments_string(); 12735 Handle<String> arguments_str = isolate->factory()->arguments_string();
12713 RETURN_ON_EXCEPTION( 12736 RETURN_ON_EXCEPTION(
12714 isolate, 12737 isolate,
12715 Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE), 12738 Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
12716 JSObject); 12739 JSObject);
12717 return target; 12740 return target;
(...skipping 2277 matching lines...) Expand 10 before | Expand all | Expand 10 after
14995 } 15018 }
14996 return NULL; 15019 return NULL;
14997 } 15020 }
14998 15021
14999 15022
15000 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) { 15023 const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
15001 return &(kIntrinsicFunctions[static_cast<int>(id)]); 15024 return &(kIntrinsicFunctions[static_cast<int>(id)]);
15002 } 15025 }
15003 15026
15004 } } // namespace v8::internal 15027 } } // namespace v8::internal
OLDNEW
« src/objects-inl.h ('K') | « src/objects-inl.h ('k') | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698