Line data Source code
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 383733 : Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString(
18 : Isolate* isolate) const {
19 383733 : if (arg_ != nullptr) return arg_->string();
20 306765 : if (char_arg_ != nullptr) {
21 : return isolate->factory()
22 : ->NewStringFromUtf8(CStrVector(char_arg_))
23 209880 : .ToHandleChecked();
24 : }
25 : return isolate->factory()->undefined_string();
26 : }
27 :
28 0 : MessageLocation PendingCompilationErrorHandler::MessageDetails::GetLocation(
29 : Handle<Script> script) const {
30 381231 : return MessageLocation(script, start_position_, end_position_);
31 : }
32 :
33 2270098 : void PendingCompilationErrorHandler::ReportMessageAt(
34 : int start_position, int end_position, MessageTemplate message,
35 : const char* arg, ParseErrorType error_type) {
36 4540196 : if (has_pending_error_) return;
37 425082 : has_pending_error_ = true;
38 :
39 : error_details_ =
40 425082 : MessageDetails(start_position, end_position, message, nullptr, arg);
41 425082 : error_type_ = error_type;
42 : }
43 :
44 78575 : void PendingCompilationErrorHandler::ReportMessageAt(
45 : int start_position, int end_position, MessageTemplate message,
46 : const AstRawString* arg, ParseErrorType error_type) {
47 157150 : if (has_pending_error_) return;
48 77298 : has_pending_error_ = true;
49 :
50 : error_details_ =
51 77298 : MessageDetails(start_position, end_position, message, arg, nullptr);
52 77298 : error_type_ = error_type;
53 : }
54 :
55 1246 : void PendingCompilationErrorHandler::ReportWarningAt(int start_position,
56 : int end_position,
57 : MessageTemplate message,
58 : const char* arg) {
59 : warning_messages_.emplace_front(
60 1247 : MessageDetails(start_position, end_position, message, nullptr, arg));
61 1247 : }
62 :
63 445 : void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
64 : Handle<Script> script) {
65 : DCHECK(!has_pending_error());
66 :
67 1780 : for (const MessageDetails& warning : warning_messages_) {
68 : MessageLocation location = warning.GetLocation(script);
69 445 : Handle<String> argument = warning.ArgumentString(isolate);
70 : Handle<JSMessageObject> message =
71 : MessageHandler::MakeMessageObject(isolate, warning.message(), &location,
72 445 : argument, Handle<FixedArray>::null());
73 : message->set_error_level(v8::Isolate::kMessageWarning);
74 445 : MessageHandler::ReportMessage(isolate, &location, message);
75 : }
76 445 : }
77 :
78 387870 : void PendingCompilationErrorHandler::ReportErrors(
79 : Isolate* isolate, Handle<Script> script,
80 387870 : AstValueFactory* ast_value_factory) {
81 387870 : if (stack_overflow()) {
82 7084 : isolate->StackOverflow();
83 : } else {
84 : DCHECK(has_pending_error());
85 : // Internalize ast values for throwing the pending error.
86 380786 : ast_value_factory->Internalize(isolate);
87 380786 : ThrowPendingError(isolate, script);
88 : }
89 387870 : }
90 :
91 761572 : void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
92 : Handle<Script> script) {
93 380816 : if (!has_pending_error_) return;
94 :
95 380786 : MessageLocation location = error_details_.GetLocation(script);
96 380786 : Handle<String> argument = error_details_.ArgumentString(isolate);
97 380786 : isolate->debug()->OnCompileError(script);
98 :
99 : Factory* factory = isolate->factory();
100 : Handle<Object> error;
101 380786 : switch (error_type_) {
102 : case kReferenceError:
103 4964 : error = factory->NewReferenceError(error_details_.message(), argument);
104 4964 : break;
105 : case kSyntaxError:
106 375822 : error = factory->NewSyntaxError(error_details_.message(), argument);
107 375822 : break;
108 : default:
109 0 : UNREACHABLE();
110 : break;
111 : }
112 :
113 761572 : if (!error->IsJSObject()) {
114 30 : isolate->Throw(*error, &location);
115 30 : return;
116 : }
117 :
118 380756 : Handle<JSObject> jserror = Handle<JSObject>::cast(error);
119 :
120 : Handle<Name> key_start_pos = factory->error_start_pos_symbol();
121 : Object::SetProperty(isolate, jserror, key_start_pos,
122 : handle(Smi::FromInt(location.start_pos()), isolate),
123 : StoreOrigin::kMaybeKeyed,
124 761512 : Just(ShouldThrow::kThrowOnError))
125 761512 : .Check();
126 :
127 : Handle<Name> key_end_pos = factory->error_end_pos_symbol();
128 : Object::SetProperty(isolate, jserror, key_end_pos,
129 : handle(Smi::FromInt(location.end_pos()), isolate),
130 : StoreOrigin::kMaybeKeyed,
131 761512 : Just(ShouldThrow::kThrowOnError))
132 761512 : .Check();
133 :
134 : Handle<Name> key_script = factory->error_script_symbol();
135 : Object::SetProperty(isolate, jserror, key_script, script,
136 : StoreOrigin::kMaybeKeyed,
137 380756 : Just(ShouldThrow::kThrowOnError))
138 761512 : .Check();
139 :
140 380756 : isolate->Throw(*error, &location);
141 : }
142 :
143 2502 : Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
144 : Isolate* isolate) const {
145 : return MessageFormatter::FormatMessage(
146 : isolate, error_details_.message(),
147 5004 : error_details_.ArgumentString(isolate));
148 : }
149 :
150 : } // namespace internal
151 178779 : } // namespace v8
|