| 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" |
| 11 #include "src/factory.h" | 11 #include "src/factory.h" |
| 12 #include "src/frames-inl.h" | 12 #include "src/frames-inl.h" |
| 13 #include "src/isolate-inl.h" | 13 #include "src/isolate-inl.h" |
| 14 #include "src/list-inl.h" | 14 #include "src/list-inl.h" |
| 15 #include "src/messages.h" | 15 #include "src/messages.h" |
| 16 #include "src/property-details.h" | 16 #include "src/property-details.h" |
| 17 #include "src/prototype.h" | 17 #include "src/prototype.h" |
| 18 | 18 |
| 19 namespace v8 { | 19 namespace v8 { |
| 20 namespace internal { | 20 namespace internal { |
| 21 | 21 |
| 22 | |
| 23 Handle<AccessorInfo> Accessors::MakeAccessor( | 22 Handle<AccessorInfo> Accessors::MakeAccessor( |
| 24 Isolate* isolate, | 23 Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter, |
| 25 Handle<Name> name, | 24 AccessorNameBooleanSetterCallback setter, PropertyAttributes attributes) { |
| 26 AccessorNameGetterCallback getter, | |
| 27 AccessorNameSetterCallback setter, | |
| 28 PropertyAttributes attributes) { | |
| 29 Factory* factory = isolate->factory(); | 25 Factory* factory = isolate->factory(); |
| 30 Handle<AccessorInfo> info = factory->NewAccessorInfo(); | 26 Handle<AccessorInfo> info = factory->NewAccessorInfo(); |
| 31 info->set_property_attributes(attributes); | 27 info->set_property_attributes(attributes); |
| 32 info->set_all_can_read(false); | 28 info->set_all_can_read(false); |
| 33 info->set_all_can_write(false); | 29 info->set_all_can_write(false); |
| 34 info->set_is_special_data_property(true); | 30 info->set_is_special_data_property(true); |
| 35 info->set_is_sloppy(false); | 31 info->set_is_sloppy(false); |
| 36 name = factory->InternalizeName(name); | 32 name = factory->InternalizeName(name); |
| 37 info->set_name(*name); | 33 info->set_name(*name); |
| 38 Handle<Object> get = v8::FromCData(isolate, getter); | 34 Handle<Object> get = v8::FromCData(isolate, getter); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 DCHECK(holder.is_identical_to(it.GetHolder<JSObject>())); | 95 DCHECK(holder.is_identical_to(it.GetHolder<JSObject>())); |
| 100 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); | 96 CHECK_EQ(LookupIterator::ACCESSOR, it.state()); |
| 101 it.ReconfigureDataProperty(value, it.property_attributes()); | 97 it.ReconfigureDataProperty(value, it.property_attributes()); |
| 102 return value; | 98 return value; |
| 103 } | 99 } |
| 104 | 100 |
| 105 } // namespace | 101 } // namespace |
| 106 | 102 |
| 107 void Accessors::ReconfigureToDataProperty( | 103 void Accessors::ReconfigureToDataProperty( |
| 108 v8::Local<v8::Name> key, v8::Local<v8::Value> val, | 104 v8::Local<v8::Name> key, v8::Local<v8::Value> val, |
| 109 const v8::PropertyCallbackInfo<void>& info) { | 105 const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
| 110 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 106 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 111 HandleScope scope(isolate); | 107 HandleScope scope(isolate); |
| 112 Handle<Object> receiver = Utils::OpenHandle(*info.This()); | 108 Handle<Object> receiver = Utils::OpenHandle(*info.This()); |
| 113 Handle<JSObject> holder = | 109 Handle<JSObject> holder = |
| 114 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); | 110 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); |
| 115 Handle<Name> name = Utils::OpenHandle(*key); | 111 Handle<Name> name = Utils::OpenHandle(*key); |
| 116 Handle<Object> value = Utils::OpenHandle(*val); | 112 Handle<Object> value = Utils::OpenHandle(*val); |
| 117 MaybeHandle<Object> result = | 113 MaybeHandle<Object> result = |
| 118 ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value); | 114 ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value); |
| 119 if (result.is_null()) isolate->OptionalRescheduleException(false); | 115 if (result.is_null()) { |
| 116 isolate->OptionalRescheduleException(false); |
| 117 } else { |
| 118 info.GetReturnValue().Set(true); |
| 119 } |
| 120 } | 120 } |
| 121 | 121 |
| 122 // | 122 // |
| 123 // Accessors::ArgumentsIterator | 123 // Accessors::ArgumentsIterator |
| 124 // | 124 // |
| 125 | 125 |
| 126 | 126 |
| 127 void Accessors::ArgumentsIteratorGetter( | 127 void Accessors::ArgumentsIteratorGetter( |
| 128 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | 128 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 129 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 129 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 151 v8::Local<v8::Name> name, | 151 v8::Local<v8::Name> name, |
| 152 const v8::PropertyCallbackInfo<v8::Value>& info) { | 152 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 153 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 153 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 154 DisallowHeapAllocation no_allocation; | 154 DisallowHeapAllocation no_allocation; |
| 155 HandleScope scope(isolate); | 155 HandleScope scope(isolate); |
| 156 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder())); | 156 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder())); |
| 157 Object* result = holder->length(); | 157 Object* result = holder->length(); |
| 158 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); | 158 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); |
| 159 } | 159 } |
| 160 | 160 |
| 161 | |
| 162 void Accessors::ArrayLengthSetter( | 161 void Accessors::ArrayLengthSetter( |
| 163 v8::Local<v8::Name> name, | 162 v8::Local<v8::Name> name, v8::Local<v8::Value> val, |
| 164 v8::Local<v8::Value> val, | 163 const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
| 165 const v8::PropertyCallbackInfo<void>& info) { | |
| 166 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 167 HandleScope scope(isolate); | 165 HandleScope scope(isolate); |
| 168 | 166 |
| 169 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder()); | 167 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder()); |
| 170 Handle<JSArray> array = Handle<JSArray>::cast(object); | 168 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 171 Handle<Object> length_obj = Utils::OpenHandle(*val); | 169 Handle<Object> length_obj = Utils::OpenHandle(*val); |
| 172 | 170 |
| 173 uint32_t length = 0; | 171 uint32_t length = 0; |
| 174 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { | 172 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) { |
| 175 isolate->OptionalRescheduleException(false); | 173 isolate->OptionalRescheduleException(false); |
| 176 return; | 174 return; |
| 177 } | 175 } |
| 178 | 176 |
| 179 JSArray::SetLength(array, length); | 177 JSArray::SetLength(array, length); |
| 180 | 178 |
| 181 if (info.ShouldThrowOnError()) { | 179 uint32_t actual_new_len = 0; |
| 182 uint32_t actual_new_len = 0; | 180 CHECK(array->length()->ToArrayLength(&actual_new_len)); |
| 183 CHECK(array->length()->ToArrayLength(&actual_new_len)); | 181 // Fail if there were non-deletable elements. |
| 184 // Throw TypeError if there were non-deletable elements. | 182 if (actual_new_len != length) { |
| 185 if (actual_new_len != length) { | 183 if (info.ShouldThrowOnError()) { |
| 186 Factory* factory = isolate->factory(); | 184 Factory* factory = isolate->factory(); |
| 187 isolate->Throw(*factory->NewTypeError( | 185 isolate->Throw(*factory->NewTypeError( |
| 188 MessageTemplate::kStrictDeleteProperty, | 186 MessageTemplate::kStrictDeleteProperty, |
| 189 factory->NewNumberFromUint(actual_new_len - 1), array)); | 187 factory->NewNumberFromUint(actual_new_len - 1), array)); |
| 190 isolate->OptionalRescheduleException(false); | 188 isolate->OptionalRescheduleException(false); |
| 189 } else { |
| 190 info.GetReturnValue().Set(false); |
| 191 } | 191 } |
| 192 } else { |
| 193 info.GetReturnValue().Set(true); |
| 192 } | 194 } |
| 193 } | 195 } |
| 194 | 196 |
| 195 | 197 |
| 196 Handle<AccessorInfo> Accessors::ArrayLengthInfo( | 198 Handle<AccessorInfo> Accessors::ArrayLengthInfo( |
| 197 Isolate* isolate, PropertyAttributes attributes) { | 199 Isolate* isolate, PropertyAttributes attributes) { |
| 198 return MakeAccessor(isolate, | 200 return MakeAccessor(isolate, |
| 199 isolate->factory()->length_string(), | 201 isolate->factory()->length_string(), |
| 200 &ArrayLengthGetter, | 202 &ArrayLengthGetter, |
| 201 &ArrayLengthSetter, | 203 &ArrayLengthSetter, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 216 if (!holder->GetExport(Handle<String>::cast(Utils::OpenHandle(*name))) | 218 if (!holder->GetExport(Handle<String>::cast(Utils::OpenHandle(*name))) |
| 217 .ToHandle(&result)) { | 219 .ToHandle(&result)) { |
| 218 isolate->OptionalRescheduleException(false); | 220 isolate->OptionalRescheduleException(false); |
| 219 } else { | 221 } else { |
| 220 info.GetReturnValue().Set(Utils::ToLocal(result)); | 222 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 221 } | 223 } |
| 222 } | 224 } |
| 223 | 225 |
| 224 void Accessors::ModuleNamespaceEntrySetter( | 226 void Accessors::ModuleNamespaceEntrySetter( |
| 225 v8::Local<v8::Name> name, v8::Local<v8::Value> val, | 227 v8::Local<v8::Name> name, v8::Local<v8::Value> val, |
| 226 const v8::PropertyCallbackInfo<void>& info) { | 228 const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
| 227 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 229 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 228 HandleScope scope(isolate); | 230 HandleScope scope(isolate); |
| 229 Factory* factory = isolate->factory(); | 231 Factory* factory = isolate->factory(); |
| 230 Handle<JSModuleNamespace> holder = | 232 Handle<JSModuleNamespace> holder = |
| 231 Handle<JSModuleNamespace>::cast(Utils::OpenHandle(*info.Holder())); | 233 Handle<JSModuleNamespace>::cast(Utils::OpenHandle(*info.Holder())); |
| 232 | 234 |
| 233 if (info.ShouldThrowOnError()) { | 235 if (info.ShouldThrowOnError()) { |
| 234 isolate->Throw(*factory->NewTypeError( | 236 isolate->Throw(*factory->NewTypeError( |
| 235 MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name), | 237 MessageTemplate::kStrictReadOnlyProperty, Utils::OpenHandle(*name), |
| 236 i::Object::TypeOf(isolate, holder), holder)); | 238 i::Object::TypeOf(isolate, holder), holder)); |
| 237 isolate->OptionalRescheduleException(false); | 239 isolate->OptionalRescheduleException(false); |
| 238 } else { | 240 } else { |
| 239 info.GetReturnValue().Set(Utils::ToLocal(factory->ToBoolean(false))); | 241 info.GetReturnValue().Set(false); |
| 240 } | 242 } |
| 241 } | 243 } |
| 242 | 244 |
| 243 Handle<AccessorInfo> Accessors::ModuleNamespaceEntryInfo( | 245 Handle<AccessorInfo> Accessors::ModuleNamespaceEntryInfo( |
| 244 Isolate* isolate, Handle<String> name, PropertyAttributes attributes) { | 246 Isolate* isolate, Handle<String> name, PropertyAttributes attributes) { |
| 245 return MakeAccessor(isolate, name, &ModuleNamespaceEntryGetter, | 247 return MakeAccessor(isolate, name, &ModuleNamespaceEntryGetter, |
| 246 &ModuleNamespaceEntrySetter, attributes); | 248 &ModuleNamespaceEntrySetter, attributes); |
| 247 } | 249 } |
| 248 | 250 |
| 249 | 251 |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 v8::Local<v8::Name> name, | 737 v8::Local<v8::Name> name, |
| 736 const v8::PropertyCallbackInfo<v8::Value>& info) { | 738 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 737 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 739 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 738 HandleScope scope(isolate); | 740 HandleScope scope(isolate); |
| 739 Handle<JSFunction> function = | 741 Handle<JSFunction> function = |
| 740 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 742 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 741 Handle<Object> result = GetFunctionPrototype(isolate, function); | 743 Handle<Object> result = GetFunctionPrototype(isolate, function); |
| 742 info.GetReturnValue().Set(Utils::ToLocal(result)); | 744 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 743 } | 745 } |
| 744 | 746 |
| 745 | |
| 746 void Accessors::FunctionPrototypeSetter( | 747 void Accessors::FunctionPrototypeSetter( |
| 747 v8::Local<v8::Name> name, | 748 v8::Local<v8::Name> name, v8::Local<v8::Value> val, |
| 748 v8::Local<v8::Value> val, | 749 const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
| 749 const v8::PropertyCallbackInfo<void>& info) { | |
| 750 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 750 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 751 HandleScope scope(isolate); | 751 HandleScope scope(isolate); |
| 752 Handle<Object> value = Utils::OpenHandle(*val); | 752 Handle<Object> value = Utils::OpenHandle(*val); |
| 753 Handle<JSFunction> object = | 753 Handle<JSFunction> object = |
| 754 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 754 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 755 if (SetFunctionPrototype(isolate, object, value).is_null()) { | 755 if (SetFunctionPrototype(isolate, object, value).is_null()) { |
| 756 isolate->OptionalRescheduleException(false); | 756 isolate->OptionalRescheduleException(false); |
| 757 } else { |
| 758 info.GetReturnValue().Set(true); |
| 757 } | 759 } |
| 758 } | 760 } |
| 759 | 761 |
| 760 | 762 |
| 761 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo( | 763 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo( |
| 762 Isolate* isolate, PropertyAttributes attributes) { | 764 Isolate* isolate, PropertyAttributes attributes) { |
| 763 return MakeAccessor(isolate, | 765 return MakeAccessor(isolate, |
| 764 isolate->factory()->prototype_string(), | 766 isolate->factory()->prototype_string(), |
| 765 &FunctionPrototypeGetter, | 767 &FunctionPrototypeGetter, |
| 766 &FunctionPrototypeSetter, | 768 &FunctionPrototypeSetter, |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 if (!JSObject::GetProperty(holder, name).ToHandle(&formatted_stack_trace)) { | 1246 if (!JSObject::GetProperty(holder, name).ToHandle(&formatted_stack_trace)) { |
| 1245 isolate->OptionalRescheduleException(false); | 1247 isolate->OptionalRescheduleException(false); |
| 1246 return; | 1248 return; |
| 1247 } | 1249 } |
| 1248 } | 1250 } |
| 1249 | 1251 |
| 1250 v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace); | 1252 v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace); |
| 1251 info.GetReturnValue().Set(value); | 1253 info.GetReturnValue().Set(value); |
| 1252 } | 1254 } |
| 1253 | 1255 |
| 1254 void Accessors::ErrorStackSetter(v8::Local<v8::Name> name, | 1256 void Accessors::ErrorStackSetter( |
| 1255 v8::Local<v8::Value> val, | 1257 v8::Local<v8::Name> name, v8::Local<v8::Value> val, |
| 1256 const v8::PropertyCallbackInfo<void>& info) { | 1258 const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
| 1257 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 1259 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 1258 HandleScope scope(isolate); | 1260 HandleScope scope(isolate); |
| 1259 Handle<JSObject> obj = | 1261 Handle<JSObject> obj = |
| 1260 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | 1262 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); |
| 1261 | 1263 |
| 1262 // Clear internal properties to avoid memory leaks. | 1264 // Clear internal properties to avoid memory leaks. |
| 1263 Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol(); | 1265 Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol(); |
| 1264 if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) { | 1266 if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) { |
| 1265 ClearInternalStackTrace(isolate, obj); | 1267 ClearInternalStackTrace(isolate, obj); |
| 1266 } | 1268 } |
| 1267 | 1269 |
| 1268 Accessors::ReconfigureToDataProperty(name, val, info); | 1270 Accessors::ReconfigureToDataProperty(name, val, info); |
| 1269 } | 1271 } |
| 1270 | 1272 |
| 1271 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, | 1273 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, |
| 1272 PropertyAttributes attributes) { | 1274 PropertyAttributes attributes) { |
| 1273 Handle<AccessorInfo> info = | 1275 Handle<AccessorInfo> info = |
| 1274 MakeAccessor(isolate, isolate->factory()->stack_string(), | 1276 MakeAccessor(isolate, isolate->factory()->stack_string(), |
| 1275 &ErrorStackGetter, &ErrorStackSetter, attributes); | 1277 &ErrorStackGetter, &ErrorStackSetter, attributes); |
| 1276 return info; | 1278 return info; |
| 1277 } | 1279 } |
| 1278 | 1280 |
| 1279 } // namespace internal | 1281 } // namespace internal |
| 1280 } // namespace v8 | 1282 } // namespace v8 |
| OLD | NEW |