Home | History | Annotate | Download | only in src
      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
      3 // found in the LICENSE file.
      4 
      5 #include "src/pending-compilation-error-handler.h"
      6 
      7 #include "src/ast/ast-value-factory.h"
      8 #include "src/debug/debug.h"
      9 #include "src/handles.h"
     10 #include "src/isolate.h"
     11 #include "src/messages.h"
     12 #include "src/objects-inl.h"
     13 
     14 namespace v8 {
     15 namespace internal {
     16 
     17 Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString(
     18     Isolate* isolate) const {
     19   if (arg_ != nullptr) return arg_->string();
     20   if (char_arg_ != nullptr) {
     21     return isolate->factory()
     22         ->NewStringFromUtf8(CStrVector(char_arg_))
     23         .ToHandleChecked();
     24   }
     25   return isolate->factory()->undefined_string();
     26 }
     27 
     28 MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
     29     Handle<Script> script) const {
     30   return MessageLocation(script, start_position_, end_position_);
     31 }
     32 
     33 void PendingCompilationErrorHandler::ReportMessageAt(
     34     int start_position, int end_position, MessageTemplate::Template message,
     35     const char* arg, ParseErrorType error_type) {
     36   if (has_pending_error_) return;
     37   has_pending_error_ = true;
     38 
     39   error_details_ =
     40       MessageDetails(start_position, end_position, message, nullptr, arg);
     41   error_type_ = error_type;
     42 }
     43 
     44 void PendingCompilationErrorHandler::ReportMessageAt(
     45     int start_position, int end_position, MessageTemplate::Template message,
     46     const AstRawString* arg, ParseErrorType error_type) {
     47   if (has_pending_error_) return;
     48   has_pending_error_ = true;
     49 
     50   error_details_ =
     51       MessageDetails(start_position, end_position, message, arg, nullptr);
     52   error_type_ = error_type;
     53 }
     54 
     55 void PendingCompilationErrorHandler::ReportWarningAt(
     56     int start_position, int end_position, MessageTemplate::Template message,
     57     const char* arg) {
     58   warning_messages_.emplace_front(
     59       MessageDetails(start_position, end_position, message, nullptr, arg));
     60 }
     61 
     62 void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
     63                                                     Handle<Script> script) {
     64   DCHECK(!has_pending_error());
     65 
     66   for (const MessageDetails& warning : warning_messages_) {
     67     MessageLocation location = warning.GetLocation(script);
     68     Handle<String> argument = warning.ArgumentString(isolate);
     69     Handle<JSMessageObject> message =
     70         MessageHandler::MakeMessageObject(isolate, warning.message(), &location,
     71                                           argument, Handle<FixedArray>::null());
     72     message->set_error_level(v8::Isolate::kMessageWarning);
     73     MessageHandler::ReportMessage(isolate, &location, message);
     74   }
     75 }
     76 
     77 void PendingCompilationErrorHandler::ReportErrors(
     78     Isolate* isolate, Handle<Script> script,
     79     AstValueFactory* ast_value_factory) {
     80   if (stack_overflow()) {
     81     isolate->StackOverflow();
     82   } else {
     83     DCHECK(has_pending_error());
     84     // Internalize ast values for throwing the pending error.
     85     ast_value_factory->Internalize(isolate);
     86     ThrowPendingError(isolate, script);
     87   }
     88 }
     89 
     90 void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
     91                                                        Handle<Script> script) {
     92   if (!has_pending_error_) return;
     93 
     94   MessageLocation location = error_details_.GetLocation(script);
     95   Handle<String> argument = error_details_.ArgumentString(isolate);
     96   isolate->debug()->OnCompileError(script);
     97 
     98   Factory* factory = isolate->factory();
     99   Handle<Object> error;
    100   switch (error_type_) {
    101     case kReferenceError:
    102       error = factory->NewReferenceError(error_details_.message(), argument);
    103       break;
    104     case kSyntaxError:
    105       error = factory->NewSyntaxError(error_details_.message(), argument);
    106       break;
    107     default:
    108       UNREACHABLE();
    109       break;
    110   }
    111 
    112   if (!error->IsJSObject()) {
    113     isolate->Throw(*error, &location);
    114     return;
    115   }
    116 
    117   Handle<JSObject> jserror = Handle<JSObject>::cast(error);
    118 
    119   Handle<Name> key_start_pos = factory->error_start_pos_symbol();
    120   JSObject::SetProperty(isolate, jserror, key_start_pos,
    121                         handle(Smi::FromInt(location.start_pos()), isolate),
    122                         LanguageMode::kSloppy)
    123       .Check();
    124 
    125   Handle<Name> key_end_pos = factory->error_end_pos_symbol();
    126   JSObject::SetProperty(isolate, jserror, key_end_pos,
    127                         handle(Smi::FromInt(location.end_pos()), isolate),
    128                         LanguageMode::kSloppy)
    129       .Check();
    130 
    131   Handle<Name> key_script = factory->error_script_symbol();
    132   JSObject::SetProperty(isolate, jserror, key_script, script,
    133                         LanguageMode::kSloppy)
    134       .Check();
    135 
    136   isolate->Throw(*error, &location);
    137 }
    138 
    139 Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
    140     Isolate* isolate) const {
    141   return MessageTemplate::FormatMessage(isolate, error_details_.message(),
    142                                         error_details_.ArgumentString(isolate));
    143 }
    144 
    145 }  // namespace internal
    146 }  // namespace v8
    147