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

Side by Side Diff: src/objects.cc

Issue 10388047: Implement correct checking for inherited readonliness on assignment. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed Michael's comments. Created 8 years, 6 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
« no previous file with comments | « src/objects.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 PropertyAttributes attributes, 1757 PropertyAttributes attributes,
1758 StrictModeFlag strict_mode) { 1758 StrictModeFlag strict_mode) {
1759 // Check local property, ignore interceptor. 1759 // Check local property, ignore interceptor.
1760 LookupResult result(GetIsolate()); 1760 LookupResult result(GetIsolate());
1761 LocalLookupRealNamedProperty(name, &result); 1761 LocalLookupRealNamedProperty(name, &result);
1762 if (result.IsFound()) { 1762 if (result.IsFound()) {
1763 // An existing property, a map transition or a null descriptor was 1763 // An existing property, a map transition or a null descriptor was
1764 // found. Use set property to handle all these cases. 1764 // found. Use set property to handle all these cases.
1765 return SetProperty(&result, name, value, attributes, strict_mode); 1765 return SetProperty(&result, name, value, attributes, strict_mode);
1766 } 1766 }
1767 bool found = false; 1767 bool done = false;
1768 MaybeObject* result_object; 1768 MaybeObject* result_object;
1769 result_object = SetPropertyWithCallbackSetterInPrototypes(name, 1769 result_object =
1770 value, 1770 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
1771 attributes, 1771 if (done) return result_object;
1772 &found,
1773 strict_mode);
1774 if (found) return result_object;
1775 // Add a new real property. 1772 // Add a new real property.
1776 return AddProperty(name, value, attributes, strict_mode); 1773 return AddProperty(name, value, attributes, strict_mode);
1777 } 1774 }
1778 1775
1779 1776
1780 MaybeObject* JSObject::ReplaceSlowProperty(String* name, 1777 MaybeObject* JSObject::ReplaceSlowProperty(String* name,
1781 Object* value, 1778 Object* value,
1782 PropertyAttributes attributes) { 1779 PropertyAttributes attributes) {
1783 StringDictionary* dictionary = property_dictionary(); 1780 StringDictionary* dictionary = property_dictionary();
1784 int old_index = dictionary->FindEntry(name); 1781 int old_index = dictionary->FindEntry(name);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2044 #endif 2041 #endif
2045 bool has_pending_exception; 2042 bool has_pending_exception;
2046 Handle<Object> argv[] = { value_handle }; 2043 Handle<Object> argv[] = { value_handle };
2047 Execution::Call(fun, self, ARRAY_SIZE(argv), argv, &has_pending_exception); 2044 Execution::Call(fun, self, ARRAY_SIZE(argv), argv, &has_pending_exception);
2048 // Check for pending exception and return the result. 2045 // Check for pending exception and return the result.
2049 if (has_pending_exception) return Failure::Exception(); 2046 if (has_pending_exception) return Failure::Exception();
2050 return *value_handle; 2047 return *value_handle;
2051 } 2048 }
2052 2049
2053 2050
2054 void JSObject::LookupCallbackSetterInPrototypes(String* name,
2055 LookupResult* result) {
2056 Heap* heap = GetHeap();
2057 for (Object* pt = GetPrototype();
2058 pt != heap->null_value();
2059 pt = pt->GetPrototype()) {
2060 if (pt->IsJSProxy()) {
2061 return result->HandlerResult(JSProxy::cast(pt));
2062 }
2063 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
2064 if (result->IsProperty()) {
2065 if (result->type() == CALLBACKS && !result->IsReadOnly()) return;
2066 // Found non-callback or read-only callback, stop looking.
2067 break;
2068 }
2069 }
2070 result->NotFound();
2071 }
2072
2073
2074 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2051 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
2075 uint32_t index, 2052 uint32_t index,
2076 Object* value, 2053 Object* value,
2077 bool* found, 2054 bool* found,
2078 StrictModeFlag strict_mode) { 2055 StrictModeFlag strict_mode) {
2079 Heap* heap = GetHeap(); 2056 Heap* heap = GetHeap();
2080 for (Object* pt = GetPrototype(); 2057 for (Object* pt = GetPrototype();
2081 pt != heap->null_value(); 2058 pt != heap->null_value();
2082 pt = pt->GetPrototype()) { 2059 pt = pt->GetPrototype()) {
2083 if (pt->IsJSProxy()) { 2060 if (pt->IsJSProxy()) {
2084 String* name; 2061 String* name;
2085 MaybeObject* maybe = GetHeap()->Uint32ToString(index); 2062 MaybeObject* maybe = GetHeap()->Uint32ToString(index);
2086 if (!maybe->To<String>(&name)) { 2063 if (!maybe->To<String>(&name)) {
2087 *found = true; // Force abort 2064 *found = true; // Force abort
2088 return maybe; 2065 return maybe;
2089 } 2066 }
2090 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( 2067 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler(
2091 name, value, NONE, strict_mode, found); 2068 this, name, value, NONE, strict_mode, found);
2092 } 2069 }
2093 if (!JSObject::cast(pt)->HasDictionaryElements()) { 2070 if (!JSObject::cast(pt)->HasDictionaryElements()) {
2094 continue; 2071 continue;
2095 } 2072 }
2096 SeededNumberDictionary* dictionary = 2073 SeededNumberDictionary* dictionary =
2097 JSObject::cast(pt)->element_dictionary(); 2074 JSObject::cast(pt)->element_dictionary();
2098 int entry = dictionary->FindEntry(index); 2075 int entry = dictionary->FindEntry(index);
2099 if (entry != SeededNumberDictionary::kNotFound) { 2076 if (entry != SeededNumberDictionary::kNotFound) {
2100 PropertyDetails details = dictionary->DetailsAt(entry); 2077 PropertyDetails details = dictionary->DetailsAt(entry);
2101 if (details.type() == CALLBACKS) { 2078 if (details.type() == CALLBACKS) {
2102 *found = true; 2079 *found = true;
2103 return SetElementWithCallback(dictionary->ValueAt(entry), 2080 return SetElementWithCallback(dictionary->ValueAt(entry),
2104 index, 2081 index,
2105 value, 2082 value,
2106 JSObject::cast(pt), 2083 JSObject::cast(pt),
2107 strict_mode); 2084 strict_mode);
2108 } 2085 }
2109 } 2086 }
2110 } 2087 }
2111 *found = false; 2088 *found = false;
2112 return heap->the_hole_value(); 2089 return heap->the_hole_value();
2113 } 2090 }
2114 2091
2115 MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes( 2092 MaybeObject* JSObject::SetPropertyViaPrototypes(
2116 String* name, 2093 String* name,
2117 Object* value, 2094 Object* value,
2118 PropertyAttributes attributes, 2095 PropertyAttributes attributes,
2119 bool* found, 2096 StrictModeFlag strict_mode,
2120 StrictModeFlag strict_mode) { 2097 bool* done) {
2121 Heap* heap = GetHeap(); 2098 Heap* heap = GetHeap();
2099 Isolate* isolate = heap->isolate();
2100
2101 *done = false;
2122 // We could not find a local property so let's check whether there is an 2102 // We could not find a local property so let's check whether there is an
2123 // accessor that wants to handle the property. 2103 // accessor that wants to handle the property, or whether the property is
2124 LookupResult accessor_result(heap->isolate()); 2104 // read-only on the prototype chain.
2125 LookupCallbackSetterInPrototypes(name, &accessor_result); 2105 LookupResult result(isolate);
2126 if (accessor_result.IsFound()) { 2106 LookupRealNamedPropertyInPrototypes(name, &result);
2127 *found = true; 2107 if (result.IsFound()) {
2128 if (accessor_result.type() == CALLBACKS) { 2108 switch (result.type()) {
2129 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), 2109 case NORMAL:
2130 name, 2110 case FIELD:
2131 value, 2111 case CONSTANT_FUNCTION:
2132 accessor_result.holder(), 2112 *done = result.IsReadOnly();
2133 strict_mode); 2113 break;
2134 } else if (accessor_result.type() == HANDLER) { 2114 case INTERCEPTOR: {
2135 // There is a proxy in the prototype chain. Invoke its 2115 PropertyAttributes attr =
2136 // getPropertyDescriptor trap. 2116 result.holder()->GetPropertyAttributeWithInterceptor(
2137 bool found = false; 2117 this, name, true);
2138 // SetPropertyWithHandlerIfDefiningSetter can cause GC, 2118 *done = !!(attr & READ_ONLY);
2139 // make sure to use the handlified references after calling 2119 break;
2140 // the function. 2120 }
2141 Handle<JSObject> self(this); 2121 case CALLBACKS: {
2142 Handle<String> hname(name); 2122 *done = true;
2143 Handle<Object> hvalue(value); 2123 return SetPropertyWithCallback(result.GetCallbackObject(),
2144 MaybeObject* result = 2124 name, value, result.holder(), strict_mode);
2145 accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter( 2125 }
2146 name, value, attributes, strict_mode, &found); 2126 case HANDLER: {
2147 if (found) return result; 2127 return result.proxy()->SetPropertyViaPrototypesWithHandler(
2148 // The proxy does not define the property as an accessor. 2128 this, name, value, attributes, strict_mode, done);
2149 // Consequently, it has no effect on setting the receiver. 2129 }
2150 return self->AddProperty(*hname, *hvalue, attributes, strict_mode); 2130 case MAP_TRANSITION:
2131 case CONSTANT_TRANSITION:
2132 case NULL_DESCRIPTOR:
2133 case ELEMENTS_TRANSITION:
2134 break;
2151 } 2135 }
2152 } 2136 }
2153 *found = false; 2137
2138 // If we get here with *done true, we have encountered a read-only property.
2139 if (*done) {
2140 if (strict_mode == kNonStrictMode) return value;
2141 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)};
2142 return isolate->Throw(*isolate->factory()->NewTypeError(
2143 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
2144 }
2154 return heap->the_hole_value(); 2145 return heap->the_hole_value();
2155 } 2146 }
2156 2147
2157 2148
2158 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { 2149 void JSObject::LookupInDescriptor(String* name, LookupResult* result) {
2159 DescriptorArray* descriptors = map()->instance_descriptors(); 2150 DescriptorArray* descriptors = map()->instance_descriptors();
2160 int number = descriptors->SearchWithCache(name); 2151 int number = descriptors->SearchWithCache(name);
2161 if (number != DescriptorArray::kNotFound) { 2152 if (number != DescriptorArray::kNotFound) {
2162 result->DescriptorResult(this, descriptors->GetDetails(number), number); 2153 result->DescriptorResult(this, descriptors->GetDetails(number), number);
2163 } else { 2154 } else {
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 2525
2535 LookupRealNamedPropertyInPrototypes(name, result); 2526 LookupRealNamedPropertyInPrototypes(name, result);
2536 } 2527 }
2537 2528
2538 2529
2539 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, 2530 void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
2540 LookupResult* result) { 2531 LookupResult* result) {
2541 Heap* heap = GetHeap(); 2532 Heap* heap = GetHeap();
2542 for (Object* pt = GetPrototype(); 2533 for (Object* pt = GetPrototype();
2543 pt != heap->null_value(); 2534 pt != heap->null_value();
2544 pt = JSObject::cast(pt)->GetPrototype()) { 2535 pt = pt->GetPrototype()) {
2536 if (pt->IsJSProxy()) {
2537 return result->HandlerResult(JSProxy::cast(pt));
2538 }
2545 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); 2539 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);
2546 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; 2540 if (result->IsProperty()) return;
2547 } 2541 }
2548 result->NotFound(); 2542 result->NotFound();
2549 } 2543 }
2550 2544
2551 2545
2552 // We only need to deal with CALLBACKS and INTERCEPTORS 2546 // We only need to deal with CALLBACKS and INTERCEPTORS
2553 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( 2547 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(
2554 LookupResult* result, 2548 LookupResult* result,
2555 String* name, 2549 String* name,
2556 Object* value, 2550 Object* value,
2557 bool check_prototype, 2551 bool check_prototype,
2558 StrictModeFlag strict_mode) { 2552 StrictModeFlag strict_mode) {
2559 if (check_prototype && !result->IsProperty()) { 2553 if (check_prototype && !result->IsProperty()) {
2560 LookupCallbackSetterInPrototypes(name, result); 2554 LookupRealNamedPropertyInPrototypes(name, result);
2561 } 2555 }
2562 2556
2563 if (result->IsProperty()) { 2557 if (result->IsProperty()) {
2564 if (!result->IsReadOnly()) { 2558 if (!result->IsReadOnly()) {
2565 switch (result->type()) { 2559 switch (result->type()) {
2566 case CALLBACKS: { 2560 case CALLBACKS: {
2567 Object* obj = result->GetCallbackObject(); 2561 Object* obj = result->GetCallbackObject();
2568 if (obj->IsAccessorInfo()) { 2562 if (obj->IsAccessorInfo()) {
2569 AccessorInfo* info = AccessorInfo::cast(obj); 2563 AccessorInfo* info = AccessorInfo::cast(obj);
2570 if (info->all_can_write()) { 2564 if (info->all_can_write()) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2623 2617
2624 bool JSProxy::HasPropertyWithHandler(String* name_raw) { 2618 bool JSProxy::HasPropertyWithHandler(String* name_raw) {
2625 Isolate* isolate = GetIsolate(); 2619 Isolate* isolate = GetIsolate();
2626 HandleScope scope(isolate); 2620 HandleScope scope(isolate);
2627 Handle<Object> receiver(this); 2621 Handle<Object> receiver(this);
2628 Handle<Object> name(name_raw); 2622 Handle<Object> name(name_raw);
2629 2623
2630 Handle<Object> args[] = { name }; 2624 Handle<Object> args[] = { name };
2631 Handle<Object> result = CallTrap( 2625 Handle<Object> result = CallTrap(
2632 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); 2626 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args);
2633 if (isolate->has_pending_exception()) return Failure::Exception(); 2627 if (isolate->has_pending_exception()) return false;
2634 2628
2635 return result->ToBoolean()->IsTrue(); 2629 return result->ToBoolean()->IsTrue();
2636 } 2630 }
2637 2631
2638 2632
2639 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( 2633 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
2640 String* name_raw, 2634 String* name_raw,
2641 Object* value_raw, 2635 Object* value_raw,
2642 PropertyAttributes attributes, 2636 PropertyAttributes attributes,
2643 StrictModeFlag strict_mode) { 2637 StrictModeFlag strict_mode) {
2644 Isolate* isolate = GetIsolate(); 2638 Isolate* isolate = GetIsolate();
2645 HandleScope scope(isolate); 2639 HandleScope scope(isolate);
2646 Handle<Object> receiver(this); 2640 Handle<Object> receiver(this);
2647 Handle<Object> name(name_raw); 2641 Handle<Object> name(name_raw);
2648 Handle<Object> value(value_raw); 2642 Handle<Object> value(value_raw);
2649 2643
2650 Handle<Object> args[] = { receiver, name, value }; 2644 Handle<Object> args[] = { receiver, name, value };
2651 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); 2645 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args);
2652 if (isolate->has_pending_exception()) return Failure::Exception(); 2646 if (isolate->has_pending_exception()) return Failure::Exception();
2653 2647
2654 return *value; 2648 return *value;
2655 } 2649 }
2656 2650
2657 2651
2658 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( 2652 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler(
2653 JSObject* receiver_raw,
2659 String* name_raw, 2654 String* name_raw,
2660 Object* value_raw, 2655 Object* value_raw,
2661 PropertyAttributes attributes, 2656 PropertyAttributes attributes,
2662 StrictModeFlag strict_mode, 2657 StrictModeFlag strict_mode,
2663 bool* found) { 2658 bool* done) {
2664 *found = true; // except where defined otherwise... 2659 Isolate* isolate = GetIsolate();
2665 Isolate* isolate = GetHeap()->isolate();
2666 Handle<JSProxy> proxy(this); 2660 Handle<JSProxy> proxy(this);
2667 Handle<Object> handler(this->handler()); // Trap might morph proxy. 2661 Handle<JSObject> receiver(receiver_raw);
2668 Handle<String> name(name_raw); 2662 Handle<String> name(name_raw);
2669 Handle<Object> value(value_raw); 2663 Handle<Object> value(value_raw);
2664 Handle<Object> handler(this->handler()); // Trap might morph proxy.
2665
2666 *done = true; // except where redefined...
2670 Handle<Object> args[] = { name }; 2667 Handle<Object> args[] = { name };
2671 Handle<Object> result = proxy->CallTrap( 2668 Handle<Object> result = proxy->CallTrap(
2672 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); 2669 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args);
2673 if (isolate->has_pending_exception()) return Failure::Exception(); 2670 if (isolate->has_pending_exception()) return Failure::Exception();
2674 2671
2675 if (!result->IsUndefined()) { 2672 if (result->IsUndefined()) {
2676 // The proxy handler cares about this property. 2673 *done = false;
2677 // Check whether it is virtualized as an accessor. 2674 return GetHeap()->the_hole_value();
2678 // Emulate [[GetProperty]] semantics for proxies.
2679 bool has_pending_exception;
2680 Handle<Object> argv[] = { result };
2681 Handle<Object> desc =
2682 Execution::Call(isolate->to_complete_property_descriptor(), result,
2683 ARRAY_SIZE(argv), argv, &has_pending_exception);
2684 if (has_pending_exception) return Failure::Exception();
2685
2686 Handle<String> conf_name =
2687 isolate->factory()->LookupAsciiSymbol("configurable_");
2688 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name));
2689 ASSERT(!isolate->has_pending_exception());
2690 if (configurable->IsFalse()) {
2691 Handle<String> trap =
2692 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
2693 Handle<Object> args[] = { handler, trap, name };
2694 Handle<Object> error = isolate->factory()->NewTypeError(
2695 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2696 return isolate->Throw(*error);
2697 }
2698 ASSERT(configurable->IsTrue());
2699
2700 // Check for AccessorDescriptor.
2701 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_");
2702 Handle<Object> setter(v8::internal::GetProperty(desc, set_name));
2703 ASSERT(!isolate->has_pending_exception());
2704 if (!setter->IsUndefined()) {
2705 // We have a setter -- invoke it.
2706 // TODO(rossberg): nicer would be to cast to some JSCallable here...
2707 return proxy->SetPropertyWithDefinedSetter(
2708 JSReceiver::cast(*setter), *value);
2709 } else {
2710 Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_");
2711 Handle<Object> getter(v8::internal::GetProperty(desc, get_name));
2712 ASSERT(!isolate->has_pending_exception());
2713 if (!getter->IsUndefined()) {
2714 // We have a getter but no setter -- the property may not be
2715 // written. In strict mode, throw an error.
2716 if (strict_mode == kNonStrictMode) return *value;
2717 Handle<Object> args[] = { name, proxy };
2718 Handle<Object> error = isolate->factory()->NewTypeError(
2719 "no_setter_in_callback", HandleVector(args, ARRAY_SIZE(args)));
2720 return isolate->Throw(*error);
2721 }
2722 }
2723 // Fall-through.
2724 } 2675 }
2725 2676
2726 // The proxy does not define the property as an accessor. 2677 // Emulate [[GetProperty]] semantics for proxies.
2727 *found = false; 2678 bool has_pending_exception;
2728 return *value; 2679 Handle<Object> argv[] = { result };
2680 Handle<Object> desc =
2681 Execution::Call(isolate->to_complete_property_descriptor(), result,
2682 ARRAY_SIZE(argv), argv, &has_pending_exception);
2683 if (has_pending_exception) return Failure::Exception();
2684
2685 // [[GetProperty]] requires to check that all properties are configurable.
2686 Handle<String> configurable_name =
2687 isolate->factory()->LookupAsciiSymbol("configurable_");
2688 Handle<Object> configurable(
2689 v8::internal::GetProperty(desc, configurable_name));
2690 ASSERT(!isolate->has_pending_exception());
2691 ASSERT(configurable->IsTrue() || configurable->IsFalse());
2692 if (configurable->IsFalse()) {
2693 Handle<String> trap =
2694 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
2695 Handle<Object> args[] = { handler, trap, name };
2696 Handle<Object> error = isolate->factory()->NewTypeError(
2697 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args)));
2698 return isolate->Throw(*error);
2699 }
2700 ASSERT(configurable->IsTrue());
2701
2702 // Check for DataDescriptor.
2703 Handle<String> hasWritable_name =
2704 isolate->factory()->LookupAsciiSymbol("hasWritable_");
2705 Handle<Object> hasWritable(v8::internal::GetProperty(desc, hasWritable_name));
2706 ASSERT(!isolate->has_pending_exception());
2707 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
2708 if (hasWritable->IsTrue()) {
2709 Handle<String> writable_name =
2710 isolate->factory()->LookupAsciiSymbol("writable_");
2711 Handle<Object> writable(v8::internal::GetProperty(desc, writable_name));
2712 ASSERT(!isolate->has_pending_exception());
2713 ASSERT(writable->IsTrue() || writable->IsFalse());
2714 *done = writable->IsFalse();
2715 if (!*done) return GetHeap()->the_hole_value();
2716 if (strict_mode == kNonStrictMode) return *value;
2717 Handle<Object> args[] = { name, receiver };
2718 Handle<Object> error = isolate->factory()->NewTypeError(
2719 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
2720 return isolate->Throw(*error);
2721 }
2722
2723 // We have an AccessorDescriptor.
2724 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_");
2725 Handle<Object> setter(v8::internal::GetProperty(desc, set_name));
2726 ASSERT(!isolate->has_pending_exception());
2727 if (!setter->IsUndefined()) {
2728 // TODO(rossberg): nicer would be to cast to some JSCallable here...
2729 return proxy->SetPropertyWithDefinedSetter(
2730 JSReceiver::cast(*setter), *value);
2731 }
2732
2733 if (strict_mode == kNonStrictMode) return *value;
2734 Handle<Object> args2[] = { name, proxy };
2735 Handle<Object> error = isolate->factory()->NewTypeError(
2736 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2)));
2737 return isolate->Throw(*error);
2729 } 2738 }
2730 2739
2731 2740
2732 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( 2741 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler(
2733 String* name_raw, DeleteMode mode) { 2742 String* name_raw, DeleteMode mode) {
2734 Isolate* isolate = GetIsolate(); 2743 Isolate* isolate = GetIsolate();
2735 HandleScope scope(isolate); 2744 HandleScope scope(isolate);
2736 Handle<Object> receiver(this); 2745 Handle<Object> receiver(this);
2737 Handle<Object> name(name_raw); 2746 Handle<Object> name(name_raw);
2738 2747
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2911 2920
2912 if (IsJSGlobalProxy()) { 2921 if (IsJSGlobalProxy()) {
2913 Object* proto = GetPrototype(); 2922 Object* proto = GetPrototype();
2914 if (proto->IsNull()) return value; 2923 if (proto->IsNull()) return value;
2915 ASSERT(proto->IsJSGlobalObject()); 2924 ASSERT(proto->IsJSGlobalObject());
2916 return JSObject::cast(proto)->SetPropertyForResult( 2925 return JSObject::cast(proto)->SetPropertyForResult(
2917 result, name, value, attributes, strict_mode); 2926 result, name, value, attributes, strict_mode);
2918 } 2927 }
2919 2928
2920 if (!result->IsProperty() && !IsJSContextExtensionObject()) { 2929 if (!result->IsProperty() && !IsJSContextExtensionObject()) {
2921 bool found = false; 2930 bool done = false;
2922 MaybeObject* result_object; 2931 MaybeObject* result_object =
2923 result_object = SetPropertyWithCallbackSetterInPrototypes(name, 2932 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
2924 value, 2933 if (done) return result_object;
2925 attributes,
2926 &found,
2927 strict_mode);
2928 if (found) return result_object;
2929 } 2934 }
2930 2935
2931 // At this point, no GC should have happened, as this would invalidate
2932 // 'result', which we cannot handlify!
2933
2934 if (!result->IsFound()) { 2936 if (!result->IsFound()) {
2935 // Neither properties nor transitions found. 2937 // Neither properties nor transitions found.
2936 return AddProperty(name, value, attributes, strict_mode); 2938 return AddProperty(name, value, attributes, strict_mode);
2937 } 2939 }
2938 if (result->IsReadOnly() && result->IsProperty()) { 2940 if (result->IsReadOnly() && result->IsProperty()) {
2939 if (strict_mode == kStrictMode) { 2941 if (strict_mode == kStrictMode) {
2940 Handle<JSObject> self(this); 2942 Handle<JSObject> self(this);
2941 Handle<String> hname(name); 2943 Handle<String> hname(name);
2942 Handle<Object> args[] = { hname, self }; 2944 Handle<Object> args[] = { hname, self };
2943 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( 2945 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError(
(...skipping 10166 matching lines...) Expand 10 before | Expand all | Expand 10 after
13110 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13112 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13111 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13113 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13112 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13114 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13113 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13115 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13114 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13116 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13115 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13117 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13116 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13118 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13117 } 13119 }
13118 13120
13119 } } // namespace v8::internal 13121 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698