Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // 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 |