OLD | NEW |
---|---|
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 Loading... | |
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 = SetPropertyViaPrototypes( |
Michael Starzinger
2012/05/30 13:08:55
The method call should fit into one line if we bre
rossberg
2012/05/31 13:31:28
Done.
| |
1770 value, | 1770 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 Loading... | |
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, | 2051 void JSObject::LookupCallbackSetterInPrototypes(String* name, |
Michael Starzinger
2012/05/30 13:08:55
Can we rename this to "LookupRealNamedProperty" or
rossberg
2012/05/31 13:31:28
A method of that name already exists, but does som
Michael Starzinger
2012/06/01 08:34:04
Nice.
| |
2055 LookupResult* result) { | 2052 LookupResult* result) { |
2056 Heap* heap = GetHeap(); | 2053 Heap* heap = GetHeap(); |
2057 for (Object* pt = GetPrototype(); | 2054 for (Object* pt = GetPrototype(); |
2058 pt != heap->null_value(); | 2055 pt != heap->null_value(); |
2059 pt = pt->GetPrototype()) { | 2056 pt = pt->GetPrototype()) { |
2060 if (pt->IsJSProxy()) { | 2057 if (pt->IsJSProxy()) { |
2061 return result->HandlerResult(JSProxy::cast(pt)); | 2058 return result->HandlerResult(JSProxy::cast(pt)); |
2062 } | 2059 } |
2063 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 2060 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
2064 if (result->IsProperty()) { | 2061 if (result->IsProperty()) return; |
2065 if (result->type() == CALLBACKS && !result->IsReadOnly()) return; | |
2066 // Found non-callback or read-only callback, stop looking. | |
2067 break; | |
2068 } | |
2069 } | 2062 } |
2070 result->NotFound(); | 2063 result->NotFound(); |
2071 } | 2064 } |
2072 | 2065 |
2073 | 2066 |
2074 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2067 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
2075 uint32_t index, | 2068 uint32_t index, |
2076 Object* value, | 2069 Object* value, |
2077 bool* found, | 2070 bool* found, |
2078 StrictModeFlag strict_mode) { | 2071 StrictModeFlag strict_mode) { |
2079 Heap* heap = GetHeap(); | 2072 Heap* heap = GetHeap(); |
2080 for (Object* pt = GetPrototype(); | 2073 for (Object* pt = GetPrototype(); |
2081 pt != heap->null_value(); | 2074 pt != heap->null_value(); |
2082 pt = pt->GetPrototype()) { | 2075 pt = pt->GetPrototype()) { |
2083 if (pt->IsJSProxy()) { | 2076 if (pt->IsJSProxy()) { |
2084 String* name; | 2077 String* name; |
2085 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 2078 MaybeObject* maybe = GetHeap()->Uint32ToString(index); |
2086 if (!maybe->To<String>(&name)) { | 2079 if (!maybe->To<String>(&name)) { |
2087 *found = true; // Force abort | 2080 *found = true; // Force abort |
2088 return maybe; | 2081 return maybe; |
2089 } | 2082 } |
2090 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( | 2083 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( |
2091 name, value, NONE, strict_mode, found); | 2084 this, name, value, NONE, strict_mode, found); |
2092 } | 2085 } |
2093 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2086 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
2094 continue; | 2087 continue; |
2095 } | 2088 } |
2096 SeededNumberDictionary* dictionary = | 2089 SeededNumberDictionary* dictionary = |
2097 JSObject::cast(pt)->element_dictionary(); | 2090 JSObject::cast(pt)->element_dictionary(); |
2098 int entry = dictionary->FindEntry(index); | 2091 int entry = dictionary->FindEntry(index); |
2099 if (entry != SeededNumberDictionary::kNotFound) { | 2092 if (entry != SeededNumberDictionary::kNotFound) { |
2100 PropertyDetails details = dictionary->DetailsAt(entry); | 2093 PropertyDetails details = dictionary->DetailsAt(entry); |
2101 if (details.type() == CALLBACKS) { | 2094 if (details.type() == CALLBACKS) { |
2102 *found = true; | 2095 *found = true; |
2103 return SetElementWithCallback(dictionary->ValueAt(entry), | 2096 return SetElementWithCallback(dictionary->ValueAt(entry), |
2104 index, | 2097 index, |
2105 value, | 2098 value, |
2106 JSObject::cast(pt), | 2099 JSObject::cast(pt), |
2107 strict_mode); | 2100 strict_mode); |
2108 } | 2101 } |
2109 } | 2102 } |
2110 } | 2103 } |
2111 *found = false; | 2104 *found = false; |
2112 return heap->the_hole_value(); | 2105 return heap->the_hole_value(); |
2113 } | 2106 } |
2114 | 2107 |
2115 MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes( | 2108 MaybeObject* JSObject::SetPropertyViaPrototypes( |
2116 String* name, | 2109 String* name, |
2117 Object* value, | 2110 Object* value, |
2118 PropertyAttributes attributes, | 2111 PropertyAttributes attributes, |
2119 bool* found, | 2112 StrictModeFlag strict_mode, |
2120 StrictModeFlag strict_mode) { | 2113 bool* done) { |
2121 Heap* heap = GetHeap(); | 2114 Heap* heap = GetHeap(); |
2115 Isolate* isolate = heap->isolate(); | |
2116 | |
2117 *done = false; | |
2122 // We could not find a local property so let's check whether there is an | 2118 // We could not find a local property so let's check whether there is an |
2123 // accessor that wants to handle the property. | 2119 // accessor that wants to handle the property, or whether the property is |
2124 LookupResult accessor_result(heap->isolate()); | 2120 // read-only on the prototype chain. |
2125 LookupCallbackSetterInPrototypes(name, &accessor_result); | 2121 LookupResult result(isolate); |
2126 if (accessor_result.IsFound()) { | 2122 LookupCallbackSetterInPrototypes(name, &result); |
2127 *found = true; | 2123 if (result.IsFound()) { |
2128 if (accessor_result.type() == CALLBACKS) { | 2124 switch (result.type()) { |
2129 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 2125 case NORMAL: |
2130 name, | 2126 case FIELD: |
2131 value, | 2127 case CONSTANT_FUNCTION: |
2132 accessor_result.holder(), | 2128 *done = result.IsReadOnly(); |
2133 strict_mode); | 2129 break; |
2134 } else if (accessor_result.type() == HANDLER) { | 2130 case INTERCEPTOR: { |
2135 // There is a proxy in the prototype chain. Invoke its | 2131 PropertyAttributes attr = |
2136 // getPropertyDescriptor trap. | 2132 result.holder()->GetPropertyAttributeWithInterceptor( |
2137 bool found = false; | 2133 this, name, true); |
2138 // SetPropertyWithHandlerIfDefiningSetter can cause GC, | 2134 *done = !!(attr & READ_ONLY); |
Michael Starzinger
2012/05/30 13:08:55
Why not not not use no negation?
rossberg
2012/05/31 13:31:28
Standard JS idiom for (explicitly) converting to a
| |
2139 // make sure to use the handlified references after calling | 2135 break; |
2140 // the function. | 2136 } |
2141 Handle<JSObject> self(this); | 2137 case CALLBACKS: { |
2142 Handle<String> hname(name); | 2138 *done = true; |
2143 Handle<Object> hvalue(value); | 2139 return SetPropertyWithCallback(result.GetCallbackObject(), |
2144 MaybeObject* result = | 2140 name, value, result.holder(), strict_mode); |
2145 accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter( | 2141 } |
2146 name, value, attributes, strict_mode, &found); | 2142 case HANDLER: { |
2147 if (found) return result; | 2143 return result.proxy()->SetPropertyViaPrototypesWithHandler( |
2148 // The proxy does not define the property as an accessor. | 2144 this, name, value, attributes, strict_mode, done); |
2149 // Consequently, it has no effect on setting the receiver. | 2145 } |
2150 return self->AddProperty(*hname, *hvalue, attributes, strict_mode); | 2146 case MAP_TRANSITION: |
2147 case CONSTANT_TRANSITION: | |
2148 case NULL_DESCRIPTOR: | |
2149 case ELEMENTS_TRANSITION: | |
2150 ; // Fall through | |
Michael Starzinger
2012/05/30 13:08:55
Fall through to nothing makes no sense, can we jus
rossberg
2012/05/31 13:31:28
Done.
| |
2151 } | 2151 } |
2152 } | 2152 } |
2153 *found = false; | 2153 |
2154 // If we get here with *done true, we have encountered a read-only property. | |
2155 if (*done) { | |
2156 if (strict_mode == kNonStrictMode) return value; | |
2157 Handle<Object> args[] = { Handle<Object>(name), Handle<Object>(this)}; | |
2158 return isolate->Throw(*isolate->factory()->NewTypeError( | |
2159 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | |
2160 } | |
2154 return heap->the_hole_value(); | 2161 return heap->the_hole_value(); |
2155 } | 2162 } |
2156 | 2163 |
2157 | 2164 |
2158 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { | 2165 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { |
2159 DescriptorArray* descriptors = map()->instance_descriptors(); | 2166 DescriptorArray* descriptors = map()->instance_descriptors(); |
2160 int number = descriptors->SearchWithCache(name); | 2167 int number = descriptors->SearchWithCache(name); |
2161 if (number != DescriptorArray::kNotFound) { | 2168 if (number != DescriptorArray::kNotFound) { |
2162 result->DescriptorResult(this, descriptors->GetDetails(number), number); | 2169 result->DescriptorResult(this, descriptors->GetDetails(number), number); |
2163 } else { | 2170 } else { |
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2623 | 2630 |
2624 bool JSProxy::HasPropertyWithHandler(String* name_raw) { | 2631 bool JSProxy::HasPropertyWithHandler(String* name_raw) { |
2625 Isolate* isolate = GetIsolate(); | 2632 Isolate* isolate = GetIsolate(); |
2626 HandleScope scope(isolate); | 2633 HandleScope scope(isolate); |
2627 Handle<Object> receiver(this); | 2634 Handle<Object> receiver(this); |
2628 Handle<Object> name(name_raw); | 2635 Handle<Object> name(name_raw); |
2629 | 2636 |
2630 Handle<Object> args[] = { name }; | 2637 Handle<Object> args[] = { name }; |
2631 Handle<Object> result = CallTrap( | 2638 Handle<Object> result = CallTrap( |
2632 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); | 2639 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); |
2633 if (isolate->has_pending_exception()) return Failure::Exception(); | 2640 if (isolate->has_pending_exception()) return false; |
2634 | 2641 |
2635 return result->ToBoolean()->IsTrue(); | 2642 return result->ToBoolean()->IsTrue(); |
2636 } | 2643 } |
2637 | 2644 |
2638 | 2645 |
2639 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( | 2646 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( |
2640 String* name_raw, | 2647 String* name_raw, |
2641 Object* value_raw, | 2648 Object* value_raw, |
2642 PropertyAttributes attributes, | 2649 PropertyAttributes attributes, |
2643 StrictModeFlag strict_mode) { | 2650 StrictModeFlag strict_mode) { |
2644 Isolate* isolate = GetIsolate(); | 2651 Isolate* isolate = GetIsolate(); |
2645 HandleScope scope(isolate); | 2652 HandleScope scope(isolate); |
2646 Handle<Object> receiver(this); | 2653 Handle<Object> receiver(this); |
2647 Handle<Object> name(name_raw); | 2654 Handle<Object> name(name_raw); |
2648 Handle<Object> value(value_raw); | 2655 Handle<Object> value(value_raw); |
2649 | 2656 |
2650 Handle<Object> args[] = { receiver, name, value }; | 2657 Handle<Object> args[] = { receiver, name, value }; |
2651 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); | 2658 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
2652 if (isolate->has_pending_exception()) return Failure::Exception(); | 2659 if (isolate->has_pending_exception()) return Failure::Exception(); |
2653 | 2660 |
2654 return *value; | 2661 return *value; |
2655 } | 2662 } |
2656 | 2663 |
2657 | 2664 |
2658 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( | 2665 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( |
2666 JSObject* receiver_raw, | |
2659 String* name_raw, | 2667 String* name_raw, |
2660 Object* value_raw, | 2668 Object* value_raw, |
2661 PropertyAttributes attributes, | 2669 PropertyAttributes attributes, |
2662 StrictModeFlag strict_mode, | 2670 StrictModeFlag strict_mode, |
2663 bool* found) { | 2671 bool* done) { |
2664 *found = true; // except where defined otherwise... | 2672 Isolate* isolate = GetIsolate(); |
2665 Isolate* isolate = GetHeap()->isolate(); | |
2666 Handle<JSProxy> proxy(this); | 2673 Handle<JSProxy> proxy(this); |
2667 Handle<Object> handler(this->handler()); // Trap might morph proxy. | 2674 Handle<JSObject> receiver(receiver_raw); |
2668 Handle<String> name(name_raw); | 2675 Handle<String> name(name_raw); |
2669 Handle<Object> value(value_raw); | 2676 Handle<Object> value(value_raw); |
2677 Handle<Object> handler(this->handler()); // Trap might morph proxy. | |
2678 | |
2679 *done = true; // except where redefined... | |
2670 Handle<Object> args[] = { name }; | 2680 Handle<Object> args[] = { name }; |
2671 Handle<Object> result = proxy->CallTrap( | 2681 Handle<Object> result = proxy->CallTrap( |
2672 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 2682 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); |
2673 if (isolate->has_pending_exception()) return Failure::Exception(); | 2683 if (isolate->has_pending_exception()) return Failure::Exception(); |
2674 | 2684 |
2675 if (!result->IsUndefined()) { | 2685 if (result->IsUndefined()) { |
2676 // The proxy handler cares about this property. | 2686 *done = false; |
2677 // Check whether it is virtualized as an accessor. | 2687 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 } | 2688 } |
2725 | 2689 |
2726 // The proxy does not define the property as an accessor. | 2690 // Emulate [[GetProperty]] semantics for proxies. |
2727 *found = false; | 2691 bool has_pending_exception; |
2728 return *value; | 2692 Handle<Object> argv[] = { result }; |
2693 Handle<Object> desc = | |
2694 Execution::Call(isolate->to_complete_property_descriptor(), result, | |
2695 ARRAY_SIZE(argv), argv, &has_pending_exception); | |
2696 if (has_pending_exception) return Failure::Exception(); | |
2697 | |
2698 // [[GetProperty]] requires to check that all properties are configurable. | |
2699 Handle<String> configurable_name = | |
2700 isolate->factory()->LookupAsciiSymbol("configurable_"); | |
2701 Handle<Object> configurable( | |
2702 v8::internal::GetProperty(desc, configurable_name)); | |
2703 ASSERT(!isolate->has_pending_exception()); | |
2704 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | |
2705 if (configurable->IsFalse()) { | |
2706 Handle<String> trap = | |
2707 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); | |
2708 Handle<Object> args[] = { handler, trap, name }; | |
2709 Handle<Object> error = isolate->factory()->NewTypeError( | |
2710 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | |
2711 return isolate->Throw(*error); | |
2712 } | |
2713 ASSERT(configurable->IsTrue()); | |
2714 | |
2715 // Check for DataDescriptor. | |
2716 Handle<String> hasWritable_name = | |
2717 isolate->factory()->LookupAsciiSymbol("hasWritable_"); | |
2718 Handle<Object> hasWritable(v8::internal::GetProperty(desc, hasWritable_name)); | |
2719 ASSERT(!isolate->has_pending_exception()); | |
2720 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | |
2721 if (hasWritable->IsTrue()) { | |
2722 Handle<String> writable_name = | |
2723 isolate->factory()->LookupAsciiSymbol("writable_"); | |
2724 Handle<Object> writable(v8::internal::GetProperty(desc, writable_name)); | |
2725 ASSERT(!isolate->has_pending_exception()); | |
2726 ASSERT(writable->IsTrue() || writable->IsFalse()); | |
2727 *done = writable->IsFalse(); | |
2728 if (!*done) return GetHeap()->the_hole_value(); | |
2729 if (strict_mode == kNonStrictMode) return *value; | |
2730 Handle<Object> args[] = { name, receiver }; | |
2731 Handle<Object> error = isolate->factory()->NewTypeError( | |
2732 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | |
2733 return isolate->Throw(*error); | |
2734 } | |
2735 | |
2736 // We have an AccessorDescriptor. | |
2737 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_"); | |
2738 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); | |
2739 ASSERT(!isolate->has_pending_exception()); | |
2740 if (!setter->IsUndefined()) { | |
2741 // TODO(rossberg): nicer would be to cast to some JSCallable here... | |
2742 return proxy->SetPropertyWithDefinedSetter( | |
2743 JSReceiver::cast(*setter), *value); | |
2744 } | |
2745 | |
2746 if (strict_mode == kNonStrictMode) return *value; | |
2747 Handle<Object> args2[] = { name, proxy }; | |
2748 Handle<Object> error = isolate->factory()->NewTypeError( | |
2749 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | |
2750 return isolate->Throw(*error); | |
2729 } | 2751 } |
2730 | 2752 |
2731 | 2753 |
2732 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( | 2754 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( |
2733 String* name_raw, DeleteMode mode) { | 2755 String* name_raw, DeleteMode mode) { |
2734 Isolate* isolate = GetIsolate(); | 2756 Isolate* isolate = GetIsolate(); |
2735 HandleScope scope(isolate); | 2757 HandleScope scope(isolate); |
2736 Handle<Object> receiver(this); | 2758 Handle<Object> receiver(this); |
2737 Handle<Object> name(name_raw); | 2759 Handle<Object> name(name_raw); |
2738 | 2760 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2911 | 2933 |
2912 if (IsJSGlobalProxy()) { | 2934 if (IsJSGlobalProxy()) { |
2913 Object* proto = GetPrototype(); | 2935 Object* proto = GetPrototype(); |
2914 if (proto->IsNull()) return value; | 2936 if (proto->IsNull()) return value; |
2915 ASSERT(proto->IsJSGlobalObject()); | 2937 ASSERT(proto->IsJSGlobalObject()); |
2916 return JSObject::cast(proto)->SetPropertyForResult( | 2938 return JSObject::cast(proto)->SetPropertyForResult( |
2917 result, name, value, attributes, strict_mode); | 2939 result, name, value, attributes, strict_mode); |
2918 } | 2940 } |
2919 | 2941 |
2920 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 2942 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
2921 bool found = false; | 2943 bool done = false; |
2922 MaybeObject* result_object; | 2944 MaybeObject* result_object = SetPropertyViaPrototypes( |
Michael Starzinger
2012/05/30 13:08:55
The method call should fit into one line if we bre
rossberg
2012/05/31 13:31:28
Done.
| |
2923 result_object = SetPropertyWithCallbackSetterInPrototypes(name, | 2945 name, value, attributes, strict_mode, &done); |
2924 value, | 2946 if (done) return result_object; |
2925 attributes, | |
2926 &found, | |
2927 strict_mode); | |
2928 if (found) return result_object; | |
2929 } | 2947 } |
2930 | 2948 |
2931 // At this point, no GC should have happened, as this would invalidate | |
2932 // 'result', which we cannot handlify! | |
2933 | |
2934 if (!result->IsFound()) { | 2949 if (!result->IsFound()) { |
2935 // Neither properties nor transitions found. | 2950 // Neither properties nor transitions found. |
2936 return AddProperty(name, value, attributes, strict_mode); | 2951 return AddProperty(name, value, attributes, strict_mode); |
2937 } | 2952 } |
2938 if (result->IsReadOnly() && result->IsProperty()) { | 2953 if (result->IsReadOnly() && result->IsProperty()) { |
2939 if (strict_mode == kStrictMode) { | 2954 if (strict_mode == kStrictMode) { |
2940 Handle<JSObject> self(this); | 2955 Handle<JSObject> self(this); |
2941 Handle<String> hname(name); | 2956 Handle<String> hname(name); |
2942 Handle<Object> args[] = { hname, self }; | 2957 Handle<Object> args[] = { hname, self }; |
2943 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 2958 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
(...skipping 10166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13110 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13125 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13111 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13126 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13112 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13127 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13113 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13128 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13114 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13129 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13115 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13130 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13116 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13131 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13117 } | 13132 } |
13118 | 13133 |
13119 } } // namespace v8::internal | 13134 } } // namespace v8::internal |
OLD | NEW |