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 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1109 info.GetReturnValue().Set(Utils::ToLocal(result)); | 1109 info.GetReturnValue().Set(Utils::ToLocal(result)); |
1110 } | 1110 } |
1111 | 1111 |
1112 Handle<AccessorInfo> Accessors::BoundFunctionNameInfo( | 1112 Handle<AccessorInfo> Accessors::BoundFunctionNameInfo( |
1113 Isolate* isolate, PropertyAttributes attributes) { | 1113 Isolate* isolate, PropertyAttributes attributes) { |
1114 return MakeAccessor(isolate, isolate->factory()->name_string(), | 1114 return MakeAccessor(isolate, isolate->factory()->name_string(), |
1115 &BoundFunctionNameGetter, &ReconfigureToDataProperty, | 1115 &BoundFunctionNameGetter, &ReconfigureToDataProperty, |
1116 attributes); | 1116 attributes); |
1117 } | 1117 } |
1118 | 1118 |
1119 // | |
1120 // Accessors::ErrorStack | |
1121 // | |
1122 | |
1123 namespace { | |
1124 | |
1125 MaybeHandle<JSReceiver> ClearInternalStackTrace(Isolate* isolate, | |
1126 Handle<JSObject> error) { | |
1127 RETURN_ON_EXCEPTION( | |
1128 isolate, | |
1129 JSReceiver::SetProperty(error, isolate->factory()->stack_trace_symbol(), | |
1130 isolate->factory()->undefined_value(), STRICT), | |
1131 JSReceiver); | |
1132 return error; | |
1133 } | |
1134 | |
1135 MaybeHandle<Object> FormatStackTrace(Isolate* isolate, Handle<JSObject> error, | |
1136 Handle<Object> stack_trace) { | |
1137 // TODO(jgruber): Port FormatStackTrace from JS. | |
1138 Handle<JSFunction> fun = isolate->error_format_stack_trace(); | |
1139 | |
1140 int argc = 2; | |
1141 ScopedVector<Handle<Object>> argv(argc); | |
1142 argv[0] = error; | |
1143 argv[1] = stack_trace; | |
1144 | |
1145 Handle<Object> formatted_stack_trace; | |
1146 ASSIGN_RETURN_ON_EXCEPTION( | |
1147 isolate, formatted_stack_trace, | |
1148 Execution::Call(isolate, fun, error, argc, argv.start()), Object); | |
1149 | |
1150 return formatted_stack_trace; | |
1151 } | |
1152 | |
1153 bool IsAccessor(Handle<Object> receiver, Handle<Name> name, | |
1154 Handle<JSObject> holder) { | |
1155 LookupIterator it(receiver, name, holder, | |
1156 LookupIterator::OWN_SKIP_INTERCEPTOR); | |
1157 // Skip any access checks we might hit. This accessor should never hit in a | |
1158 // situation where the caller does not have access. | |
1159 if (it.state() == LookupIterator::ACCESS_CHECK) { | |
1160 CHECK(it.HasAccess()); | |
1161 it.Next(); | |
1162 } | |
1163 return (it.state() == LookupIterator::ACCESSOR); | |
1164 } | |
1165 | |
1166 } // namespace | |
1167 | |
1168 void Accessors::ErrorStackGetter( | |
1169 v8::Local<v8::Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
1170 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
1171 HandleScope scope(isolate); | |
1172 Handle<JSObject> holder = | |
1173 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder())); | |
1174 | |
1175 // Retrieve the structured stack trace. | |
1176 | |
1177 Handle<Object> stack_trace; | |
1178 Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol(); | |
1179 MaybeHandle<Object> maybe_stack_trace = | |
1180 JSObject::GetProperty(holder, stack_trace_symbol); | |
1181 if (!maybe_stack_trace.ToHandle(&stack_trace) || | |
1182 stack_trace->IsUndefined(isolate)) { | |
1183 Handle<Object> result = isolate->factory()->undefined_value(); | |
1184 info.GetReturnValue().Set(Utils::ToLocal(result)); | |
1185 return; | |
1186 } | |
1187 | |
1188 // Format it, clear the internal structured trace and reconfigure as a data | |
1189 // property. | |
1190 | |
1191 Handle<Object> formatted_stack_trace; | |
1192 if (!FormatStackTrace(isolate, holder, stack_trace) | |
1193 .ToHandle(&formatted_stack_trace)) { | |
1194 isolate->OptionalRescheduleException(false); | |
1195 return; | |
1196 } | |
1197 | |
1198 MaybeHandle<Object> result = ClearInternalStackTrace(isolate, holder); | |
1199 if (result.is_null()) { | |
1200 isolate->OptionalRescheduleException(false); | |
1201 return; | |
1202 } | |
1203 | |
1204 // If stack is still an accessor (this could have changed in the meantime | |
1205 // since FormatStackTrace can execute arbitrary JS), replace it with a data | |
1206 // property. | |
1207 Handle<Object> receiver = Utils::OpenHandle(*info.This()); | |
1208 Handle<Name> name = Utils::OpenHandle(*key); | |
1209 if (IsAccessor(receiver, name, holder)) { | |
1210 result = ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, | |
1211 formatted_stack_trace); | |
1212 if (result.is_null()) { | |
1213 isolate->OptionalRescheduleException(false); | |
1214 return; | |
1215 } | |
1216 } else { | |
1217 // The stack property has been modified in the meantime. | |
1218 if (!JSObject::GetProperty(holder, name).ToHandle(&formatted_stack_trace)) { | |
Yang
2016/07/20 12:07:51
In this case we would have an exception. We should
jgruber
2016/07/20 12:14:11
Done.
| |
1219 formatted_stack_trace = isolate->factory()->undefined_value(); | |
1220 } | |
1221 } | |
1222 | |
1223 v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace); | |
1224 info.GetReturnValue().Set(value); | |
1225 } | |
1226 | |
1227 void Accessors::ErrorStackSetter(v8::Local<v8::Name> name, | |
1228 v8::Local<v8::Value> val, | |
1229 const v8::PropertyCallbackInfo<void>& info) { | |
1230 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
1231 HandleScope scope(isolate); | |
1232 Handle<JSObject> obj = | |
1233 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | |
1234 | |
1235 // Clear internal properties to avoid memory leaks. | |
1236 Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol(); | |
1237 if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) { | |
1238 ClearInternalStackTrace(isolate, obj); | |
1239 } | |
1240 | |
1241 Accessors::ReconfigureToDataProperty(name, val, info); | |
1242 } | |
1243 | |
1244 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, | |
1245 PropertyAttributes attributes) { | |
1246 Handle<AccessorInfo> info = | |
1247 MakeAccessor(isolate, isolate->factory()->stack_string(), | |
1248 &ErrorStackGetter, &ErrorStackSetter, attributes); | |
1249 return info; | |
1250 } | |
1119 | 1251 |
1120 } // namespace internal | 1252 } // namespace internal |
1121 } // namespace v8 | 1253 } // namespace v8 |
OLD | NEW |