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