| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/accessors.h" | 5 #include "src/accessors.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/contexts.h" | 8 #include "src/contexts.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/execution.h" | 10 #include "src/execution.h" |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 JSDataView::kByteLengthOffset, object_offset) || | 128 JSDataView::kByteLengthOffset, object_offset) || |
| 129 CheckForName(name, isolate->factory()->byte_offset_string(), | 129 CheckForName(name, isolate->factory()->byte_offset_string(), |
| 130 JSDataView::kByteOffsetOffset, object_offset); | 130 JSDataView::kByteOffsetOffset, object_offset); |
| 131 default: | 131 default: |
| 132 return false; | 132 return false; |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 | 135 |
| 136 MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty( | 136 MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty( |
| 137 Isolate* isolate, Handle<JSObject> receiver, Handle<JSObject> holder, | 137 Isolate* isolate, Handle<JSObject> receiver, Handle<JSObject> holder, |
| 138 Handle<Name> name, Handle<Object> value, bool observe) { | 138 Handle<Name> name, Handle<Object> value) { |
| 139 LookupIterator it(receiver, name, holder, | 139 LookupIterator it(receiver, name, holder, |
| 140 LookupIterator::OWN_SKIP_INTERCEPTOR); | 140 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 141 // Skip any access checks we might hit. This accessor should never hit in a | 141 // Skip any access checks we might hit. This accessor should never hit in a |
| 142 // situation where the caller does not have access. | 142 // situation where the caller does not have access. |
| 143 if (it.state() == LookupIterator::ACCESS_CHECK) { | 143 if (it.state() == LookupIterator::ACCESS_CHECK) { |
| 144 CHECK(it.HasAccess()); | 144 CHECK(it.HasAccess()); |
| 145 it.Next(); | 145 it.Next(); |
| 146 } | 146 } |
| 147 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); | 147 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); |
| 148 | |
| 149 Handle<Object> old_value; | |
| 150 bool is_observed = observe && receiver->map()->is_observed(); | |
| 151 if (is_observed) { | |
| 152 MaybeHandle<Object> maybe_old = Object::GetPropertyWithAccessor(&it); | |
| 153 if (!maybe_old.ToHandle(&old_value)) return maybe_old; | |
| 154 } | |
| 155 | |
| 156 it.ReconfigureDataProperty(value, it.property_attributes()); | 148 it.ReconfigureDataProperty(value, it.property_attributes()); |
| 157 | |
| 158 if (is_observed && !old_value->SameValue(*value)) { | |
| 159 return JSObject::EnqueueChangeRecord(receiver, "update", name, old_value); | |
| 160 } | |
| 161 | |
| 162 return value; | 149 return value; |
| 163 } | 150 } |
| 164 | 151 |
| 165 void Accessors::ReconfigureToDataProperty( | 152 void Accessors::ReconfigureToDataProperty( |
| 166 v8::Local<v8::Name> key, v8::Local<v8::Value> val, | 153 v8::Local<v8::Name> key, v8::Local<v8::Value> val, |
| 167 const v8::PropertyCallbackInfo<void>& info) { | 154 const v8::PropertyCallbackInfo<void>& info) { |
| 168 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 155 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 169 HandleScope scope(isolate); | 156 HandleScope scope(isolate); |
| 170 Handle<JSObject> receiver = | 157 Handle<JSObject> receiver = |
| 171 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | 158 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); |
| 172 Handle<JSObject> holder = | 159 Handle<JSObject> holder = |
| 173 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); | 160 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); |
| 174 Handle<Name> name = Utils::OpenHandle(*key); | 161 Handle<Name> name = Utils::OpenHandle(*key); |
| 175 Handle<Object> value = Utils::OpenHandle(*val); | 162 Handle<Object> value = Utils::OpenHandle(*val); |
| 176 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty( | 163 MaybeHandle<Object> result = |
| 177 isolate, receiver, holder, name, value, false); | 164 ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value); |
| 178 if (result.is_null()) isolate->OptionalRescheduleException(false); | 165 if (result.is_null()) isolate->OptionalRescheduleException(false); |
| 179 } | 166 } |
| 180 | 167 |
| 181 // | 168 // |
| 182 // Accessors::ArgumentsIterator | 169 // Accessors::ArgumentsIterator |
| 183 // | 170 // |
| 184 | 171 |
| 185 | 172 |
| 186 void Accessors::ArgumentsIteratorGetter( | 173 void Accessors::ArgumentsIteratorGetter( |
| 187 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | 174 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 Handle<JSReceiver> object = Utils::OpenHandle(*info.This()); | 215 Handle<JSReceiver> object = Utils::OpenHandle(*info.This()); |
| 229 Handle<JSArray> array = Handle<JSArray>::cast(object); | 216 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 230 Handle<Object> length_obj = Utils::OpenHandle(*val); | 217 Handle<Object> length_obj = Utils::OpenHandle(*val); |
| 231 | 218 |
| 232 uint32_t length = 0; | 219 uint32_t length = 0; |
| 233 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { | 220 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { |
| 234 isolate->OptionalRescheduleException(false); | 221 isolate->OptionalRescheduleException(false); |
| 235 return; | 222 return; |
| 236 } | 223 } |
| 237 | 224 |
| 238 if (JSArray::ObservableSetLength(array, length).is_null()) { | 225 JSArray::SetLength(array, length); |
| 239 isolate->OptionalRescheduleException(false); | |
| 240 } | |
| 241 | 226 |
| 242 if (info.ShouldThrowOnError()) { | 227 if (info.ShouldThrowOnError()) { |
| 243 uint32_t actual_new_len = 0; | 228 uint32_t actual_new_len = 0; |
| 244 CHECK(array->length()->ToArrayLength(&actual_new_len)); | 229 CHECK(array->length()->ToArrayLength(&actual_new_len)); |
| 245 // Throw TypeError if there were non-deletable elements. | 230 // Throw TypeError if there were non-deletable elements. |
| 246 if (actual_new_len != length) { | 231 if (actual_new_len != length) { |
| 247 Factory* factory = isolate->factory(); | 232 Factory* factory = isolate->factory(); |
| 248 isolate->Throw(*factory->NewTypeError( | 233 isolate->Throw(*factory->NewTypeError( |
| 249 MessageTemplate::kStrictDeleteProperty, | 234 MessageTemplate::kStrictDeleteProperty, |
| 250 factory->NewNumberFromUint(actual_new_len - 1), array)); | 235 factory->NewNumberFromUint(actual_new_len - 1), array)); |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 if (!function->has_prototype()) { | 710 if (!function->has_prototype()) { |
| 726 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); | 711 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); |
| 727 JSFunction::SetPrototype(function, proto); | 712 JSFunction::SetPrototype(function, proto); |
| 728 } | 713 } |
| 729 return Handle<Object>(function->prototype(), isolate); | 714 return Handle<Object>(function->prototype(), isolate); |
| 730 } | 715 } |
| 731 | 716 |
| 732 | 717 |
| 733 MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype( | 718 MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype( |
| 734 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) { | 719 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) { |
| 735 Handle<Object> old_value; | |
| 736 bool is_observed = function->map()->is_observed(); | |
| 737 if (is_observed) { | |
| 738 if (function->has_prototype()) | |
| 739 old_value = handle(function->prototype(), isolate); | |
| 740 else | |
| 741 old_value = isolate->factory()->NewFunctionPrototype(function); | |
| 742 } | |
| 743 | |
| 744 JSFunction::SetPrototype(function, value); | 720 JSFunction::SetPrototype(function, value); |
| 745 DCHECK(function->prototype() == *value); | 721 DCHECK(function->prototype() == *value); |
| 746 | |
| 747 if (is_observed && !old_value->SameValue(*value)) { | |
| 748 MaybeHandle<Object> result = JSObject::EnqueueChangeRecord( | |
| 749 function, "update", isolate->factory()->prototype_string(), old_value); | |
| 750 if (result.is_null()) return MaybeHandle<Object>(); | |
| 751 } | |
| 752 | |
| 753 return function; | 722 return function; |
| 754 } | 723 } |
| 755 | 724 |
| 756 | 725 |
| 757 MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function, | 726 MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function, |
| 758 Handle<Object> prototype) { | 727 Handle<Object> prototype) { |
| 759 DCHECK(function->IsConstructor()); | 728 DCHECK(function->IsConstructor()); |
| 760 Isolate* isolate = function->GetIsolate(); | 729 Isolate* isolate = function->GetIsolate(); |
| 761 return SetFunctionPrototype(isolate, function, prototype); | 730 return SetFunctionPrototype(isolate, function, prototype); |
| 762 } | 731 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 782 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 814 Handle<Object> result; | 783 Handle<Object> result; |
| 815 if (!JSFunction::GetLength(isolate, function).ToHandle(&result)) { | 784 if (!JSFunction::GetLength(isolate, function).ToHandle(&result)) { |
| 816 result = handle(Smi::FromInt(0), isolate); | 785 result = handle(Smi::FromInt(0), isolate); |
| 817 isolate->OptionalRescheduleException(false); | 786 isolate->OptionalRescheduleException(false); |
| 818 } | 787 } |
| 819 | 788 |
| 820 info.GetReturnValue().Set(Utils::ToLocal(result)); | 789 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 821 } | 790 } |
| 822 | 791 |
| 823 void Accessors::ObservedReconfigureToDataProperty( | |
| 824 v8::Local<v8::Name> key, v8::Local<v8::Value> val, | |
| 825 const v8::PropertyCallbackInfo<void>& info) { | |
| 826 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
| 827 HandleScope scope(isolate); | |
| 828 Handle<JSObject> receiver = | |
| 829 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | |
| 830 Handle<JSObject> holder = | |
| 831 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); | |
| 832 Handle<Name> name = Utils::OpenHandle(*key); | |
| 833 Handle<Object> value = Utils::OpenHandle(*val); | |
| 834 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty( | |
| 835 isolate, receiver, holder, name, value, true); | |
| 836 if (result.is_null()) isolate->OptionalRescheduleException(false); | |
| 837 } | |
| 838 | |
| 839 | |
| 840 Handle<AccessorInfo> Accessors::FunctionLengthInfo( | 792 Handle<AccessorInfo> Accessors::FunctionLengthInfo( |
| 841 Isolate* isolate, PropertyAttributes attributes) { | 793 Isolate* isolate, PropertyAttributes attributes) { |
| 842 return MakeAccessor(isolate, isolate->factory()->length_string(), | 794 return MakeAccessor(isolate, isolate->factory()->length_string(), |
| 843 &FunctionLengthGetter, &ObservedReconfigureToDataProperty, | 795 &FunctionLengthGetter, &ReconfigureToDataProperty, |
| 844 attributes); | 796 attributes); |
| 845 } | 797 } |
| 846 | 798 |
| 847 | 799 |
| 848 // | 800 // |
| 849 // Accessors::FunctionName | 801 // Accessors::FunctionName |
| 850 // | 802 // |
| 851 | 803 |
| 852 | 804 |
| 853 void Accessors::FunctionNameGetter( | 805 void Accessors::FunctionNameGetter( |
| 854 v8::Local<v8::Name> name, | 806 v8::Local<v8::Name> name, |
| 855 const v8::PropertyCallbackInfo<v8::Value>& info) { | 807 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 856 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 808 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 857 HandleScope scope(isolate); | 809 HandleScope scope(isolate); |
| 858 Handle<JSFunction> function = | 810 Handle<JSFunction> function = |
| 859 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 811 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 860 Handle<Object> result = JSFunction::GetName(isolate, function); | 812 Handle<Object> result = JSFunction::GetName(isolate, function); |
| 861 info.GetReturnValue().Set(Utils::ToLocal(result)); | 813 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 862 } | 814 } |
| 863 | 815 |
| 864 Handle<AccessorInfo> Accessors::FunctionNameInfo( | 816 Handle<AccessorInfo> Accessors::FunctionNameInfo( |
| 865 Isolate* isolate, PropertyAttributes attributes) { | 817 Isolate* isolate, PropertyAttributes attributes) { |
| 866 return MakeAccessor(isolate, isolate->factory()->name_string(), | 818 return MakeAccessor(isolate, isolate->factory()->name_string(), |
| 867 &FunctionNameGetter, &ObservedReconfigureToDataProperty, | 819 &FunctionNameGetter, &ReconfigureToDataProperty, |
| 868 attributes); | 820 attributes); |
| 869 } | 821 } |
| 870 | 822 |
| 871 | 823 |
| 872 // | 824 // |
| 873 // Accessors::FunctionArguments | 825 // Accessors::FunctionArguments |
| 874 // | 826 // |
| 875 | 827 |
| 876 | 828 |
| 877 static Handle<Object> ArgumentsForInlinedFunction( | 829 static Handle<Object> ArgumentsForInlinedFunction( |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 int bound_length = function->bound_arguments()->length(); | 1115 int bound_length = function->bound_arguments()->length(); |
| 1164 int length = Max(0, target_length->value() - bound_length); | 1116 int length = Max(0, target_length->value() - bound_length); |
| 1165 | 1117 |
| 1166 Handle<Object> result(Smi::FromInt(length), isolate); | 1118 Handle<Object> result(Smi::FromInt(length), isolate); |
| 1167 info.GetReturnValue().Set(Utils::ToLocal(result)); | 1119 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 1168 } | 1120 } |
| 1169 | 1121 |
| 1170 Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo( | 1122 Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo( |
| 1171 Isolate* isolate, PropertyAttributes attributes) { | 1123 Isolate* isolate, PropertyAttributes attributes) { |
| 1172 return MakeAccessor(isolate, isolate->factory()->length_string(), | 1124 return MakeAccessor(isolate, isolate->factory()->length_string(), |
| 1173 &BoundFunctionLengthGetter, | 1125 &BoundFunctionLengthGetter, &ReconfigureToDataProperty, |
| 1174 &ObservedReconfigureToDataProperty, attributes); | 1126 attributes); |
| 1175 } | 1127 } |
| 1176 | 1128 |
| 1177 // | 1129 // |
| 1178 // Accessors::BoundFunctionName | 1130 // Accessors::BoundFunctionName |
| 1179 // | 1131 // |
| 1180 | 1132 |
| 1181 void Accessors::BoundFunctionNameGetter( | 1133 void Accessors::BoundFunctionNameGetter( |
| 1182 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | 1134 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1183 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 1135 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 1184 HandleScope scope(isolate); | 1136 HandleScope scope(isolate); |
| 1185 Handle<JSBoundFunction> function = | 1137 Handle<JSBoundFunction> function = |
| 1186 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder())); | 1138 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 1187 Handle<Object> result; | 1139 Handle<Object> result; |
| 1188 if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) { | 1140 if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) { |
| 1189 isolate->OptionalRescheduleException(false); | 1141 isolate->OptionalRescheduleException(false); |
| 1190 return; | 1142 return; |
| 1191 } | 1143 } |
| 1192 info.GetReturnValue().Set(Utils::ToLocal(result)); | 1144 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 1193 } | 1145 } |
| 1194 | 1146 |
| 1195 Handle<AccessorInfo> Accessors::BoundFunctionNameInfo( | 1147 Handle<AccessorInfo> Accessors::BoundFunctionNameInfo( |
| 1196 Isolate* isolate, PropertyAttributes attributes) { | 1148 Isolate* isolate, PropertyAttributes attributes) { |
| 1197 return MakeAccessor(isolate, isolate->factory()->name_string(), | 1149 return MakeAccessor(isolate, isolate->factory()->name_string(), |
| 1198 &BoundFunctionNameGetter, | 1150 &BoundFunctionNameGetter, &ReconfigureToDataProperty, |
| 1199 &ObservedReconfigureToDataProperty, attributes); | 1151 attributes); |
| 1200 } | 1152 } |
| 1201 | 1153 |
| 1202 // | 1154 // |
| 1203 // Accessors::MakeModuleExport | 1155 // Accessors::MakeModuleExport |
| 1204 // | 1156 // |
| 1205 | 1157 |
| 1206 static void ModuleGetExport(v8::Local<v8::Name> property, | 1158 static void ModuleGetExport(v8::Local<v8::Name> property, |
| 1207 const v8::PropertyCallbackInfo<v8::Value>& info) { | 1159 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 1208 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); | 1160 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); |
| 1209 Context* context = Context::cast(instance->context()); | 1161 Context* context = Context::cast(instance->context()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1252 Isolate* isolate = name->GetIsolate(); | 1204 Isolate* isolate = name->GetIsolate(); |
| 1253 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport, | 1205 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport, |
| 1254 &ModuleSetExport, attributes); | 1206 &ModuleSetExport, attributes); |
| 1255 info->set_data(Smi::FromInt(index)); | 1207 info->set_data(Smi::FromInt(index)); |
| 1256 return info; | 1208 return info; |
| 1257 } | 1209 } |
| 1258 | 1210 |
| 1259 | 1211 |
| 1260 } // namespace internal | 1212 } // namespace internal |
| 1261 } // namespace v8 | 1213 } // namespace v8 |
| OLD | NEW |