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