| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/compiler.h" | 9 #include "src/compiler.h" |
| 10 #include "src/contexts.h" | 10 #include "src/contexts.h" |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 Handle<String> name, | 129 Handle<String> name, |
| 130 int* object_offset); | 130 int* object_offset); |
| 131 | 131 |
| 132 | 132 |
| 133 template | 133 template |
| 134 bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type, | 134 bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type, |
| 135 Handle<String> name, | 135 Handle<String> name, |
| 136 int* object_offset); | 136 int* object_offset); |
| 137 | 137 |
| 138 | 138 |
| 139 bool SetPropertyOnInstanceIfInherited( |
| 140 Isolate* isolate, const v8::PropertyCallbackInfo<void>& info, |
| 141 v8::Local<v8::String> name, Handle<Object> value) { |
| 142 Handle<Object> holder = Utils::OpenHandle(*info.Holder()); |
| 143 Handle<Object> receiver = Utils::OpenHandle(*info.This()); |
| 144 if (*holder == *receiver) return false; |
| 145 if (receiver->IsJSObject()) { |
| 146 Handle<JSObject> object = Handle<JSObject>::cast(receiver); |
| 147 // This behaves sloppy since we lost the actual strict-mode. |
| 148 // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data |
| 149 // properties. |
| 150 if (!object->map()->is_extensible()) return true; |
| 151 JSObject::SetOwnPropertyIgnoreAttributes(object, Utils::OpenHandle(*name), |
| 152 value, NONE); |
| 153 } |
| 154 return true; |
| 155 } |
| 156 |
| 157 |
| 139 // | 158 // |
| 140 // Accessors::ArrayLength | 159 // Accessors::ArrayLength |
| 141 // | 160 // |
| 142 | 161 |
| 143 | 162 |
| 144 // The helper function will 'flatten' Number objects. | 163 // The helper function will 'flatten' Number objects. |
| 145 Handle<Object> Accessors::FlattenNumber(Isolate* isolate, | 164 Handle<Object> Accessors::FlattenNumber(Isolate* isolate, |
| 146 Handle<Object> value) { | 165 Handle<Object> value) { |
| 147 if (value->IsNumber() || !value->IsJSValue()) return value; | 166 if (value->IsNumber() || !value->IsJSValue()) return value; |
| 148 Handle<JSValue> wrapper = Handle<JSValue>::cast(value); | 167 Handle<JSValue> wrapper = Handle<JSValue>::cast(value); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 169 | 188 |
| 170 | 189 |
| 171 void Accessors::ArrayLengthSetter( | 190 void Accessors::ArrayLengthSetter( |
| 172 v8::Local<v8::String> name, | 191 v8::Local<v8::String> name, |
| 173 v8::Local<v8::Value> val, | 192 v8::Local<v8::Value> val, |
| 174 const v8::PropertyCallbackInfo<void>& info) { | 193 const v8::PropertyCallbackInfo<void>& info) { |
| 175 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 194 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 176 HandleScope scope(isolate); | 195 HandleScope scope(isolate); |
| 177 Handle<JSObject> object = Utils::OpenHandle(*info.This()); | 196 Handle<JSObject> object = Utils::OpenHandle(*info.This()); |
| 178 Handle<Object> value = Utils::OpenHandle(*val); | 197 Handle<Object> value = Utils::OpenHandle(*val); |
| 179 // This means one of the object's prototypes is a JSArray and the | 198 if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) { |
| 180 // object does not have a 'length' property. Calling SetProperty | |
| 181 // causes an infinite loop. | |
| 182 if (!object->IsJSArray()) { | |
| 183 // This behaves sloppy since we lost the actual strict-mode. | |
| 184 // TODO(verwaest): Fix by making ExecutableAccessorInfo behave like data | |
| 185 // properties. | |
| 186 if (!object->map()->is_extensible()) return; | |
| 187 MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( | |
| 188 object, isolate->factory()->length_string(), value, NONE); | |
| 189 maybe_result.Check(); | |
| 190 return; | 199 return; |
| 191 } | 200 } |
| 192 | 201 |
| 193 value = FlattenNumber(isolate, value); | 202 value = FlattenNumber(isolate, value); |
| 194 | 203 |
| 195 Handle<JSArray> array_handle = Handle<JSArray>::cast(object); | 204 Handle<JSArray> array_handle = Handle<JSArray>::cast(object); |
| 196 MaybeHandle<Object> maybe; | 205 MaybeHandle<Object> maybe; |
| 197 Handle<Object> uint32_v; | 206 Handle<Object> uint32_v; |
| 198 maybe = Execution::ToUint32(isolate, value); | 207 maybe = Execution::ToUint32(isolate, value); |
| 199 if (!maybe.ToHandle(&uint32_v)) { | 208 if (!maybe.ToHandle(&uint32_v)) { |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 Handle<JSFunction> function) { | 840 Handle<JSFunction> function) { |
| 832 if (!function->has_prototype()) { | 841 if (!function->has_prototype()) { |
| 833 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); | 842 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); |
| 834 JSFunction::SetPrototype(function, proto); | 843 JSFunction::SetPrototype(function, proto); |
| 835 } | 844 } |
| 836 return Handle<Object>(function->prototype(), isolate); | 845 return Handle<Object>(function->prototype(), isolate); |
| 837 } | 846 } |
| 838 | 847 |
| 839 | 848 |
| 840 static Handle<Object> SetFunctionPrototype(Isolate* isolate, | 849 static Handle<Object> SetFunctionPrototype(Isolate* isolate, |
| 841 Handle<JSObject> receiver, | 850 Handle<JSFunction> function, |
| 842 Handle<Object> value) { | 851 Handle<Object> value) { |
| 843 Handle<JSFunction> function; | |
| 844 { | |
| 845 DisallowHeapAllocation no_allocation; | |
| 846 JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver); | |
| 847 if (function_raw == NULL) return isolate->factory()->undefined_value(); | |
| 848 function = Handle<JSFunction>(function_raw, isolate); | |
| 849 } | |
| 850 | |
| 851 if (!function->should_have_prototype()) { | |
| 852 // Since we hit this accessor, object will have no prototype property. | |
| 853 MaybeHandle<Object> maybe_result = JSObject::SetOwnPropertyIgnoreAttributes( | |
| 854 receiver, isolate->factory()->prototype_string(), value, NONE); | |
| 855 return maybe_result.ToHandleChecked(); | |
| 856 } | |
| 857 | |
| 858 Handle<Object> old_value; | 852 Handle<Object> old_value; |
| 859 bool is_observed = *function == *receiver && function->map()->is_observed(); | 853 bool is_observed = function->map()->is_observed(); |
| 860 if (is_observed) { | 854 if (is_observed) { |
| 861 if (function->has_prototype()) | 855 if (function->has_prototype()) |
| 862 old_value = handle(function->prototype(), isolate); | 856 old_value = handle(function->prototype(), isolate); |
| 863 else | 857 else |
| 864 old_value = isolate->factory()->NewFunctionPrototype(function); | 858 old_value = isolate->factory()->NewFunctionPrototype(function); |
| 865 } | 859 } |
| 866 | 860 |
| 867 JSFunction::SetPrototype(function, value); | 861 JSFunction::SetPrototype(function, value); |
| 868 ASSERT(function->prototype() == *value); | 862 ASSERT(function->prototype() == *value); |
| 869 | 863 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 900 info.GetReturnValue().Set(Utils::ToLocal(result)); | 894 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 901 } | 895 } |
| 902 | 896 |
| 903 | 897 |
| 904 void Accessors::FunctionPrototypeSetter( | 898 void Accessors::FunctionPrototypeSetter( |
| 905 v8::Local<v8::String> name, | 899 v8::Local<v8::String> name, |
| 906 v8::Local<v8::Value> val, | 900 v8::Local<v8::Value> val, |
| 907 const v8::PropertyCallbackInfo<void>& info) { | 901 const v8::PropertyCallbackInfo<void>& info) { |
| 908 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | 902 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 909 HandleScope scope(isolate); | 903 HandleScope scope(isolate); |
| 910 Handle<JSObject> object = | |
| 911 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | |
| 912 Handle<Object> value = Utils::OpenHandle(*val); | 904 Handle<Object> value = Utils::OpenHandle(*val); |
| 913 | 905 if (SetPropertyOnInstanceIfInherited(isolate, info, name, value)) { |
| 906 return; |
| 907 } |
| 908 Handle<JSFunction> object = |
| 909 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 914 SetFunctionPrototype(isolate, object, value); | 910 SetFunctionPrototype(isolate, object, value); |
| 915 } | 911 } |
| 916 | 912 |
| 917 | 913 |
| 918 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo( | 914 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo( |
| 919 Isolate* isolate, PropertyAttributes attributes) { | 915 Isolate* isolate, PropertyAttributes attributes) { |
| 920 return MakeAccessor(isolate, | 916 return MakeAccessor(isolate, |
| 921 isolate->factory()->prototype_string(), | 917 isolate->factory()->prototype_string(), |
| 922 &FunctionPrototypeGetter, | 918 &FunctionPrototypeGetter, |
| 923 &FunctionPrototypeSetter, | 919 &FunctionPrototypeSetter, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 953 } | 949 } |
| 954 Handle<Object> result(Smi::FromInt(length), isolate); | 950 Handle<Object> result(Smi::FromInt(length), isolate); |
| 955 info.GetReturnValue().Set(Utils::ToLocal(result)); | 951 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 956 } | 952 } |
| 957 | 953 |
| 958 | 954 |
| 959 void Accessors::FunctionLengthSetter( | 955 void Accessors::FunctionLengthSetter( |
| 960 v8::Local<v8::String> name, | 956 v8::Local<v8::String> name, |
| 961 v8::Local<v8::Value> val, | 957 v8::Local<v8::Value> val, |
| 962 const v8::PropertyCallbackInfo<void>& info) { | 958 const v8::PropertyCallbackInfo<void>& info) { |
| 963 // Do nothing. | 959 // Function length is non writable, non configurable. |
| 960 UNREACHABLE(); |
| 964 } | 961 } |
| 965 | 962 |
| 966 | 963 |
| 967 Handle<AccessorInfo> Accessors::FunctionLengthInfo( | 964 Handle<AccessorInfo> Accessors::FunctionLengthInfo( |
| 968 Isolate* isolate, PropertyAttributes attributes) { | 965 Isolate* isolate, PropertyAttributes attributes) { |
| 969 return MakeAccessor(isolate, | 966 return MakeAccessor(isolate, |
| 970 isolate->factory()->length_string(), | 967 isolate->factory()->length_string(), |
| 971 &FunctionLengthGetter, | 968 &FunctionLengthGetter, |
| 972 &FunctionLengthSetter, | 969 &FunctionLengthSetter, |
| 973 attributes); | 970 attributes); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 988 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 985 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 989 Handle<Object> result(function->shared()->name(), isolate); | 986 Handle<Object> result(function->shared()->name(), isolate); |
| 990 info.GetReturnValue().Set(Utils::ToLocal(result)); | 987 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 991 } | 988 } |
| 992 | 989 |
| 993 | 990 |
| 994 void Accessors::FunctionNameSetter( | 991 void Accessors::FunctionNameSetter( |
| 995 v8::Local<v8::String> name, | 992 v8::Local<v8::String> name, |
| 996 v8::Local<v8::Value> val, | 993 v8::Local<v8::Value> val, |
| 997 const v8::PropertyCallbackInfo<void>& info) { | 994 const v8::PropertyCallbackInfo<void>& info) { |
| 998 // Do nothing. | 995 // Function name is non writable, non configurable. |
| 996 UNREACHABLE(); |
| 999 } | 997 } |
| 1000 | 998 |
| 1001 | 999 |
| 1002 Handle<AccessorInfo> Accessors::FunctionNameInfo( | 1000 Handle<AccessorInfo> Accessors::FunctionNameInfo( |
| 1003 Isolate* isolate, PropertyAttributes attributes) { | 1001 Isolate* isolate, PropertyAttributes attributes) { |
| 1004 return MakeAccessor(isolate, | 1002 return MakeAccessor(isolate, |
| 1005 isolate->factory()->name_string(), | 1003 isolate->factory()->name_string(), |
| 1006 &FunctionNameGetter, | 1004 &FunctionNameGetter, |
| 1007 &FunctionNameSetter, | 1005 &FunctionNameSetter, |
| 1008 attributes); | 1006 attributes); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); | 1122 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder())); |
| 1125 Handle<Object> result = GetFunctionArguments(isolate, function); | 1123 Handle<Object> result = GetFunctionArguments(isolate, function); |
| 1126 info.GetReturnValue().Set(Utils::ToLocal(result)); | 1124 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 1127 } | 1125 } |
| 1128 | 1126 |
| 1129 | 1127 |
| 1130 void Accessors::FunctionArgumentsSetter( | 1128 void Accessors::FunctionArgumentsSetter( |
| 1131 v8::Local<v8::String> name, | 1129 v8::Local<v8::String> name, |
| 1132 v8::Local<v8::Value> val, | 1130 v8::Local<v8::Value> val, |
| 1133 const v8::PropertyCallbackInfo<void>& info) { | 1131 const v8::PropertyCallbackInfo<void>& info) { |
| 1134 // Do nothing. | 1132 // Function arguments is non writable, non configurable. |
| 1133 UNREACHABLE(); |
| 1135 } | 1134 } |
| 1136 | 1135 |
| 1137 | 1136 |
| 1138 Handle<AccessorInfo> Accessors::FunctionArgumentsInfo( | 1137 Handle<AccessorInfo> Accessors::FunctionArgumentsInfo( |
| 1139 Isolate* isolate, PropertyAttributes attributes) { | 1138 Isolate* isolate, PropertyAttributes attributes) { |
| 1140 return MakeAccessor(isolate, | 1139 return MakeAccessor(isolate, |
| 1141 isolate->factory()->arguments_string(), | 1140 isolate->factory()->arguments_string(), |
| 1142 &FunctionArgumentsGetter, | 1141 &FunctionArgumentsGetter, |
| 1143 &FunctionArgumentsSetter, | 1142 &FunctionArgumentsSetter, |
| 1144 attributes); | 1143 attributes); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 result = isolate->factory()->null_value(); | 1273 result = isolate->factory()->null_value(); |
| 1275 } | 1274 } |
| 1276 info.GetReturnValue().Set(Utils::ToLocal(result)); | 1275 info.GetReturnValue().Set(Utils::ToLocal(result)); |
| 1277 } | 1276 } |
| 1278 | 1277 |
| 1279 | 1278 |
| 1280 void Accessors::FunctionCallerSetter( | 1279 void Accessors::FunctionCallerSetter( |
| 1281 v8::Local<v8::String> name, | 1280 v8::Local<v8::String> name, |
| 1282 v8::Local<v8::Value> val, | 1281 v8::Local<v8::Value> val, |
| 1283 const v8::PropertyCallbackInfo<void>& info) { | 1282 const v8::PropertyCallbackInfo<void>& info) { |
| 1284 // Do nothing. | 1283 // Function caller is non writable, non configurable. |
| 1284 UNREACHABLE(); |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 | 1287 |
| 1288 Handle<AccessorInfo> Accessors::FunctionCallerInfo( | 1288 Handle<AccessorInfo> Accessors::FunctionCallerInfo( |
| 1289 Isolate* isolate, PropertyAttributes attributes) { | 1289 Isolate* isolate, PropertyAttributes attributes) { |
| 1290 return MakeAccessor(isolate, | 1290 return MakeAccessor(isolate, |
| 1291 isolate->factory()->caller_string(), | 1291 isolate->factory()->caller_string(), |
| 1292 &FunctionCallerGetter, | 1292 &FunctionCallerGetter, |
| 1293 &FunctionCallerSetter, | 1293 &FunctionCallerSetter, |
| 1294 attributes); | 1294 attributes); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1354 info->set_data(Smi::FromInt(index)); | 1354 info->set_data(Smi::FromInt(index)); |
| 1355 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); | 1355 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); |
| 1356 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); | 1356 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); |
| 1357 info->set_getter(*getter); | 1357 info->set_getter(*getter); |
| 1358 if (!(attributes & ReadOnly)) info->set_setter(*setter); | 1358 if (!(attributes & ReadOnly)) info->set_setter(*setter); |
| 1359 return info; | 1359 return info; |
| 1360 } | 1360 } |
| 1361 | 1361 |
| 1362 | 1362 |
| 1363 } } // namespace v8::internal | 1363 } } // namespace v8::internal |
| OLD | NEW |