OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/objects.h" | 5 #include "src/objects.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 #include <iomanip> | 8 #include <iomanip> |
9 #include <memory> | 9 #include <memory> |
10 #include <sstream> | 10 #include <sstream> |
(...skipping 13124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13135 return MaybeHandle<SharedFunctionInfo>(); | 13135 return MaybeHandle<SharedFunctionInfo>(); |
13136 } | 13136 } |
13137 | 13137 |
13138 | 13138 |
13139 Script::Iterator::Iterator(Isolate* isolate) | 13139 Script::Iterator::Iterator(Isolate* isolate) |
13140 : iterator_(isolate->heap()->script_list()) {} | 13140 : iterator_(isolate->heap()->script_list()) {} |
13141 | 13141 |
13142 | 13142 |
13143 Script* Script::Iterator::Next() { return iterator_.Next<Script>(); } | 13143 Script* Script::Iterator::Next() { return iterator_.Next<Script>(); } |
13144 | 13144 |
| 13145 namespace { |
| 13146 |
| 13147 int JSSTGetPosition(Handle<StackTraceFrame> frame) { |
| 13148 DCHECK(frame->IsJavaScriptFrame()); |
| 13149 return frame->abstract_code()->SourcePosition(frame->offset()); |
| 13150 } |
| 13151 |
| 13152 Handle<Object> JSSTGetFileName(Handle<StackTraceFrame> frame) { |
| 13153 DCHECK(frame->IsJavaScriptFrame()); |
| 13154 Isolate* isolate = frame->GetIsolate(); |
| 13155 Object* script = frame->function()->shared()->script(); |
| 13156 if (!script->IsScript()) return isolate->factory()->null_value(); |
| 13157 return Handle<Object>(Script::cast(script)->name(), isolate); |
| 13158 } |
| 13159 |
| 13160 Handle<Object> JSSTGetFunctionName(Handle<StackTraceFrame> frame) { |
| 13161 DCHECK(frame->IsJavaScriptFrame()); |
| 13162 Isolate* isolate = frame->GetIsolate(); |
| 13163 |
| 13164 Handle<JSFunction> function = handle(frame->function()); |
| 13165 Handle<String> result = JSFunction::GetName(function); |
| 13166 if (result->length() != 0) return result; |
| 13167 |
| 13168 Handle<Object> script(function->shared()->script(), isolate); |
| 13169 if (script->IsScript() && |
| 13170 Handle<Script>::cast(script)->compilation_type() == |
| 13171 Script::COMPILATION_TYPE_EVAL) { |
| 13172 return isolate->factory()->eval_string(); |
| 13173 } |
| 13174 |
| 13175 return isolate->factory()->null_value(); |
| 13176 } |
| 13177 |
| 13178 Handle<Object> JSSTGetScriptNameOrSourceUrl(Handle<StackTraceFrame> frame) { |
| 13179 DCHECK(frame->IsJavaScriptFrame()); |
| 13180 Isolate* isolate = frame->GetIsolate(); |
| 13181 |
| 13182 Object* script_obj = frame->function()->shared()->script(); |
| 13183 if (!script_obj->IsScript()) return isolate->factory()->null_value(); |
| 13184 |
| 13185 Handle<Script> script(Script::cast(script_obj), isolate); |
| 13186 Object* source_url = script->source_url(); |
| 13187 if (source_url->IsString()) return Handle<Object>(source_url, isolate); |
| 13188 |
| 13189 return Handle<Object>(script->name(), isolate); |
| 13190 } |
| 13191 |
| 13192 bool CheckMethodName(Isolate* isolate, Handle<JSObject> obj, Handle<Name> name, |
| 13193 Handle<JSFunction> fun, |
| 13194 LookupIterator::Configuration config) { |
| 13195 LookupIterator iter = |
| 13196 LookupIterator::PropertyOrElement(isolate, obj, name, config); |
| 13197 if (iter.state() == LookupIterator::DATA) { |
| 13198 return iter.GetDataValue().is_identical_to(fun); |
| 13199 } else if (iter.state() == LookupIterator::ACCESSOR) { |
| 13200 Handle<Object> accessors = iter.GetAccessors(); |
| 13201 if (accessors->IsAccessorPair()) { |
| 13202 Handle<AccessorPair> pair = Handle<AccessorPair>::cast(accessors); |
| 13203 return pair->getter() == *fun || pair->setter() == *fun; |
| 13204 } |
| 13205 } |
| 13206 return false; |
| 13207 } |
| 13208 |
| 13209 Handle<Object> JSSTGetMethodName(Handle<StackTraceFrame> frame) { |
| 13210 DCHECK(frame->IsJavaScriptFrame()); |
| 13211 Isolate* isolate = frame->GetIsolate(); |
| 13212 Handle<JSFunction> fun = handle(frame->function()); |
| 13213 Handle<Object> recv_obj = handle(frame->receiver(), isolate); |
| 13214 |
| 13215 if (recv_obj->IsNull(isolate) || recv_obj->IsUndefined(isolate)) { |
| 13216 return isolate->factory()->null_value(); |
| 13217 } |
| 13218 |
| 13219 Handle<JSReceiver> recv = |
| 13220 Object::ToObject(isolate, recv_obj).ToHandleChecked(); |
| 13221 if (!recv->IsJSObject()) { |
| 13222 return isolate->factory()->null_value(); |
| 13223 } |
| 13224 |
| 13225 Handle<JSObject> obj = Handle<JSObject>::cast(recv); |
| 13226 Handle<Object> function_name(fun->shared()->name(), isolate); |
| 13227 if (function_name->IsString()) { |
| 13228 Handle<String> name = Handle<String>::cast(function_name); |
| 13229 // ES2015 gives getters and setters name prefixes which must |
| 13230 // be stripped to find the property name. |
| 13231 if (name->IsUtf8EqualTo(CStrVector("get "), true) || |
| 13232 name->IsUtf8EqualTo(CStrVector("set "), true)) { |
| 13233 name = isolate->factory()->NewProperSubString(name, 4, name->length()); |
| 13234 } |
| 13235 if (CheckMethodName(isolate, obj, name, fun, |
| 13236 LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR)) { |
| 13237 return name; |
| 13238 } |
| 13239 } |
| 13240 |
| 13241 HandleScope outer_scope(isolate); |
| 13242 Handle<Object> result; |
| 13243 for (PrototypeIterator iter(isolate, obj, kStartAtReceiver); !iter.IsAtEnd(); |
| 13244 iter.Advance()) { |
| 13245 Handle<Object> current = PrototypeIterator::GetCurrent(iter); |
| 13246 if (!current->IsJSObject()) break; |
| 13247 Handle<JSObject> current_obj = Handle<JSObject>::cast(current); |
| 13248 if (current_obj->IsAccessCheckNeeded()) break; |
| 13249 Handle<FixedArray> keys = |
| 13250 KeyAccumulator::GetOwnEnumPropertyKeys(isolate, current_obj); |
| 13251 for (int i = 0; i < keys->length(); i++) { |
| 13252 HandleScope inner_scope(isolate); |
| 13253 if (!keys->get(i)->IsName()) continue; |
| 13254 Handle<Name> name_key(Name::cast(keys->get(i)), isolate); |
| 13255 if (!CheckMethodName(isolate, current_obj, name_key, fun, |
| 13256 LookupIterator::OWN_SKIP_INTERCEPTOR)) { |
| 13257 continue; |
| 13258 } |
| 13259 // Return null in case of duplicates to avoid confusion. |
| 13260 if (!result.is_null()) return isolate->factory()->null_value(); |
| 13261 result = inner_scope.CloseAndEscape(name_key); |
| 13262 } |
| 13263 } |
| 13264 |
| 13265 if (!result.is_null()) return outer_scope.CloseAndEscape(result); |
| 13266 return isolate->factory()->null_value(); |
| 13267 } |
| 13268 |
| 13269 Handle<Object> JSSTGetTypeName(Handle<StackTraceFrame> frame) { |
| 13270 // TODO(jgruber): Check for strict/constructor here as in |
| 13271 // CallSitePrototypeGetThis. |
| 13272 |
| 13273 DCHECK(frame->IsJavaScriptFrame()); |
| 13274 Isolate* isolate = frame->GetIsolate(); |
| 13275 Handle<Object> recv = handle(frame->receiver(), isolate); |
| 13276 |
| 13277 if (recv->IsNull(isolate) || recv->IsUndefined(isolate)) |
| 13278 return isolate->factory()->null_value(); |
| 13279 |
| 13280 if (recv->IsJSProxy()) return isolate->factory()->Proxy_string(); |
| 13281 |
| 13282 Handle<JSReceiver> receiver_object = |
| 13283 Object::ToObject(isolate, recv).ToHandleChecked(); |
| 13284 return JSReceiver::GetConstructorName(receiver_object); |
| 13285 } |
| 13286 |
| 13287 Object* EvalFromFunctionName(Isolate* isolate, Handle<Script> script) { |
| 13288 if (script->eval_from_shared()->IsUndefined(isolate)) |
| 13289 return *isolate->factory()->undefined_value(); |
| 13290 |
| 13291 Handle<SharedFunctionInfo> shared( |
| 13292 SharedFunctionInfo::cast(script->eval_from_shared())); |
| 13293 // Find the name of the function calling eval. |
| 13294 if (shared->name()->BooleanValue()) { |
| 13295 return shared->name(); |
| 13296 } |
| 13297 |
| 13298 return shared->inferred_name(); |
| 13299 } |
| 13300 |
| 13301 Object* EvalFromScript(Isolate* isolate, Handle<Script> script) { |
| 13302 if (script->eval_from_shared()->IsUndefined(isolate)) |
| 13303 return *isolate->factory()->undefined_value(); |
| 13304 |
| 13305 Handle<SharedFunctionInfo> eval_from_shared( |
| 13306 SharedFunctionInfo::cast(script->eval_from_shared())); |
| 13307 return eval_from_shared->script()->IsScript() |
| 13308 ? eval_from_shared->script() |
| 13309 : *isolate->factory()->undefined_value(); |
| 13310 } |
| 13311 |
| 13312 MaybeHandle<String> FormatEvalOrigin(Isolate* isolate, Handle<Script> script) { |
| 13313 Handle<Object> sourceURL = Script::GetNameOrSourceURL(script); |
| 13314 if (!sourceURL->IsUndefined(isolate)) { |
| 13315 DCHECK(sourceURL->IsString()); |
| 13316 return Handle<String>::cast(sourceURL); |
| 13317 } |
| 13318 |
| 13319 IncrementalStringBuilder builder(isolate); |
| 13320 builder.AppendCString("eval at "); |
| 13321 |
| 13322 Handle<Object> eval_from_function_name = |
| 13323 handle(EvalFromFunctionName(isolate, script), isolate); |
| 13324 if (eval_from_function_name->BooleanValue()) { |
| 13325 Handle<String> str; |
| 13326 ASSIGN_RETURN_ON_EXCEPTION( |
| 13327 isolate, str, Object::ToString(isolate, eval_from_function_name), |
| 13328 String); |
| 13329 builder.AppendString(str); |
| 13330 } else { |
| 13331 builder.AppendCString("<anonymous>"); |
| 13332 } |
| 13333 |
| 13334 Handle<Object> eval_from_script_obj = |
| 13335 handle(EvalFromScript(isolate, script), isolate); |
| 13336 if (eval_from_script_obj->IsScript()) { |
| 13337 Handle<Script> eval_from_script = |
| 13338 Handle<Script>::cast(eval_from_script_obj); |
| 13339 builder.AppendCString(" ("); |
| 13340 if (eval_from_script->compilation_type() == Script::COMPILATION_TYPE_EVAL) { |
| 13341 // Eval script originated from another eval. |
| 13342 Handle<String> str; |
| 13343 ASSIGN_RETURN_ON_EXCEPTION( |
| 13344 isolate, str, FormatEvalOrigin(isolate, eval_from_script), String); |
| 13345 builder.AppendString(str); |
| 13346 } else { |
| 13347 DCHECK(eval_from_script->compilation_type() != |
| 13348 Script::COMPILATION_TYPE_EVAL); |
| 13349 // eval script originated from "real" source. |
| 13350 Handle<Object> name_obj = handle(eval_from_script->name(), isolate); |
| 13351 if (eval_from_script->name()->IsString()) { |
| 13352 builder.AppendString(Handle<String>::cast(name_obj)); |
| 13353 |
| 13354 Script::PositionInfo info; |
| 13355 if (eval_from_script->GetPositionInfo(script->GetEvalPosition(), &info, |
| 13356 Script::NO_OFFSET)) { |
| 13357 builder.AppendCString(":"); |
| 13358 |
| 13359 Handle<String> str = isolate->factory()->NumberToString( |
| 13360 handle(Smi::FromInt(info.line + 1), isolate)); |
| 13361 builder.AppendString(str); |
| 13362 |
| 13363 builder.AppendCString(":"); |
| 13364 |
| 13365 str = isolate->factory()->NumberToString( |
| 13366 handle(Smi::FromInt(info.column + 1), isolate)); |
| 13367 builder.AppendString(str); |
| 13368 } |
| 13369 } else { |
| 13370 DCHECK(!eval_from_script->name()->IsString()); |
| 13371 builder.AppendCString("unknown source"); |
| 13372 } |
| 13373 } |
| 13374 builder.AppendCString(")"); |
| 13375 } |
| 13376 |
| 13377 Handle<String> result; |
| 13378 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, builder.Finish(), String); |
| 13379 return result; |
| 13380 } |
| 13381 |
| 13382 Handle<Object> JSSTGetEvalOrigin(Handle<StackTraceFrame> frame) { |
| 13383 DCHECK(frame->IsJavaScriptFrame()); |
| 13384 Isolate* isolate = frame->GetIsolate(); |
| 13385 |
| 13386 Handle<Object> script = |
| 13387 handle(frame->function()->shared()->script(), isolate); |
| 13388 if (!script->IsScript()) return isolate->factory()->undefined_value(); |
| 13389 |
| 13390 return FormatEvalOrigin(isolate, Handle<Script>::cast(script)) |
| 13391 .ToHandleChecked(); |
| 13392 } |
| 13393 |
| 13394 // Return 1-based line number, including line offset. |
| 13395 int JSSTGetLineNumber(Handle<StackTraceFrame> frame) { |
| 13396 DCHECK(frame->IsJavaScriptFrame()); |
| 13397 Isolate* isolate = frame->GetIsolate(); |
| 13398 const int pos = frame->GetPosition(); |
| 13399 if (pos >= 0) { |
| 13400 Handle<Object> script_obj(frame->function()->shared()->script(), isolate); |
| 13401 if (script_obj->IsScript()) { |
| 13402 Handle<Script> script = Handle<Script>::cast(script_obj); |
| 13403 return Script::GetLineNumber(script, pos) + 1; |
| 13404 } |
| 13405 } |
| 13406 return -1; |
| 13407 } |
| 13408 |
| 13409 // Return 1-based column number, including column offset if first line. |
| 13410 int JSSTGetColumnNumber(Handle<StackTraceFrame> frame) { |
| 13411 DCHECK(frame->IsJavaScriptFrame()); |
| 13412 Isolate* isolate = frame->GetIsolate(); |
| 13413 const int pos = frame->GetPosition(); |
| 13414 if (pos >= 0) { |
| 13415 Handle<Object> script_obj(frame->function()->shared()->script(), isolate); |
| 13416 if (script_obj->IsScript()) { |
| 13417 Handle<Script> script = Handle<Script>::cast(script_obj); |
| 13418 return Script::GetColumnNumber(script, pos) + 1; |
| 13419 } |
| 13420 } |
| 13421 return -1; |
| 13422 } |
| 13423 |
| 13424 bool JSSTIsNative(Handle<StackTraceFrame> frame) { |
| 13425 DCHECK(frame->IsJavaScriptFrame()); |
| 13426 Isolate* isolate = frame->GetIsolate(); |
| 13427 Handle<Object> script(frame->function()->shared()->script(), isolate); |
| 13428 return script->IsScript() && |
| 13429 Handle<Script>::cast(script)->type() == Script::TYPE_NATIVE; |
| 13430 } |
| 13431 |
| 13432 bool JSSTIsToplevel(Handle<StackTraceFrame> frame) { |
| 13433 DCHECK(frame->IsJavaScriptFrame()); |
| 13434 Isolate* isolate = frame->GetIsolate(); |
| 13435 Object* recv = frame->receiver(); |
| 13436 return recv->IsJSGlobalProxy() || recv->IsNull(isolate) || |
| 13437 recv->IsUndefined(isolate); |
| 13438 } |
| 13439 |
| 13440 bool JSSTIsEval(Handle<StackTraceFrame> frame) { |
| 13441 DCHECK(frame->IsJavaScriptFrame()); |
| 13442 Isolate* isolate = frame->GetIsolate(); |
| 13443 Handle<Object> script(frame->function()->shared()->script(), isolate); |
| 13444 return script->IsScript() && |
| 13445 Handle<Script>::cast(script)->compilation_type() == |
| 13446 Script::COMPILATION_TYPE_EVAL; |
| 13447 } |
| 13448 |
| 13449 bool JSSTIsConstructor(Handle<StackTraceFrame> frame) { |
| 13450 DCHECK(frame->IsJavaScriptFrame()); |
| 13451 Isolate* isolate = frame->GetIsolate(); |
| 13452 Object* recv = frame->receiver(); |
| 13453 |
| 13454 if (frame->ForceConstructor()) return true; |
| 13455 if (!recv->IsJSObject()) return false; |
| 13456 Handle<Object> constructor = |
| 13457 JSReceiver::GetDataProperty(Handle<JSObject>::cast(handle(recv, isolate)), |
| 13458 isolate->factory()->constructor_string()); |
| 13459 return constructor.is_identical_to(handle(frame->function())); |
| 13460 } |
| 13461 |
| 13462 bool IsNonEmptyString(Handle<Object> object) { |
| 13463 return (object->IsString() && String::cast(*object)->length() > 0); |
| 13464 } |
| 13465 |
| 13466 int StringIndexOf(Isolate* isolate, Handle<String> subject, |
| 13467 Handle<String> pattern) { |
| 13468 if (pattern->length() > subject->length()) return -1; |
| 13469 return String::IndexOf(isolate, subject, pattern, 0); |
| 13470 } |
| 13471 |
| 13472 // Returns true iff |
| 13473 // 1. the subject ends with '.' + pattern, or |
| 13474 // 2. subject == pattern. |
| 13475 bool StringEndsWithMethodName(Isolate* isolate, Handle<String> subject, |
| 13476 Handle<String> pattern) { |
| 13477 if (String::Equals(subject, pattern)) return true; |
| 13478 |
| 13479 FlatStringReader subject_reader(isolate, String::Flatten(subject)); |
| 13480 FlatStringReader pattern_reader(isolate, String::Flatten(pattern)); |
| 13481 |
| 13482 int pattern_index = pattern_reader.length() - 1; |
| 13483 int subject_index = subject_reader.length() - 1; |
| 13484 for (int i = 0; i <= pattern_reader.length(); i++) { // Iterate over len + 1. |
| 13485 if (subject_index < 0) { |
| 13486 return false; |
| 13487 } |
| 13488 |
| 13489 const uc32 subject_char = subject_reader.Get(subject_index); |
| 13490 if (i == pattern_reader.length()) { |
| 13491 if (subject_char != '.') return false; |
| 13492 } else if (subject_char != pattern_reader.Get(pattern_index)) { |
| 13493 return false; |
| 13494 } |
| 13495 |
| 13496 pattern_index--; |
| 13497 subject_index--; |
| 13498 } |
| 13499 |
| 13500 return true; |
| 13501 } |
| 13502 |
| 13503 void AppendMethodCall(Isolate* isolate, Handle<StackTraceFrame> frame, |
| 13504 IncrementalStringBuilder* builder) { |
| 13505 Handle<Object> type_name = frame->GetTypeName(); |
| 13506 Handle<Object> method_name = frame->GetMethodName(); |
| 13507 Handle<Object> function_name = frame->GetFunctionName(); |
| 13508 |
| 13509 if (IsNonEmptyString(function_name)) { |
| 13510 Handle<String> function_string = Handle<String>::cast(function_name); |
| 13511 if (IsNonEmptyString(type_name)) { |
| 13512 Handle<String> type_string = Handle<String>::cast(type_name); |
| 13513 bool starts_with_type_name = |
| 13514 (StringIndexOf(isolate, function_string, type_string) == 0); |
| 13515 if (!starts_with_type_name) { |
| 13516 builder->AppendString(type_string); |
| 13517 builder->AppendCharacter('.'); |
| 13518 } |
| 13519 } |
| 13520 builder->AppendString(function_string); |
| 13521 |
| 13522 if (IsNonEmptyString(method_name)) { |
| 13523 Handle<String> method_string = Handle<String>::cast(method_name); |
| 13524 if (!StringEndsWithMethodName(isolate, function_string, method_string)) { |
| 13525 builder->AppendCString(" [as "); |
| 13526 builder->AppendString(method_string); |
| 13527 builder->AppendCharacter(']'); |
| 13528 } |
| 13529 } |
| 13530 } else { |
| 13531 builder->AppendString(Handle<String>::cast(type_name)); |
| 13532 builder->AppendCharacter('.'); |
| 13533 if (IsNonEmptyString(method_name)) { |
| 13534 builder->AppendString(Handle<String>::cast(method_name)); |
| 13535 } else { |
| 13536 builder->AppendCString("<anonymous>"); |
| 13537 } |
| 13538 } |
| 13539 } |
| 13540 |
| 13541 void AppendFileLocation(Isolate* isolate, Handle<StackTraceFrame> frame, |
| 13542 IncrementalStringBuilder* builder) { |
| 13543 if (frame->IsNative()) { |
| 13544 builder->AppendCString("native"); |
| 13545 return; |
| 13546 } |
| 13547 |
| 13548 Handle<Object> file_name = frame->GetScriptNameOrSourceUrl(); |
| 13549 if (!file_name->IsString() && frame->IsEval()) { |
| 13550 Handle<Object> eval_origin = frame->GetEvalOrigin(); |
| 13551 DCHECK(eval_origin->IsString()); |
| 13552 builder->AppendString(Handle<String>::cast(eval_origin)); |
| 13553 builder->AppendCString(", "); // Expecting source position to follow. |
| 13554 } |
| 13555 |
| 13556 if (IsNonEmptyString(file_name)) { |
| 13557 builder->AppendString(Handle<String>::cast(file_name)); |
| 13558 } else { |
| 13559 // Source code does not originate from a file and is not native, but we |
| 13560 // can still get the source position inside the source string, e.g. in |
| 13561 // an eval string. |
| 13562 builder->AppendCString("<anonymous>"); |
| 13563 } |
| 13564 |
| 13565 int line_number = frame->GetLineNumber(); |
| 13566 if (line_number != -1) { |
| 13567 builder->AppendCharacter(':'); |
| 13568 Handle<String> line_string = isolate->factory()->NumberToString( |
| 13569 handle(Smi::FromInt(line_number), isolate), isolate); |
| 13570 builder->AppendString(line_string); |
| 13571 |
| 13572 int column_number = frame->GetColumnNumber(); |
| 13573 if (column_number != -1) { |
| 13574 builder->AppendCharacter(':'); |
| 13575 Handle<String> column_string = isolate->factory()->NumberToString( |
| 13576 handle(Smi::FromInt(column_number), isolate), isolate); |
| 13577 builder->AppendString(column_string); |
| 13578 } |
| 13579 } |
| 13580 } |
| 13581 |
| 13582 Handle<String> JSSTToString(Handle<StackTraceFrame> frame) { |
| 13583 DCHECK(frame->IsJavaScriptFrame()); |
| 13584 Isolate* isolate = frame->GetIsolate(); |
| 13585 IncrementalStringBuilder builder(isolate); |
| 13586 |
| 13587 Handle<Object> function_name = frame->GetFunctionName(); |
| 13588 |
| 13589 const bool is_toplevel = frame->IsToplevel(); |
| 13590 const bool is_constructor = frame->IsConstructor(); |
| 13591 const bool is_method_call = !(is_toplevel || is_constructor); |
| 13592 |
| 13593 if (is_method_call) { |
| 13594 AppendMethodCall(isolate, frame, &builder); |
| 13595 } else if (is_constructor) { |
| 13596 builder.AppendCString("new "); |
| 13597 if (IsNonEmptyString(function_name)) { |
| 13598 builder.AppendString(Handle<String>::cast(function_name)); |
| 13599 } else { |
| 13600 builder.AppendCString("<anonymous>"); |
| 13601 } |
| 13602 } else if (IsNonEmptyString(function_name)) { |
| 13603 builder.AppendString(Handle<String>::cast(function_name)); |
| 13604 } else { |
| 13605 AppendFileLocation(isolate, frame, &builder); |
| 13606 return builder.Finish().ToHandleChecked(); |
| 13607 } |
| 13608 |
| 13609 builder.AppendCString(" ("); |
| 13610 AppendFileLocation(isolate, frame, &builder); |
| 13611 builder.AppendCString(")"); |
| 13612 |
| 13613 return builder.Finish().ToHandleChecked(); |
| 13614 } |
| 13615 |
| 13616 int WasmSTGetPosition(Handle<StackTraceFrame> frame) { |
| 13617 DCHECK(frame->IsWasmFrame()); |
| 13618 const int off = frame->offset(); |
| 13619 return (off < 0) ? -1 - off : frame->abstract_code()->SourcePosition(off); |
| 13620 } |
| 13621 |
| 13622 Handle<Object> WasmSTGetFileName(Handle<StackTraceFrame> frame) { |
| 13623 DCHECK(frame->IsWasmFrame()); |
| 13624 Isolate* isolate = frame->GetIsolate(); |
| 13625 return isolate->factory()->null_value(); |
| 13626 } |
| 13627 |
| 13628 Handle<Object> WasmSTGetFunctionName(Handle<StackTraceFrame> frame) { |
| 13629 DCHECK(frame->IsWasmFrame()); |
| 13630 |
| 13631 Isolate* isolate = frame->GetIsolate(); |
| 13632 |
| 13633 return wasm::GetWasmFunctionNameOrNull(isolate, |
| 13634 handle(frame->wasm_object(), isolate), |
| 13635 frame->wasm_function_index()); |
| 13636 } |
| 13637 |
| 13638 Handle<Object> WasmSTGetScriptNameOrSourceUrl(Handle<StackTraceFrame> frame) { |
| 13639 DCHECK(frame->IsWasmFrame()); |
| 13640 Isolate* isolate = frame->GetIsolate(); |
| 13641 return isolate->factory()->null_value(); |
| 13642 } |
| 13643 |
| 13644 Handle<Object> WasmSTGetMethodName(Handle<StackTraceFrame> frame) { |
| 13645 DCHECK(frame->IsWasmFrame()); |
| 13646 Isolate* isolate = frame->GetIsolate(); |
| 13647 return isolate->factory()->null_value(); |
| 13648 } |
| 13649 |
| 13650 Handle<Object> WasmSTGetTypeName(Handle<StackTraceFrame> frame) { |
| 13651 DCHECK(frame->IsWasmFrame()); |
| 13652 |
| 13653 Isolate* isolate = frame->GetIsolate(); |
| 13654 Handle<Object> recv = handle(frame->wasm_object(), isolate); |
| 13655 |
| 13656 if (recv->IsUndefined(isolate)) return isolate->factory()->null_value(); |
| 13657 |
| 13658 DCHECK(wasm::IsWasmObject(*recv)); |
| 13659 Handle<JSReceiver> receiver_object = |
| 13660 Object::ToObject(isolate, recv).ToHandleChecked(); |
| 13661 return JSReceiver::GetConstructorName(receiver_object); |
| 13662 } |
| 13663 |
| 13664 Handle<Object> WasmSTGetEvalOrigin(Handle<StackTraceFrame> frame) { |
| 13665 DCHECK(frame->IsWasmFrame()); |
| 13666 Isolate* isolate = frame->GetIsolate(); |
| 13667 return isolate->factory()->null_value(); |
| 13668 } |
| 13669 |
| 13670 int WasmSTGetLineNumber(Handle<StackTraceFrame> frame) { |
| 13671 DCHECK(frame->IsWasmFrame()); |
| 13672 return frame->wasm_function_index(); |
| 13673 } |
| 13674 |
| 13675 int WasmSTGetColumnNumber(Handle<StackTraceFrame> frame) { |
| 13676 DCHECK(frame->IsWasmFrame()); |
| 13677 return -1; |
| 13678 } |
| 13679 |
| 13680 bool WasmSTIsNative(Handle<StackTraceFrame> frame) { |
| 13681 DCHECK(frame->IsWasmFrame()); |
| 13682 return false; |
| 13683 } |
| 13684 |
| 13685 bool WasmSTIsToplevel(Handle<StackTraceFrame> frame) { |
| 13686 DCHECK(frame->IsWasmFrame()); |
| 13687 return false; |
| 13688 } |
| 13689 |
| 13690 bool WasmSTIsEval(Handle<StackTraceFrame> frame) { |
| 13691 DCHECK(frame->IsWasmFrame()); |
| 13692 return false; |
| 13693 } |
| 13694 |
| 13695 bool WasmSTIsConstructor(Handle<StackTraceFrame> frame) { |
| 13696 DCHECK(frame->IsWasmFrame()); |
| 13697 return false; |
| 13698 } |
| 13699 |
| 13700 Handle<String> WasmSTToString(Handle<StackTraceFrame> frame) { |
| 13701 DCHECK(frame->IsWasmFrame()); |
| 13702 Isolate* isolate = frame->GetIsolate(); |
| 13703 IncrementalStringBuilder builder(isolate); |
| 13704 |
| 13705 Handle<Object> name = frame->GetFunctionName(); |
| 13706 if (name->IsNull(isolate)) { |
| 13707 builder.AppendCString("<WASM UNNAMED>"); |
| 13708 } else { |
| 13709 DCHECK(name->IsString()); |
| 13710 builder.AppendString(Handle<String>::cast(name)); |
| 13711 } |
| 13712 |
| 13713 builder.AppendCString(" (<WASM>["); |
| 13714 |
| 13715 Handle<String> ix = isolate->factory()->NumberToString( |
| 13716 handle(Smi::FromInt(frame->wasm_function_index()), isolate)); |
| 13717 builder.AppendString(ix); |
| 13718 |
| 13719 builder.AppendCString("]+"); |
| 13720 |
| 13721 Handle<Object> pos = handle(Smi::FromInt(frame->GetPosition()), isolate); |
| 13722 builder.AppendString(isolate->factory()->NumberToString(pos)); |
| 13723 builder.AppendCString(")"); |
| 13724 |
| 13725 return builder.Finish().ToHandleChecked(); |
| 13726 } |
| 13727 |
| 13728 } // namespace |
| 13729 |
| 13730 #define STACK_TRACE_FRAME_DISPATCH(return_type, name) \ |
| 13731 return_type StackTraceFrame::name() { \ |
| 13732 if (IsJavaScriptFrame()) { \ |
| 13733 return JSST##name(handle(this)); \ |
| 13734 } else { \ |
| 13735 DCHECK(IsWasmFrame()); \ |
| 13736 return WasmST##name(handle(this)); \ |
| 13737 } \ |
| 13738 } |
| 13739 |
| 13740 STACK_TRACE_FRAME_DISPATCH(int, GetPosition) |
| 13741 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetFileName) |
| 13742 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetFunctionName) |
| 13743 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetScriptNameOrSourceUrl) |
| 13744 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetMethodName) |
| 13745 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetTypeName) |
| 13746 STACK_TRACE_FRAME_DISPATCH(Handle<Object>, GetEvalOrigin) |
| 13747 STACK_TRACE_FRAME_DISPATCH(int, GetLineNumber) |
| 13748 STACK_TRACE_FRAME_DISPATCH(int, GetColumnNumber) |
| 13749 STACK_TRACE_FRAME_DISPATCH(bool, IsNative) |
| 13750 STACK_TRACE_FRAME_DISPATCH(bool, IsToplevel) |
| 13751 STACK_TRACE_FRAME_DISPATCH(bool, IsEval) |
| 13752 STACK_TRACE_FRAME_DISPATCH(bool, IsConstructor) |
| 13753 STACK_TRACE_FRAME_DISPATCH(Handle<String>, ToString) |
| 13754 #undef STACK_TRACE_FRAME_DISPATCH |
13145 | 13755 |
13146 SharedFunctionInfo::Iterator::Iterator(Isolate* isolate) | 13756 SharedFunctionInfo::Iterator::Iterator(Isolate* isolate) |
13147 : script_iterator_(isolate), | 13757 : script_iterator_(isolate), |
13148 sfi_iterator_(isolate->heap()->noscript_shared_function_infos()) {} | 13758 sfi_iterator_(isolate->heap()->noscript_shared_function_infos()) {} |
13149 | 13759 |
13150 | 13760 |
13151 bool SharedFunctionInfo::Iterator::NextScript() { | 13761 bool SharedFunctionInfo::Iterator::NextScript() { |
13152 Script* script = script_iterator_.Next(); | 13762 Script* script = script_iterator_.Next(); |
13153 if (script == NULL) return false; | 13763 if (script == NULL) return false; |
13154 sfi_iterator_.Reset(script->shared_function_infos()); | 13764 sfi_iterator_.Reset(script->shared_function_infos()); |
(...skipping 6121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19276 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, | 19886 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, |
19277 PrototypeIterator::END_AT_NULL); | 19887 PrototypeIterator::END_AT_NULL); |
19278 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { | 19888 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { |
19279 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; | 19889 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; |
19280 } | 19890 } |
19281 return false; | 19891 return false; |
19282 } | 19892 } |
19283 | 19893 |
19284 } // namespace internal | 19894 } // namespace internal |
19285 } // namespace v8 | 19895 } // namespace v8 |
OLD | NEW |