11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/parsing/pending-compilation-error-handler.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#include "src/ast/ast-value-factory.h" 81cb0ef41Sopenharmony_ci#include "src/base/export-template.h" 91cb0ef41Sopenharmony_ci#include "src/base/logging.h" 101cb0ef41Sopenharmony_ci#include "src/debug/debug.h" 111cb0ef41Sopenharmony_ci#include "src/execution/isolate.h" 121cb0ef41Sopenharmony_ci#include "src/execution/messages.h" 131cb0ef41Sopenharmony_ci#include "src/handles/handles.h" 141cb0ef41Sopenharmony_ci#include "src/heap/local-heap-inl.h" 151cb0ef41Sopenharmony_ci#include "src/objects/objects-inl.h" 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_cinamespace v8 { 181cb0ef41Sopenharmony_cinamespace internal { 191cb0ef41Sopenharmony_ci 201cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::MessageDetails::SetString( 211cb0ef41Sopenharmony_ci Handle<String> string, Isolate* isolate) { 221cb0ef41Sopenharmony_ci DCHECK_NE(args_[0].type, kMainThreadHandle); 231cb0ef41Sopenharmony_ci args_[0].type = kMainThreadHandle; 241cb0ef41Sopenharmony_ci args_[0].js_string = string; 251cb0ef41Sopenharmony_ci} 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::MessageDetails::SetString( 281cb0ef41Sopenharmony_ci Handle<String> string, LocalIsolate* isolate) { 291cb0ef41Sopenharmony_ci DCHECK_NE(args_[0].type, kMainThreadHandle); 301cb0ef41Sopenharmony_ci args_[0].type = kMainThreadHandle; 311cb0ef41Sopenharmony_ci args_[0].js_string = isolate->heap()->NewPersistentHandle(string); 321cb0ef41Sopenharmony_ci} 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_citemplate <typename IsolateT> 351cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::MessageDetails::Prepare( 361cb0ef41Sopenharmony_ci IsolateT* isolate) { 371cb0ef41Sopenharmony_ci for (int i = 0; i < kMaxArgumentCount; i++) { 381cb0ef41Sopenharmony_ci switch (args_[i].type) { 391cb0ef41Sopenharmony_ci case kAstRawString: 401cb0ef41Sopenharmony_ci return SetString(args_[i].ast_string->string(), isolate); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci case kNone: 431cb0ef41Sopenharmony_ci case kConstCharString: 441cb0ef41Sopenharmony_ci // We can delay allocation until ArgString(isolate). 451cb0ef41Sopenharmony_ci return; 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_ci case kMainThreadHandle: 481cb0ef41Sopenharmony_ci // The message details might already be prepared, so skip them if this 491cb0ef41Sopenharmony_ci // is the case. 501cb0ef41Sopenharmony_ci return; 511cb0ef41Sopenharmony_ci } 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci} 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ciHandle<String> PendingCompilationErrorHandler::MessageDetails::ArgString( 561cb0ef41Sopenharmony_ci Isolate* isolate, int index) const { 571cb0ef41Sopenharmony_ci // `index` may be >= argc; in that case we return a default value to pass on 581cb0ef41Sopenharmony_ci // elsewhere. 591cb0ef41Sopenharmony_ci DCHECK_LT(index, kMaxArgumentCount); 601cb0ef41Sopenharmony_ci switch (args_[index].type) { 611cb0ef41Sopenharmony_ci case kMainThreadHandle: 621cb0ef41Sopenharmony_ci return args_[index].js_string; 631cb0ef41Sopenharmony_ci case kNone: 641cb0ef41Sopenharmony_ci return Handle<String>::null(); 651cb0ef41Sopenharmony_ci case kConstCharString: 661cb0ef41Sopenharmony_ci return isolate->factory() 671cb0ef41Sopenharmony_ci ->NewStringFromUtf8(base::CStrVector(args_[index].c_string), 681cb0ef41Sopenharmony_ci AllocationType::kOld) 691cb0ef41Sopenharmony_ci .ToHandleChecked(); 701cb0ef41Sopenharmony_ci case kAstRawString: 711cb0ef41Sopenharmony_ci UNREACHABLE(); 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ciMessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation( 761cb0ef41Sopenharmony_ci Handle<Script> script) const { 771cb0ef41Sopenharmony_ci return MessageLocation(script, start_position_, end_position_); 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportMessageAt(int start_position, 811cb0ef41Sopenharmony_ci int end_position, 821cb0ef41Sopenharmony_ci MessageTemplate message, 831cb0ef41Sopenharmony_ci const char* arg) { 841cb0ef41Sopenharmony_ci if (has_pending_error_) return; 851cb0ef41Sopenharmony_ci has_pending_error_ = true; 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci error_details_ = MessageDetails(start_position, end_position, message, arg); 881cb0ef41Sopenharmony_ci} 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportMessageAt(int start_position, 911cb0ef41Sopenharmony_ci int end_position, 921cb0ef41Sopenharmony_ci MessageTemplate message, 931cb0ef41Sopenharmony_ci const AstRawString* arg) { 941cb0ef41Sopenharmony_ci if (has_pending_error_) return; 951cb0ef41Sopenharmony_ci has_pending_error_ = true; 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci error_details_ = MessageDetails(start_position, end_position, message, arg); 981cb0ef41Sopenharmony_ci} 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportMessageAt(int start_position, 1011cb0ef41Sopenharmony_ci int end_position, 1021cb0ef41Sopenharmony_ci MessageTemplate message, 1031cb0ef41Sopenharmony_ci const AstRawString* arg0, 1041cb0ef41Sopenharmony_ci const char* arg1) { 1051cb0ef41Sopenharmony_ci if (has_pending_error_) return; 1061cb0ef41Sopenharmony_ci has_pending_error_ = true; 1071cb0ef41Sopenharmony_ci error_details_ = 1081cb0ef41Sopenharmony_ci MessageDetails(start_position, end_position, message, arg0, arg1); 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportWarningAt(int start_position, 1121cb0ef41Sopenharmony_ci int end_position, 1131cb0ef41Sopenharmony_ci MessageTemplate message, 1141cb0ef41Sopenharmony_ci const char* arg) { 1151cb0ef41Sopenharmony_ci warning_messages_.emplace_front( 1161cb0ef41Sopenharmony_ci MessageDetails(start_position, end_position, message, arg)); 1171cb0ef41Sopenharmony_ci} 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_citemplate <typename IsolateT> 1201cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::PrepareWarnings(IsolateT* isolate) { 1211cb0ef41Sopenharmony_ci DCHECK(!has_pending_error()); 1221cb0ef41Sopenharmony_ci 1231cb0ef41Sopenharmony_ci for (MessageDetails& warning : warning_messages_) { 1241cb0ef41Sopenharmony_ci warning.Prepare(isolate); 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_citemplate void PendingCompilationErrorHandler::PrepareWarnings(Isolate* isolate); 1281cb0ef41Sopenharmony_citemplate void PendingCompilationErrorHandler::PrepareWarnings( 1291cb0ef41Sopenharmony_ci LocalIsolate* isolate); 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportWarnings( 1321cb0ef41Sopenharmony_ci Isolate* isolate, Handle<Script> script) const { 1331cb0ef41Sopenharmony_ci DCHECK(!has_pending_error()); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci for (const MessageDetails& warning : warning_messages_) { 1361cb0ef41Sopenharmony_ci MessageLocation location = warning.GetLocation(script); 1371cb0ef41Sopenharmony_ci Handle<String> argument = warning.ArgString(isolate, 0); 1381cb0ef41Sopenharmony_ci DCHECK_LT(warning.ArgCount(), 2); // Arg1 is only used for errors. 1391cb0ef41Sopenharmony_ci Handle<JSMessageObject> message = 1401cb0ef41Sopenharmony_ci MessageHandler::MakeMessageObject(isolate, warning.message(), &location, 1411cb0ef41Sopenharmony_ci argument, Handle<FixedArray>::null()); 1421cb0ef41Sopenharmony_ci message->set_error_level(v8::Isolate::kMessageWarning); 1431cb0ef41Sopenharmony_ci MessageHandler::ReportMessage(isolate, &location, message); 1441cb0ef41Sopenharmony_ci } 1451cb0ef41Sopenharmony_ci} 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_citemplate <typename IsolateT> 1481cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::PrepareErrors( 1491cb0ef41Sopenharmony_ci IsolateT* isolate, AstValueFactory* ast_value_factory) { 1501cb0ef41Sopenharmony_ci if (stack_overflow()) return; 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci DCHECK(has_pending_error()); 1531cb0ef41Sopenharmony_ci // Internalize ast values for throwing the pending error. 1541cb0ef41Sopenharmony_ci ast_value_factory->Internalize(isolate); 1551cb0ef41Sopenharmony_ci error_details_.Prepare(isolate); 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE( 1581cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE) void PendingCompilationErrorHandler:: 1591cb0ef41Sopenharmony_ci PrepareErrors(Isolate* isolate, AstValueFactory* ast_value_factory); 1601cb0ef41Sopenharmony_citemplate EXPORT_TEMPLATE_DEFINE( 1611cb0ef41Sopenharmony_ci V8_EXPORT_PRIVATE) void PendingCompilationErrorHandler:: 1621cb0ef41Sopenharmony_ci PrepareErrors(LocalIsolate* isolate, AstValueFactory* ast_value_factory); 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ReportErrors(Isolate* isolate, 1651cb0ef41Sopenharmony_ci Handle<Script> script) const { 1661cb0ef41Sopenharmony_ci if (stack_overflow()) { 1671cb0ef41Sopenharmony_ci isolate->StackOverflow(); 1681cb0ef41Sopenharmony_ci } else { 1691cb0ef41Sopenharmony_ci DCHECK(has_pending_error()); 1701cb0ef41Sopenharmony_ci ThrowPendingError(isolate, script); 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_civoid PendingCompilationErrorHandler::ThrowPendingError( 1751cb0ef41Sopenharmony_ci Isolate* isolate, Handle<Script> script) const { 1761cb0ef41Sopenharmony_ci if (!has_pending_error_) return; 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci MessageLocation location = error_details_.GetLocation(script); 1791cb0ef41Sopenharmony_ci Handle<String> arg0 = error_details_.ArgString(isolate, 0); 1801cb0ef41Sopenharmony_ci Handle<String> arg1 = error_details_.ArgString(isolate, 1); 1811cb0ef41Sopenharmony_ci isolate->debug()->OnCompileError(script); 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci Factory* factory = isolate->factory(); 1841cb0ef41Sopenharmony_ci Handle<JSObject> error = 1851cb0ef41Sopenharmony_ci factory->NewSyntaxError(error_details_.message(), arg0, arg1); 1861cb0ef41Sopenharmony_ci isolate->ThrowAt(error, &location); 1871cb0ef41Sopenharmony_ci} 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ciHandle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest( 1901cb0ef41Sopenharmony_ci Isolate* isolate) { 1911cb0ef41Sopenharmony_ci error_details_.Prepare(isolate); 1921cb0ef41Sopenharmony_ci return MessageFormatter::Format(isolate, error_details_.message(), 1931cb0ef41Sopenharmony_ci error_details_.ArgString(isolate, 0), 1941cb0ef41Sopenharmony_ci error_details_.ArgString(isolate, 1)); 1951cb0ef41Sopenharmony_ci} 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci} // namespace internal 1981cb0ef41Sopenharmony_ci} // namespace v8 199