• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ArgumentString(Isolate * isolate) const17 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 
GetLocation(Handle<Script> script) const28 MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
29     Handle<Script> script) const {
30   return MessageLocation(script, start_position_, end_position_);
31 }
32 
ReportMessageAt(int start_position,int end_position,MessageTemplate::Template message,const char * arg,ParseErrorType error_type)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 
ReportMessageAt(int start_position,int end_position,MessageTemplate::Template message,const AstRawString * arg,ParseErrorType error_type)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 
ReportWarningAt(int start_position,int end_position,MessageTemplate::Template message,const char * arg)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 
ReportWarnings(Isolate * isolate,Handle<Script> script)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 
ReportErrors(Isolate * isolate,Handle<Script> script,AstValueFactory * ast_value_factory)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 
ThrowPendingError(Isolate * isolate,Handle<Script> script)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 
FormatErrorMessageForTest(Isolate * isolate) const139 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