Chromium Code Reviews| 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 bool IsErrorObject(Isolate* isolate, Handle<JSObject> receiver) { | |
| 1126 // Anything which has a stack_trace symbol property is considered as an error | |
| 1127 // object. This is obviously the case for standard error objects such as | |
| 1128 // Error and ReferenceError; but the user can also create error-like objects | |
| 1129 // by calling Error.captureStackTrace. | |
| 1130 Maybe<bool> ret = JSReceiver::HasOwnProperty( | |
| 1131 receiver, isolate->factory()->stack_trace_symbol()); | |
| 1132 return ret.IsJust() && ret.FromJust(); | |
| 1133 } | |
| 1134 | |
| 1135 MaybeHandle<JSReceiver> SetFormattedTrace(Isolate* isolate, | |
| 1136 Handle<JSObject> error, | |
| 1137 Handle<Object> value) { | |
| 1138 RETURN_ON_EXCEPTION( | |
| 1139 isolate, | |
| 1140 JSReceiver::SetProperty(error, isolate->factory()->stack_trace_symbol(), | |
| 1141 isolate->factory()->undefined_value(), STRICT), | |
| 1142 JSReceiver); | |
| 1143 RETURN_ON_EXCEPTION( | |
| 1144 isolate, JSReceiver::SetProperty( | |
| 1145 error, isolate->factory()->formatted_stack_trace_symbol(), | |
|
Yang
2016/07/15 13:10:11
How about we simply reconfigure the "stack" proper
jgruber
2016/07/18 13:06:11
Good idea, done.
| |
| 1146 value, STRICT), | |
| 1147 JSReceiver); | |
| 1148 return error; | |
| 1149 } | |
| 1150 | |
| 1151 MaybeHandle<Object> FormatStackTrace(Isolate* isolate, Handle<JSObject> error, | |
| 1152 Handle<Object> stack_trace) { | |
| 1153 // TODO(jgruber): Port FormatStackTrace from JS. | |
| 1154 Handle<JSFunction> fun = isolate->error_format_stack_trace(); | |
| 1155 | |
| 1156 int argc = 2; | |
| 1157 ScopedVector<Handle<Object>> argv(argc); | |
| 1158 argv[0] = error; | |
| 1159 argv[1] = stack_trace; | |
| 1160 | |
| 1161 Handle<Object> formatted_stack_trace; | |
| 1162 ASSIGN_RETURN_ON_EXCEPTION( | |
| 1163 isolate, formatted_stack_trace, | |
| 1164 Execution::Call(isolate, fun, error, argc, argv.start()), Object); | |
| 1165 | |
| 1166 return formatted_stack_trace; | |
| 1167 } | |
| 1168 | |
| 1169 bool MaybeGetProperty(Isolate* isolate, Handle<JSObject> obj, | |
|
Yang
2016/07/15 13:10:11
We can inline this once this only has one call sit
jgruber
2016/07/18 13:06:11
Done.
| |
| 1170 Handle<Symbol> symbol, Handle<Object>* out) { | |
| 1171 MaybeHandle<Object> maybe = JSObject::GetProperty(obj, symbol); | |
| 1172 if (!maybe.ToHandle(out)) return false; | |
| 1173 return !(*out)->IsUndefined(isolate); | |
| 1174 } | |
| 1175 | |
| 1176 } // namespace | |
| 1177 | |
| 1178 void Accessors::ErrorStackGetter( | |
| 1179 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { | |
| 1180 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
| 1181 HandleScope scope(isolate); | |
| 1182 Handle<Object> obj = Utils::OpenHandle(*info.Holder()); | |
| 1183 | |
| 1184 while (obj->IsJSObject()) { | |
| 1185 Handle<JSObject> holder = Handle<JSObject>::cast(obj); | |
| 1186 Handle<Object> formatted_stack_trace; | |
| 1187 Handle<Symbol> fst_symbol = | |
| 1188 isolate->factory()->formatted_stack_trace_symbol(); | |
| 1189 if (!MaybeGetProperty(isolate, holder, fst_symbol, | |
| 1190 &formatted_stack_trace)) { | |
| 1191 // No formatted stack trace available. | |
| 1192 Handle<Object> stack_trace; | |
| 1193 Handle<Symbol> st_symbol = isolate->factory()->stack_trace_symbol(); | |
| 1194 if (!MaybeGetProperty(isolate, holder, st_symbol, &stack_trace)) { | |
| 1195 // Neither formatted nor structured stack trace available. | |
| 1196 // Look further up the prototype chain. | |
| 1197 obj = JSReceiver::GetPrototype(isolate, holder).ToHandleChecked(); | |
| 1198 continue; | |
| 1199 } | |
| 1200 | |
| 1201 if (!FormatStackTrace(isolate, holder, stack_trace) | |
| 1202 .ToHandle(&formatted_stack_trace)) { | |
| 1203 isolate->OptionalRescheduleException(false); | |
| 1204 return; | |
| 1205 } | |
| 1206 | |
| 1207 if (SetFormattedTrace(isolate, holder, formatted_stack_trace).is_null()) { | |
| 1208 isolate->OptionalRescheduleException(false); | |
| 1209 return; | |
| 1210 } | |
| 1211 } | |
| 1212 | |
| 1213 info.GetReturnValue().Set(Utils::ToLocal(formatted_stack_trace)); | |
| 1214 return; | |
| 1215 } | |
| 1216 | |
| 1217 Handle<Object> result = isolate->factory()->undefined_value(); | |
| 1218 info.GetReturnValue().Set(Utils::ToLocal(result)); | |
| 1219 } | |
| 1220 | |
| 1221 void Accessors::ErrorStackSetter(v8::Local<v8::Name> name, | |
| 1222 v8::Local<v8::Value> val, | |
| 1223 const v8::PropertyCallbackInfo<void>& info) { | |
| 1224 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); | |
| 1225 HandleScope scope(isolate); | |
| 1226 Handle<JSObject> obj = | |
| 1227 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); | |
| 1228 | |
| 1229 // Clear internal properties to avoid memory leaks. | |
| 1230 if (IsErrorObject(isolate, obj)) { | |
|
Yang
2016/07/15 13:10:11
I would just do this check inline (instead of defi
jgruber
2016/07/18 13:06:11
Done.
| |
| 1231 SetFormattedTrace(isolate, obj, isolate->factory()->undefined_value()); | |
| 1232 } | |
| 1233 | |
| 1234 Accessors::ReconfigureToDataProperty(name, val, info); | |
| 1235 } | |
| 1236 | |
| 1237 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, | |
| 1238 PropertyAttributes attributes) { | |
| 1239 Handle<AccessorInfo> info = | |
| 1240 MakeAccessor(isolate, isolate->factory()->stack_string(), | |
| 1241 &ErrorStackGetter, &ErrorStackSetter, attributes); | |
| 1242 return info; | |
| 1243 } | |
| 1119 | 1244 |
| 1120 } // namespace internal | 1245 } // namespace internal |
| 1121 } // namespace v8 | 1246 } // namespace v8 |
| OLD | NEW |