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