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 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1755 PropertyAttributes attributes, | 1755 PropertyAttributes attributes, |
1756 StrictModeFlag strict_mode) { | 1756 StrictModeFlag strict_mode) { |
1757 // Check local property, ignore interceptor. | 1757 // Check local property, ignore interceptor. |
1758 LookupResult result(GetIsolate()); | 1758 LookupResult result(GetIsolate()); |
1759 LocalLookupRealNamedProperty(name, &result); | 1759 LocalLookupRealNamedProperty(name, &result); |
1760 if (result.IsFound()) { | 1760 if (result.IsFound()) { |
1761 // An existing property, a map transition or a null descriptor was | 1761 // An existing property, a map transition or a null descriptor was |
1762 // found. Use set property to handle all these cases. | 1762 // found. Use set property to handle all these cases. |
1763 return SetProperty(&result, name, value, attributes, strict_mode); | 1763 return SetProperty(&result, name, value, attributes, strict_mode); |
1764 } | 1764 } |
1765 bool done = false; | 1765 bool found = false; |
1766 MaybeObject* result_object; | 1766 MaybeObject* result_object; |
1767 result_object = | 1767 result_object = SetPropertyWithCallbackSetterInPrototypes(name, |
1768 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 1768 value, |
1769 if (done) return result_object; | 1769 attributes, |
| 1770 &found, |
| 1771 strict_mode); |
| 1772 if (found) return result_object; |
1770 // Add a new real property. | 1773 // Add a new real property. |
1771 return AddProperty(name, value, attributes, strict_mode); | 1774 return AddProperty(name, value, attributes, strict_mode); |
1772 } | 1775 } |
1773 | 1776 |
1774 | 1777 |
1775 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1778 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
1776 Object* value, | 1779 Object* value, |
1777 PropertyAttributes attributes) { | 1780 PropertyAttributes attributes) { |
1778 StringDictionary* dictionary = property_dictionary(); | 1781 StringDictionary* dictionary = property_dictionary(); |
1779 int old_index = dictionary->FindEntry(name); | 1782 int old_index = dictionary->FindEntry(name); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2039 #endif | 2042 #endif |
2040 bool has_pending_exception; | 2043 bool has_pending_exception; |
2041 Handle<Object> argv[] = { value_handle }; | 2044 Handle<Object> argv[] = { value_handle }; |
2042 Execution::Call(fun, self, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2045 Execution::Call(fun, self, ARRAY_SIZE(argv), argv, &has_pending_exception); |
2043 // Check for pending exception and return the result. | 2046 // Check for pending exception and return the result. |
2044 if (has_pending_exception) return Failure::Exception(); | 2047 if (has_pending_exception) return Failure::Exception(); |
2045 return *value_handle; | 2048 return *value_handle; |
2046 } | 2049 } |
2047 | 2050 |
2048 | 2051 |
| 2052 void JSObject::LookupCallbackSetterInPrototypes(String* name, |
| 2053 LookupResult* result) { |
| 2054 Heap* heap = GetHeap(); |
| 2055 for (Object* pt = GetPrototype(); |
| 2056 pt != heap->null_value(); |
| 2057 pt = pt->GetPrototype()) { |
| 2058 if (pt->IsJSProxy()) { |
| 2059 return result->HandlerResult(JSProxy::cast(pt)); |
| 2060 } |
| 2061 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 2062 if (result->IsProperty()) { |
| 2063 if (result->type() == CALLBACKS && !result->IsReadOnly()) return; |
| 2064 // Found non-callback or read-only callback, stop looking. |
| 2065 break; |
| 2066 } |
| 2067 } |
| 2068 result->NotFound(); |
| 2069 } |
| 2070 |
| 2071 |
2049 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2072 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( |
2050 uint32_t index, | 2073 uint32_t index, |
2051 Object* value, | 2074 Object* value, |
2052 bool* found, | 2075 bool* found, |
2053 StrictModeFlag strict_mode) { | 2076 StrictModeFlag strict_mode) { |
2054 Heap* heap = GetHeap(); | 2077 Heap* heap = GetHeap(); |
2055 for (Object* pt = GetPrototype(); | 2078 for (Object* pt = GetPrototype(); |
2056 pt != heap->null_value(); | 2079 pt != heap->null_value(); |
2057 pt = pt->GetPrototype()) { | 2080 pt = pt->GetPrototype()) { |
2058 if (pt->IsJSProxy()) { | 2081 if (pt->IsJSProxy()) { |
2059 String* name; | 2082 String* name; |
2060 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 2083 MaybeObject* maybe = GetHeap()->Uint32ToString(index); |
2061 if (!maybe->To<String>(&name)) { | 2084 if (!maybe->To<String>(&name)) { |
2062 *found = true; // Force abort | 2085 *found = true; // Force abort |
2063 return maybe; | 2086 return maybe; |
2064 } | 2087 } |
2065 return JSProxy::cast(pt)->SetPropertyViaPrototypesWithHandler( | 2088 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( |
2066 this, name, value, NONE, strict_mode, found); | 2089 this, name, value, NONE, strict_mode, found); |
2067 } | 2090 } |
2068 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2091 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
2069 continue; | 2092 continue; |
2070 } | 2093 } |
2071 SeededNumberDictionary* dictionary = | 2094 SeededNumberDictionary* dictionary = |
2072 JSObject::cast(pt)->element_dictionary(); | 2095 JSObject::cast(pt)->element_dictionary(); |
2073 int entry = dictionary->FindEntry(index); | 2096 int entry = dictionary->FindEntry(index); |
2074 if (entry != SeededNumberDictionary::kNotFound) { | 2097 if (entry != SeededNumberDictionary::kNotFound) { |
2075 PropertyDetails details = dictionary->DetailsAt(entry); | 2098 PropertyDetails details = dictionary->DetailsAt(entry); |
2076 if (details.type() == CALLBACKS) { | 2099 if (details.type() == CALLBACKS) { |
2077 *found = true; | 2100 *found = true; |
2078 return SetElementWithCallback(dictionary->ValueAt(entry), | 2101 return SetElementWithCallback(dictionary->ValueAt(entry), |
2079 index, | 2102 index, |
2080 value, | 2103 value, |
2081 JSObject::cast(pt), | 2104 JSObject::cast(pt), |
2082 strict_mode); | 2105 strict_mode); |
2083 } | 2106 } |
2084 } | 2107 } |
2085 } | 2108 } |
2086 *found = false; | 2109 *found = false; |
2087 return heap->the_hole_value(); | 2110 return heap->the_hole_value(); |
2088 } | 2111 } |
2089 | 2112 |
2090 MaybeObject* JSObject::SetPropertyViaPrototypes( | 2113 MaybeObject* JSObject::SetPropertyWithCallbackSetterInPrototypes( |
2091 String* name, | 2114 String* name, |
2092 Object* value, | 2115 Object* value, |
2093 PropertyAttributes attributes, | 2116 PropertyAttributes attributes, |
2094 StrictModeFlag strict_mode, | 2117 bool* found, |
2095 bool* done) { | 2118 StrictModeFlag strict_mode) { |
2096 Heap* heap = GetHeap(); | 2119 Heap* heap = GetHeap(); |
2097 Isolate* isolate = heap->isolate(); | |
2098 | |
2099 *done = false; | |
2100 // We could not find a local property so let's check whether there is an | 2120 // We could not find a local property so let's check whether there is an |
2101 // accessor that wants to handle the property, or whether the property is | 2121 // accessor that wants to handle the property. |
2102 // read-only on the prototype chain. | 2122 LookupResult accessor_result(heap->isolate()); |
2103 LookupResult result(isolate); | 2123 LookupCallbackSetterInPrototypes(name, &accessor_result); |
2104 LookupRealNamedPropertyInPrototypes(name, &result); | 2124 if (accessor_result.IsFound()) { |
2105 if (result.IsFound()) { | 2125 *found = true; |
2106 switch (result.type()) { | 2126 if (accessor_result.type() == CALLBACKS) { |
2107 case NORMAL: | 2127 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
2108 case FIELD: | 2128 name, |
2109 case CONSTANT_FUNCTION: | 2129 value, |
2110 *done = result.IsReadOnly(); | 2130 accessor_result.holder(), |
2111 break; | 2131 strict_mode); |
2112 case INTERCEPTOR: { | 2132 } else if (accessor_result.type() == HANDLER) { |
2113 PropertyAttributes attr = | 2133 // There is a proxy in the prototype chain. Invoke its |
2114 result.holder()->GetPropertyAttributeWithInterceptor( | 2134 // getPropertyDescriptor trap. |
2115 this, name, true); | 2135 bool found = false; |
2116 *done = !!(attr & READ_ONLY); | 2136 // SetPropertyWithHandlerIfDefiningSetter can cause GC, |
2117 break; | 2137 // make sure to use the handlified references after calling |
2118 } | 2138 // the function. |
2119 case CALLBACKS: { | 2139 Handle<JSObject> self(this); |
2120 if (!FLAG_es5_readonly && result.IsReadOnly()) break; | 2140 Handle<String> hname(name); |
2121 *done = true; | 2141 Handle<Object> hvalue(value); |
2122 return SetPropertyWithCallback(result.GetCallbackObject(), | 2142 MaybeObject* result = |
2123 name, value, result.holder(), strict_mode); | 2143 accessor_result.proxy()->SetPropertyWithHandlerIfDefiningSetter( |
2124 } | 2144 this, name, value, attributes, strict_mode, &found); |
2125 case HANDLER: { | 2145 if (found) return result; |
2126 return result.proxy()->SetPropertyViaPrototypesWithHandler( | 2146 // The proxy does not define the property as an accessor. |
2127 this, name, value, attributes, strict_mode, done); | 2147 // Consequently, it has no effect on setting the receiver. |
2128 } | 2148 return self->AddProperty(*hname, *hvalue, attributes, strict_mode); |
2129 case MAP_TRANSITION: | |
2130 case CONSTANT_TRANSITION: | |
2131 case NULL_DESCRIPTOR: | |
2132 case ELEMENTS_TRANSITION: | |
2133 break; | |
2134 } | 2149 } |
2135 } | 2150 } |
2136 | 2151 *found = false; |
2137 // If we get here with *done true, we have encountered a read-only property. | |
2138 if (!FLAG_es5_readonly) *done = false; | |
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 } | |
2145 return heap->the_hole_value(); | 2152 return heap->the_hole_value(); |
2146 } | 2153 } |
2147 | 2154 |
2148 | 2155 |
2149 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { | 2156 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { |
2150 DescriptorArray* descriptors = map()->instance_descriptors(); | 2157 DescriptorArray* descriptors = map()->instance_descriptors(); |
2151 int number = descriptors->SearchWithCache(name); | 2158 int number = descriptors->SearchWithCache(name); |
2152 if (number != DescriptorArray::kNotFound) { | 2159 if (number != DescriptorArray::kNotFound) { |
2153 result->DescriptorResult(this, descriptors->GetDetails(number), number); | 2160 result->DescriptorResult(this, descriptors->GetDetails(number), number); |
2154 } else { | 2161 } else { |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2539 | 2546 |
2540 LookupRealNamedPropertyInPrototypes(name, result); | 2547 LookupRealNamedPropertyInPrototypes(name, result); |
2541 } | 2548 } |
2542 | 2549 |
2543 | 2550 |
2544 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 2551 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, |
2545 LookupResult* result) { | 2552 LookupResult* result) { |
2546 Heap* heap = GetHeap(); | 2553 Heap* heap = GetHeap(); |
2547 for (Object* pt = GetPrototype(); | 2554 for (Object* pt = GetPrototype(); |
2548 pt != heap->null_value(); | 2555 pt != heap->null_value(); |
2549 pt = pt->GetPrototype()) { | 2556 pt = JSObject::cast(pt)->GetPrototype()) { |
2550 if (pt->IsJSProxy()) { | |
2551 return result->HandlerResult(JSProxy::cast(pt)); | |
2552 } | |
2553 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 2557 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
2554 ASSERT(!(result->IsProperty() && result->type() == INTERCEPTOR)); | 2558 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
2555 if (result->IsProperty()) return; | |
2556 } | 2559 } |
2557 result->NotFound(); | 2560 result->NotFound(); |
2558 } | 2561 } |
2559 | 2562 |
2560 | 2563 |
2561 // We only need to deal with CALLBACKS and INTERCEPTORS | 2564 // We only need to deal with CALLBACKS and INTERCEPTORS |
2562 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( | 2565 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck( |
2563 LookupResult* result, | 2566 LookupResult* result, |
2564 String* name, | 2567 String* name, |
2565 Object* value, | 2568 Object* value, |
2566 bool check_prototype, | 2569 bool check_prototype, |
2567 StrictModeFlag strict_mode) { | 2570 StrictModeFlag strict_mode) { |
2568 if (check_prototype && !result->IsProperty()) { | 2571 if (check_prototype && !result->IsProperty()) { |
2569 LookupRealNamedPropertyInPrototypes(name, result); | 2572 LookupCallbackSetterInPrototypes(name, result); |
2570 } | 2573 } |
2571 | 2574 |
2572 if (result->IsProperty()) { | 2575 if (result->IsProperty()) { |
2573 if (!result->IsReadOnly()) { | 2576 if (!result->IsReadOnly()) { |
2574 switch (result->type()) { | 2577 switch (result->type()) { |
2575 case CALLBACKS: { | 2578 case CALLBACKS: { |
2576 Object* obj = result->GetCallbackObject(); | 2579 Object* obj = result->GetCallbackObject(); |
2577 if (obj->IsAccessorInfo()) { | 2580 if (obj->IsAccessorInfo()) { |
2578 AccessorInfo* info = AccessorInfo::cast(obj); | 2581 AccessorInfo* info = AccessorInfo::cast(obj); |
2579 if (info->all_can_write()) { | 2582 if (info->all_can_write()) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2632 | 2635 |
2633 bool JSProxy::HasPropertyWithHandler(String* name_raw) { | 2636 bool JSProxy::HasPropertyWithHandler(String* name_raw) { |
2634 Isolate* isolate = GetIsolate(); | 2637 Isolate* isolate = GetIsolate(); |
2635 HandleScope scope(isolate); | 2638 HandleScope scope(isolate); |
2636 Handle<Object> receiver(this); | 2639 Handle<Object> receiver(this); |
2637 Handle<Object> name(name_raw); | 2640 Handle<Object> name(name_raw); |
2638 | 2641 |
2639 Handle<Object> args[] = { name }; | 2642 Handle<Object> args[] = { name }; |
2640 Handle<Object> result = CallTrap( | 2643 Handle<Object> result = CallTrap( |
2641 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); | 2644 "has", isolate->derived_has_trap(), ARRAY_SIZE(args), args); |
2642 if (isolate->has_pending_exception()) return false; | 2645 if (isolate->has_pending_exception()) return Failure::Exception(); |
2643 | 2646 |
2644 return result->ToBoolean()->IsTrue(); | 2647 return result->ToBoolean()->IsTrue(); |
2645 } | 2648 } |
2646 | 2649 |
2647 | 2650 |
2648 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( | 2651 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler( |
2649 JSReceiver* receiver_raw, | 2652 JSReceiver* receiver_raw, |
2650 String* name_raw, | 2653 String* name_raw, |
2651 Object* value_raw, | 2654 Object* value_raw, |
2652 PropertyAttributes attributes, | 2655 PropertyAttributes attributes, |
2653 StrictModeFlag strict_mode) { | 2656 StrictModeFlag strict_mode) { |
2654 Isolate* isolate = GetIsolate(); | 2657 Isolate* isolate = GetIsolate(); |
2655 HandleScope scope(isolate); | 2658 HandleScope scope(isolate); |
2656 Handle<JSReceiver> receiver(receiver_raw); | 2659 Handle<JSReceiver> receiver(receiver_raw); |
2657 Handle<Object> name(name_raw); | 2660 Handle<Object> name(name_raw); |
2658 Handle<Object> value(value_raw); | 2661 Handle<Object> value(value_raw); |
2659 | 2662 |
2660 Handle<Object> args[] = { receiver, name, value }; | 2663 Handle<Object> args[] = { receiver, name, value }; |
2661 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); | 2664 CallTrap("set", isolate->derived_set_trap(), ARRAY_SIZE(args), args); |
2662 if (isolate->has_pending_exception()) return Failure::Exception(); | 2665 if (isolate->has_pending_exception()) return Failure::Exception(); |
2663 | 2666 |
2664 return *value; | 2667 return *value; |
2665 } | 2668 } |
2666 | 2669 |
2667 | 2670 |
2668 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyViaPrototypesWithHandler( | 2671 MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandlerIfDefiningSetter( |
2669 JSReceiver* receiver_raw, | 2672 JSReceiver* receiver_raw, |
2670 String* name_raw, | 2673 String* name_raw, |
2671 Object* value_raw, | 2674 Object* value_raw, |
2672 PropertyAttributes attributes, | 2675 PropertyAttributes attributes, |
2673 StrictModeFlag strict_mode, | 2676 StrictModeFlag strict_mode, |
2674 bool* done) { | 2677 bool* found) { |
2675 Isolate* isolate = GetIsolate(); | 2678 *found = true; // except where defined otherwise... |
| 2679 Isolate* isolate = GetHeap()->isolate(); |
| 2680 Handle<JSReceiver> receiver(receiver_raw); |
2676 Handle<JSProxy> proxy(this); | 2681 Handle<JSProxy> proxy(this); |
2677 Handle<JSReceiver> receiver(receiver_raw); | 2682 Handle<Object> handler(this->handler()); // Trap might morph proxy. |
2678 Handle<String> name(name_raw); | 2683 Handle<String> name(name_raw); |
2679 Handle<Object> value(value_raw); | 2684 Handle<Object> value(value_raw); |
2680 Handle<Object> handler(this->handler()); // Trap might morph proxy. | |
2681 | |
2682 *done = true; // except where redefined... | |
2683 Handle<Object> args[] = { name }; | 2685 Handle<Object> args[] = { name }; |
2684 Handle<Object> result = proxy->CallTrap( | 2686 Handle<Object> result = proxy->CallTrap( |
2685 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); | 2687 "getPropertyDescriptor", Handle<Object>(), ARRAY_SIZE(args), args); |
2686 if (isolate->has_pending_exception()) return Failure::Exception(); | 2688 if (isolate->has_pending_exception()) return Failure::Exception(); |
2687 | 2689 |
2688 if (result->IsUndefined()) { | 2690 if (!result->IsUndefined()) { |
2689 *done = false; | 2691 // The proxy handler cares about this property. |
2690 return GetHeap()->the_hole_value(); | 2692 // Check whether it is virtualized as an accessor. |
| 2693 // Emulate [[GetProperty]] semantics for proxies. |
| 2694 bool has_pending_exception; |
| 2695 Handle<Object> argv[] = { result }; |
| 2696 Handle<Object> desc = |
| 2697 Execution::Call(isolate->to_complete_property_descriptor(), result, |
| 2698 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 2699 if (has_pending_exception) return Failure::Exception(); |
| 2700 |
| 2701 Handle<String> conf_name = |
| 2702 isolate->factory()->LookupAsciiSymbol("configurable_"); |
| 2703 Handle<Object> configurable(v8::internal::GetProperty(desc, conf_name)); |
| 2704 ASSERT(!isolate->has_pending_exception()); |
| 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 AccessorDescriptor. |
| 2716 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_"); |
| 2717 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); |
| 2718 ASSERT(!isolate->has_pending_exception()); |
| 2719 if (!setter->IsUndefined()) { |
| 2720 // We have a setter -- invoke it. |
| 2721 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 2722 return receiver->SetPropertyWithDefinedSetter( |
| 2723 JSReceiver::cast(*setter), *value); |
| 2724 } else { |
| 2725 Handle<String> get_name = isolate->factory()->LookupAsciiSymbol("get_"); |
| 2726 Handle<Object> getter(v8::internal::GetProperty(desc, get_name)); |
| 2727 ASSERT(!isolate->has_pending_exception()); |
| 2728 if (!getter->IsUndefined()) { |
| 2729 // We have a getter but no setter -- the property may not be |
| 2730 // written. In strict mode, throw an error. |
| 2731 if (strict_mode == kNonStrictMode) return *value; |
| 2732 Handle<Object> args[] = { name, proxy }; |
| 2733 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2734 "no_setter_in_callback", HandleVector(args, ARRAY_SIZE(args))); |
| 2735 return isolate->Throw(*error); |
| 2736 } |
| 2737 } |
| 2738 // Fall-through. |
2691 } | 2739 } |
2692 | 2740 |
2693 // Emulate [[GetProperty]] semantics for proxies. | 2741 // The proxy does not define the property as an accessor. |
2694 bool has_pending_exception; | 2742 *found = false; |
2695 Handle<Object> argv[] = { result }; | 2743 return *value; |
2696 Handle<Object> desc = | |
2697 Execution::Call(isolate->to_complete_property_descriptor(), result, | |
2698 ARRAY_SIZE(argv), argv, &has_pending_exception); | |
2699 if (has_pending_exception) return Failure::Exception(); | |
2700 | |
2701 // [[GetProperty]] requires to check that all properties are configurable. | |
2702 Handle<String> configurable_name = | |
2703 isolate->factory()->LookupAsciiSymbol("configurable_"); | |
2704 Handle<Object> configurable( | |
2705 v8::internal::GetProperty(desc, configurable_name)); | |
2706 ASSERT(!isolate->has_pending_exception()); | |
2707 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | |
2708 if (configurable->IsFalse()) { | |
2709 Handle<String> trap = | |
2710 isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor"); | |
2711 Handle<Object> args[] = { handler, trap, name }; | |
2712 Handle<Object> error = isolate->factory()->NewTypeError( | |
2713 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | |
2714 return isolate->Throw(*error); | |
2715 } | |
2716 ASSERT(configurable->IsTrue()); | |
2717 | |
2718 // Check for DataDescriptor. | |
2719 Handle<String> hasWritable_name = | |
2720 isolate->factory()->LookupAsciiSymbol("hasWritable_"); | |
2721 Handle<Object> hasWritable(v8::internal::GetProperty(desc, hasWritable_name)); | |
2722 ASSERT(!isolate->has_pending_exception()); | |
2723 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | |
2724 if (hasWritable->IsTrue()) { | |
2725 Handle<String> writable_name = | |
2726 isolate->factory()->LookupAsciiSymbol("writable_"); | |
2727 Handle<Object> writable(v8::internal::GetProperty(desc, writable_name)); | |
2728 ASSERT(!isolate->has_pending_exception()); | |
2729 ASSERT(writable->IsTrue() || writable->IsFalse()); | |
2730 *done = writable->IsFalse(); | |
2731 if (!*done) return GetHeap()->the_hole_value(); | |
2732 if (strict_mode == kNonStrictMode) return *value; | |
2733 Handle<Object> args[] = { name, receiver }; | |
2734 Handle<Object> error = isolate->factory()->NewTypeError( | |
2735 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | |
2736 return isolate->Throw(*error); | |
2737 } | |
2738 | |
2739 // We have an AccessorDescriptor. | |
2740 Handle<String> set_name = isolate->factory()->LookupAsciiSymbol("set_"); | |
2741 Handle<Object> setter(v8::internal::GetProperty(desc, set_name)); | |
2742 ASSERT(!isolate->has_pending_exception()); | |
2743 if (!setter->IsUndefined()) { | |
2744 // TODO(rossberg): nicer would be to cast to some JSCallable here... | |
2745 return receiver->SetPropertyWithDefinedSetter( | |
2746 JSReceiver::cast(*setter), *value); | |
2747 } | |
2748 | |
2749 if (strict_mode == kNonStrictMode) return *value; | |
2750 Handle<Object> args2[] = { name, proxy }; | |
2751 Handle<Object> error = isolate->factory()->NewTypeError( | |
2752 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | |
2753 return isolate->Throw(*error); | |
2754 } | 2744 } |
2755 | 2745 |
2756 | 2746 |
2757 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( | 2747 MUST_USE_RESULT MaybeObject* JSProxy::DeletePropertyWithHandler( |
2758 String* name_raw, DeleteMode mode) { | 2748 String* name_raw, DeleteMode mode) { |
2759 Isolate* isolate = GetIsolate(); | 2749 Isolate* isolate = GetIsolate(); |
2760 HandleScope scope(isolate); | 2750 HandleScope scope(isolate); |
2761 Handle<Object> receiver(this); | 2751 Handle<Object> receiver(this); |
2762 Handle<Object> name(name_raw); | 2752 Handle<Object> name(name_raw); |
2763 | 2753 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2936 | 2926 |
2937 if (IsJSGlobalProxy()) { | 2927 if (IsJSGlobalProxy()) { |
2938 Object* proto = GetPrototype(); | 2928 Object* proto = GetPrototype(); |
2939 if (proto->IsNull()) return value; | 2929 if (proto->IsNull()) return value; |
2940 ASSERT(proto->IsJSGlobalObject()); | 2930 ASSERT(proto->IsJSGlobalObject()); |
2941 return JSObject::cast(proto)->SetPropertyForResult( | 2931 return JSObject::cast(proto)->SetPropertyForResult( |
2942 result, name, value, attributes, strict_mode); | 2932 result, name, value, attributes, strict_mode); |
2943 } | 2933 } |
2944 | 2934 |
2945 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 2935 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
2946 bool done = false; | 2936 bool found = false; |
2947 MaybeObject* result_object = | 2937 MaybeObject* result_object; |
2948 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 2938 result_object = SetPropertyWithCallbackSetterInPrototypes(name, |
2949 if (done) return result_object; | 2939 value, |
| 2940 attributes, |
| 2941 &found, |
| 2942 strict_mode); |
| 2943 if (found) return result_object; |
2950 } | 2944 } |
2951 | 2945 |
| 2946 // At this point, no GC should have happened, as this would invalidate |
| 2947 // 'result', which we cannot handlify! |
| 2948 |
2952 if (!result->IsFound()) { | 2949 if (!result->IsFound()) { |
2953 // Neither properties nor transitions found. | 2950 // Neither properties nor transitions found. |
2954 return AddProperty(name, value, attributes, strict_mode); | 2951 return AddProperty(name, value, attributes, strict_mode); |
2955 } | 2952 } |
2956 if (result->IsReadOnly() && result->IsProperty()) { | 2953 if (result->IsReadOnly() && result->IsProperty()) { |
2957 if (strict_mode == kStrictMode) { | 2954 if (strict_mode == kStrictMode) { |
2958 Handle<JSObject> self(this); | 2955 Handle<JSObject> self(this); |
2959 Handle<String> hname(name); | 2956 Handle<String> hname(name); |
2960 Handle<Object> args[] = { hname, self }; | 2957 Handle<Object> args[] = { hname, self }; |
2961 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 2958 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
(...skipping 10273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13235 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13232 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13236 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13233 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13237 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13234 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13238 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13235 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13239 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13236 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13240 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13237 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13241 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13238 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13242 } | 13239 } |
13243 | 13240 |
13244 } } // namespace v8::internal | 13241 } } // namespace v8::internal |
OLD | NEW |