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 |