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)) { |
| 1219 isolate->OptionalRescheduleException(false); |
| 1220 return; |
| 1221 } |
| 1222 } |
| 1223 |
| 1224 v8::Local<v8::Value> value = Utils::ToLocal(formatted_stack_trace); |
| 1225 info.GetReturnValue().Set(value); |
| 1226 } |
| 1227 |
| 1228 void Accessors::ErrorStackSetter(v8::Local<v8::Name> name, |
| 1229 v8::Local<v8::Value> val, |
| 1230 const v8::PropertyCallbackInfo<void>& info) { |
| 1231 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); |
| 1232 HandleScope scope(isolate); |
| 1233 Handle<JSObject> obj = |
| 1234 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); |
| 1235 |
| 1236 // Clear internal properties to avoid memory leaks. |
| 1237 Handle<Symbol> stack_trace_symbol = isolate->factory()->stack_trace_symbol(); |
| 1238 if (JSReceiver::HasOwnProperty(obj, stack_trace_symbol).FromMaybe(false)) { |
| 1239 ClearInternalStackTrace(isolate, obj); |
| 1240 } |
| 1241 |
| 1242 Accessors::ReconfigureToDataProperty(name, val, info); |
| 1243 } |
| 1244 |
| 1245 Handle<AccessorInfo> Accessors::ErrorStackInfo(Isolate* isolate, |
| 1246 PropertyAttributes attributes) { |
| 1247 Handle<AccessorInfo> info = |
| 1248 MakeAccessor(isolate, isolate->factory()->stack_string(), |
| 1249 &ErrorStackGetter, &ErrorStackSetter, attributes); |
| 1250 return info; |
| 1251 } |
1119 | 1252 |
1120 } // namespace internal | 1253 } // namespace internal |
1121 } // namespace v8 | 1254 } // namespace v8 |
OLD | NEW |