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 = |
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 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, | |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |