Version 1.0.0.6
svn merge -c 30233 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 30234 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 30250 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 30308 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
Cherry picked multivm blink revision 1608 to the blink stable branch in revision 1609 and updated dartium blink deps to point to that.
R=iposva@google.com
Review URL: https://codereview.chromium.org//75123002
git-svn-id: http://dart.googlecode.com/svn/trunk@30334 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 22b2d47..483f5c6 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -51,7 +51,7 @@
if (FLAG_use_mirrored_compilation_error && error.IsLanguageError()) {
// A compilation error that was delayed by lazy compilation.
const LanguageError& compilation_error = LanguageError::Cast(error);
- String& message = String::Handle(compilation_error.message());
+ String& message = String::Handle(compilation_error.FormatMessage());
ThrowMirroredCompilationError(message);
UNREACHABLE();
}
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 1113f5e..170f508 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -4,12 +4,12 @@
#include "vm/class_finalizer.h"
+#include "vm/code_generator.h"
#include "vm/flags.h"
#include "vm/heap.h"
#include "vm/isolate.h"
#include "vm/longjump.h"
#include "vm/object_store.h"
-#include "vm/parser.h"
#include "vm/symbols.h"
namespace dart {
@@ -2623,14 +2623,11 @@
const Type& type,
const char* format,
va_list args) {
- LanguageError& error = LanguageError::Handle();
- if (prev_error.IsNull()) {
- error ^= Parser::FormatError(
- script, type.token_pos(), "Error", format, args);
- } else {
- error ^= Parser::FormatErrorWithAppend(
- prev_error, script, type.token_pos(), "Error", format, args);
- }
+ LanguageError& error = LanguageError::Handle(
+ LanguageError::NewFormattedV(
+ prev_error, script, type.token_pos(),
+ LanguageError::kMalformedType, Heap::kOld,
+ format, args));
if (FLAG_error_on_bad_type) {
ReportError(error);
}
@@ -2693,13 +2690,11 @@
const char* format, ...) {
va_list args;
va_start(args, format);
- Error& error = Error::Handle();
- if (prev_error.IsNull()) {
- error ^= Parser::FormatError(script, token_pos, "Error", format, args);
- } else {
- error ^= Parser::FormatErrorWithAppend(
- prev_error, script, token_pos, "Error", format, args);
- }
+ Error& error = Error::Handle(
+ LanguageError::NewFormattedV(
+ prev_error, script, token_pos,
+ LanguageError::kError, Heap::kNew,
+ format, args));
va_end(args);
ReportError(error);
}
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index f22df2c..5e9a5f3 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2955,6 +2955,21 @@
}
const Class& cls = Class::Handle(isolate, type_obj.type_class());
+ // Mark all fields as nullable.
+ Class& iterate_cls = Class::Handle(isolate, cls.raw());
+ Field& field = Field::Handle(isolate);
+ Array& fields = Array::Handle(isolate);
+ while (!iterate_cls.IsNull()) {
+ fields = iterate_cls.fields();
+ iterate_cls = iterate_cls.SuperClass();
+ for (int field_num = 0; field_num < fields.Length(); field_num++) {
+ field ^= fields.At(field_num);
+ if (field.is_static()) {
+ continue;
+ }
+ field.UpdateGuardedCidAndLength(Object::null_object());
+ }
+ }
// Allocate an object for the given class.
return Api::NewHandle(isolate, Instance::New(cls));
}
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index d942747..ff6be53 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -1067,13 +1067,16 @@
void FlowGraph::Bailout(const char* reason) const {
- const char* kFormat = "FlowGraph Bailout: %s %s";
- const char* function_name = parsed_function_.function().ToCString();
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
- char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
- OS::SNPrint(chars, len, kFormat, function_name, reason);
+ const Function& function = parsed_function_.function();
const Error& error = Error::Handle(
- LanguageError::New(String::Handle(String::New(chars))));
+ LanguageError::NewFormatted(Error::Handle(), // No previous error.
+ Script::Handle(function.script()),
+ function.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "FlowGraph Bailout: %s %s",
+ String::Handle(function.name()).ToCString(),
+ reason));
Isolate::Current()->long_jump_base()->Jump(1, error);
}
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index b231788..d4469cd 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3853,13 +3853,16 @@
void FlowGraphBuilder::Bailout(const char* reason) {
- const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
- const char* function_name = parsed_function_->function().ToCString();
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
- char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
- OS::SNPrint(chars, len, kFormat, function_name, reason);
+ const Function& function = parsed_function_->function();
const Error& error = Error::Handle(
- LanguageError::New(String::Handle(String::New(chars))));
+ LanguageError::NewFormatted(Error::Handle(), // No previous error.
+ Script::Handle(function.script()),
+ function.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "FlowGraphBuilder Bailout: %s %s",
+ String::Handle(function.name()).ToCString(),
+ reason));
Isolate::Current()->long_jump_base()->Jump(1, error);
}
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index a7affc9..6eeba1a 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -285,13 +285,16 @@
void FlowGraphCompiler::Bailout(const char* reason) {
- const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
- const char* function_name = parsed_function().function().ToCString();
- intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
- char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
- OS::SNPrint(chars, len, kFormat, function_name, reason);
+ const Function& function = parsed_function_.function();
const Error& error = Error::Handle(
- LanguageError::New(String::Handle(String::New(chars))));
+ LanguageError::NewFormatted(Error::Handle(), // No previous error.
+ Script::Handle(function.script()),
+ function.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "FlowGraphCompiler Bailout: %s %s",
+ String::Handle(function.name()).ToCString(),
+ reason));
Isolate::Current()->long_jump_base()->Jump(1, error);
}
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index ea91a10..0ebdeab 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -4520,6 +4520,10 @@
virtual bool CanDeoptimize() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const {
+ return Isolate::kNoDeoptId;
+ }
+
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
return kUnboxedDouble;
@@ -4549,6 +4553,10 @@
virtual bool CanDeoptimize() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const {
+ return Isolate::kNoDeoptId;
+ }
+
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
return kUnboxedFloat32x4;
@@ -4581,6 +4589,10 @@
virtual bool CanDeoptimize() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const {
+ return Isolate::kNoDeoptId;
+ }
+
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
return kUnboxedInt32x4;
@@ -4613,6 +4625,10 @@
virtual bool CanDeoptimize() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const {
+ return Isolate::kNoDeoptId;
+ }
+
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
return kUnboxedMint;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 8ba182a..139e0ca 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1680,28 +1680,18 @@
}
-static RawError* FormatError(const Error& prev_error,
- const Script& script,
- intptr_t token_pos,
- const char* format, ...) {
- va_list args;
- va_start(args, format);
- if (prev_error.IsNull()) {
- return Parser::FormatError(script, token_pos, "Error", format, args);
- } else {
- return Parser::FormatErrorWithAppend(prev_error, script, token_pos,
- "Error", format, args);
- }
-}
-
static void ReportTooManyTypeArguments(const Class& cls) {
const Error& error = Error::Handle(
- FormatError(Error::Handle(), // No previous error.
- Script::Handle(cls.script()), cls.token_pos(),
- "too many type parameters declared in class '%s' or in its "
- "super classes",
- String::Handle(cls.Name()).ToCString()));
+ LanguageError::NewFormatted(
+ Error::Handle(), // No previous error.
+ Script::Handle(cls.script()),
+ cls.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "too many type parameters declared in class '%s' or in its "
+ "super classes",
+ String::Handle(cls.Name()).ToCString()));
Isolate::Current()->long_jump_base()->Jump(1, error);
UNREACHABLE();
}
@@ -2238,9 +2228,13 @@
orig_func.UserVisibleSignature()) {
// Compare user visible signatures to ignore different implicit parameters
// when patching a constructor with a factory.
- *error = FormatError(*error, // No previous error.
- Script::Handle(patch.script()), func.token_pos(),
- "signature mismatch: '%s'", member_name.ToCString());
+ *error = LanguageError::NewFormatted(
+ *error, // No previous error.
+ Script::Handle(patch.script()),
+ func.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "signature mismatch: '%s'", member_name.ToCString());
return false;
}
}
@@ -2279,9 +2273,13 @@
// Verify no duplicate additions.
orig_field ^= LookupField(member_name);
if (!orig_field.IsNull()) {
- *error = FormatError(*error, // No previous error.
- Script::Handle(patch.script()), field.token_pos(),
- "duplicate field: %s", member_name.ToCString());
+ *error = LanguageError::NewFormatted(
+ *error, // No previous error.
+ Script::Handle(patch.script()),
+ field.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
+ "duplicate field: %s", member_name.ToCString());
return false;
}
new_list.SetAt(i, field);
@@ -2843,9 +2841,11 @@
for (intptr_t i = 0; i < interfaces.Length(); i++) {
interface ^= interfaces.At(i);
if (!interface.IsFinalized()) {
- // We may be checking bounds at finalization time. Skipping this
- // unfinalized interface will postpone bound checking to run time.
- continue;
+ // We may be checking bounds at finalization time and can encounter
+ // a still unfinalized interface.
+ ClassFinalizer::FinalizeType(
+ thsi, interface, ClassFinalizer::kCanonicalize);
+ interfaces.SetAt(i, interface);
}
error = Error::null();
if (interface.IsMalboundedWithError(&error)) {
@@ -4846,10 +4846,12 @@
other, Object::null_abstract_type_arguments(), bound_error)) {
// For more informative error reporting, use the location of the other
// function here, since the caller will use the location of this function.
- *bound_error = FormatError(
+ *bound_error = LanguageError::NewFormatted(
*bound_error, // A bound error if non null.
Script::Handle(other.script()),
other.token_pos(),
+ LanguageError::kError,
+ Heap::kNew,
"signature type '%s' of function '%s' is not a subtype of signature "
"type '%s' of function '%s'",
String::Handle(UserVisibleSignature()).ToCString(),
@@ -10662,7 +10664,13 @@
}
-RawLanguageError* LanguageError::New(const String& message, Heap::Space space) {
+RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
+ const Script& script,
+ intptr_t token_pos,
+ Kind kind,
+ Heap::Space space,
+ const char* format,
+ va_list args) {
ASSERT(Object::language_error_class() != Class::null());
LanguageError& result = LanguageError::Handle();
{
@@ -10672,18 +10680,151 @@
NoGCScope no_gc;
result ^= raw;
}
- result.set_message(message);
+ result.set_previous_error(prev_error);
+ result.set_script(script);
+ result.set_token_pos(token_pos);
+ result.set_kind(kind);
+ result.set_message(String::Handle(String::NewFormattedV(format, args)));
return result.raw();
}
-void LanguageError::set_message(const String& message) const {
- StorePointer(&raw_ptr()->message_, message.raw());
+RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
+ const Script& script,
+ intptr_t token_pos,
+ Kind kind,
+ Heap::Space space,
+ const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ RawLanguageError* result = LanguageError::NewFormattedV(
+ prev_error, script, token_pos, kind, space, format, args);
+ NoGCScope no_gc;
+ va_end(args);
+ return result;
+}
+
+
+RawLanguageError* LanguageError::New(const String& formatted_message,
+ Heap::Space space) {
+ ASSERT(Object::language_error_class() != Class::null());
+ LanguageError& result = LanguageError::Handle();
+ {
+ RawObject* raw = Object::Allocate(LanguageError::kClassId,
+ LanguageError::InstanceSize(),
+ space);
+ NoGCScope no_gc;
+ result ^= raw;
+ }
+ result.set_formatted_message(formatted_message);
+ return result.raw();
+}
+
+
+void LanguageError::set_previous_error(const Error& value) const {
+ StorePointer(&raw_ptr()->previous_error_, value.raw());
+}
+
+
+void LanguageError::set_script(const Script& value) const {
+ StorePointer(&raw_ptr()->script_, value.raw());
+}
+
+
+void LanguageError::set_token_pos(intptr_t value) const {
+ ASSERT(value >= 0);
+ raw_ptr()->token_pos_ = value;
+}
+
+
+void LanguageError::set_kind(uint8_t value) const {
+ raw_ptr()->kind_ = value;
+}
+
+
+void LanguageError::set_message(const String& value) const {
+ StorePointer(&raw_ptr()->message_, value.raw());
+}
+
+
+void LanguageError::set_formatted_message(const String& value) const {
+ StorePointer(&raw_ptr()->formatted_message_, value.raw());
+}
+
+
+RawString* LanguageError::FormatMessage() const {
+ if (formatted_message() != String::null()) {
+ return formatted_message();
+ }
+ const char* message_header;
+ switch (kind()) {
+ case kWarning: message_header = "warning"; break;
+ case kError: message_header = "error"; break;
+ case kMalformedType: message_header = "malformed type"; break;
+ case kMalboundedType: message_header = "malbounded type"; break;
+ default: message_header = ""; UNREACHABLE();
+ }
+ String& result = String::Handle();
+ String& msg = String::Handle(message());
+ const Script& scr = Script::Handle(script());
+ if (!scr.IsNull()) {
+ const String& script_url = String::Handle(scr.url());
+ if (token_pos() >= 0) {
+ intptr_t line, column;
+ scr.GetTokenLocation(token_pos(), &line, &column);
+ // Only report the line position if we have the original source. We still
+ // need to get a valid column so that we can report the ^ mark below the
+ // snippet.
+ if (scr.HasSource()) {
+ result = String::NewFormatted("'%s': %s: line %" Pd " pos %" Pd ": ",
+ script_url.ToCString(),
+ message_header,
+ line,
+ column);
+ } else {
+ result = String::NewFormatted("'%s': %s: line %" Pd ": ",
+ script_url.ToCString(),
+ message_header,
+ line);
+ }
+ // Append the formatted error or warning message.
+ result = String::Concat(result, msg);
+ // Append the source line.
+ const String& script_line = String::Handle(scr.GetLine(line));
+ ASSERT(!script_line.IsNull());
+ result = String::Concat(result, Symbols::NewLine());
+ result = String::Concat(result, script_line);
+ result = String::Concat(result, Symbols::NewLine());
+ // Append the column marker.
+ const String& column_line = String::Handle(
+ String::NewFormatted("%*s\n", static_cast<int>(column), "^"));
+ result = String::Concat(result, column_line);
+ } else {
+ // Token position is unknown.
+ result = String::NewFormatted("'%s': %s: ",
+ script_url.ToCString(),
+ message_header);
+ result = String::Concat(result, msg);
+ }
+ } else {
+ // Script is unknown.
+ // Append the formatted error or warning message.
+ result = String::NewFormatted("%s: ", message_header);
+ result = String::Concat(result, msg);
+ }
+ // Prepend previous error message.
+ const Error& prev_error = Error::Handle(previous_error());
+ if (!prev_error.IsNull()) {
+ msg = String::New(prev_error.ToErrorCString());
+ result = String::Concat(msg, result);
+ }
+ set_formatted_message(result);
+ return result.raw();
}
const char* LanguageError::ToErrorCString() const {
- const String& msg_str = String::Handle(message());
+ const String& msg_str = String::Handle(FormatMessage());
return msg_str.ToCString();
}
@@ -12112,10 +12253,12 @@
const Script& script = Script::Handle(cls.script());
// Since the bound may have been canonicalized, its token index is
// meaningless, therefore use the token index of this type parameter.
- *bound_error = FormatError(
+ *bound_error = LanguageError::NewFormatted(
*bound_error,
script,
token_pos(),
+ LanguageError::kMalboundedType,
+ Heap::kNew,
"type parameter '%s' of class '%s' must extend bound '%s', "
"but type argument '%s' is not a subtype of '%s'\n",
type_param_name.ToCString(),
@@ -12370,19 +12513,28 @@
const char* BoundedType::ToCString() const {
- const char* format = "BoundedType: type %s; bound: %s; class: %s";
+ const char* format = "BoundedType: type %s; bound: %s; type param: %s%s%s";
const char* type_cstr = String::Handle(AbstractType::Handle(
type()).Name()).ToCString();
const char* bound_cstr = String::Handle(AbstractType::Handle(
bound()).Name()).ToCString();
- const Class& cls = Class::Handle(TypeParameter::Handle(
- type_parameter()).parameterized_class());
- const char* cls_cstr =
- cls.IsNull() ? " null" : String::Handle(cls.Name()).ToCString();
- intptr_t len = OS::SNPrint(
- NULL, 0, format, type_cstr, bound_cstr, cls_cstr) + 1;
+ const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
+ const char* type_param_cstr = "null";
+ const char* of_cstr = "";
+ const char* cls_cstr = "";
+ if (!type_param.IsNull()) {
+ type_param_cstr = String::Handle(type_param.name()).ToCString();
+ const Class& cls = Class::Handle(type_param.parameterized_class());
+ if (!cls.IsNull()) {
+ of_cstr = " of ";
+ cls_cstr = String::Handle(cls.Name()).ToCString();
+ }
+ }
+ intptr_t len = OS::SNPrint(NULL, 0, format, type_cstr, bound_cstr,
+ type_param_cstr, of_cstr, cls_cstr) + 1;
char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
- OS::SNPrint(chars, len, format, type_cstr, bound_cstr, cls_cstr);
+ OS::SNPrint(chars, len, format, type_cstr, bound_cstr, type_param_cstr,
+ of_cstr, cls_cstr);
return chars;
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2b48af2..d6ac20b 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3757,9 +3757,6 @@
class ApiError : public Error {
public:
RawString* message() const { return raw_ptr()->message_; }
- static intptr_t message_offset() {
- return OFFSET_OF(RawApiError, message_);
- }
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(RawApiError));
@@ -3782,22 +3779,61 @@
class LanguageError : public Error {
public:
- RawString* message() const { return raw_ptr()->message_; }
- static intptr_t message_offset() {
- return OFFSET_OF(RawLanguageError, message_);
- }
+ enum Kind {
+ kWarning,
+ kError,
+ kMalformedType,
+ kMalboundedType,
+ };
+
+ // Build, cache, and return formatted message.
+ RawString* FormatMessage() const;
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(RawLanguageError));
}
- static RawLanguageError* New(const String& message,
+ // A null script means no source and a negative token_pos means no position.
+ static RawLanguageError* NewFormatted(const Error& prev_error,
+ const Script& script,
+ intptr_t token_pos,
+ Kind kind,
+ Heap::Space space,
+ const char* format, ...)
+ PRINTF_ATTRIBUTE(6, 7);
+
+ static RawLanguageError* NewFormattedV(const Error& prev_error,
+ const Script& script,
+ intptr_t token_pos,
+ Kind kind,
+ Heap::Space space,
+ const char* format, va_list args);
+
+ static RawLanguageError* New(const String& formatted_message,
Heap::Space space = Heap::kNew);
virtual const char* ToErrorCString() const;
private:
- void set_message(const String& message) const;
+ RawError* previous_error() const {
+ return raw_ptr()->previous_error_;
+ }
+ void set_previous_error(const Error& value) const;
+
+ RawScript* script() const { return raw_ptr()->script_; }
+ void set_script(const Script& value) const;
+
+ intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+ void set_token_pos(intptr_t value) const;
+
+ Kind kind() const { return static_cast<Kind>(raw_ptr()->kind_); }
+ void set_kind(uint8_t value) const;
+
+ RawString* message() const { return raw_ptr()->message_; }
+ void set_message(const String& value) const;
+
+ RawString* formatted_message() const { return raw_ptr()->formatted_message_; }
+ void set_formatted_message(const String& value) const;
static RawLanguageError* New();
@@ -3840,9 +3876,6 @@
class UnwindError : public Error {
public:
RawString* message() const { return raw_ptr()->message_; }
- static intptr_t message_offset() {
- return OFFSET_OF(RawUnwindError, message_);
- }
static intptr_t InstanceSize() {
return RoundedAllocationSize(sizeof(RawUnwindError));
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 0fff78e..4fc43e0 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -5251,8 +5251,10 @@
if (!Utils::IsInt(16, params->num_fixed_parameters) ||
!Utils::IsInt(16, params->num_optional_parameters)) {
const Script& script = Script::Handle(Class::Handle(func.Owner()).script());
- const Error& error = Error::Handle(FormatErrorMsg(
- script, func.token_pos(), "Error", "too many formal parameters"));
+ const Error& error = Error::Handle(LanguageError::NewFormatted(
+ Error::Handle(), script, func.token_pos(),
+ LanguageError::kError, Heap::kNew,
+ "too many formal parameters"));
ErrorMsg(error);
}
func.set_num_fixed_parameters(params->num_fixed_parameters);
@@ -7226,116 +7228,12 @@
}
-RawError* Parser::FormatErrorWithAppend(const Error& prev_error,
- const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format,
- va_list args) {
- const String& msg1 = String::Handle(String::New(prev_error.ToErrorCString()));
- const String& msg2 = String::Handle(
- FormatMessage(script, token_pos, message_header, format, args));
- return LanguageError::New(String::Handle(String::Concat(msg1, msg2)));
-}
-
-
-RawError* Parser::FormatError(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format,
- va_list args) {
- const String& msg = String::Handle(
- FormatMessage(script, token_pos, message_header, format, args));
- return LanguageError::New(msg);
-}
-
-
-RawError* Parser::FormatErrorMsg(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format, ...) {
- va_list args;
- va_start(args, format);
- const Error& error = Error::Handle(
- FormatError(script, token_pos, message_header, format, args));
- va_end(args);
- return error.raw();
-}
-
-
-RawString* Parser::FormatMessage(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format, va_list args) {
- String& result = String::Handle();
- const String& msg = String::Handle(String::NewFormattedV(format, args));
- if (!script.IsNull()) {
- const String& script_url = String::Handle(script.url());
- if (token_pos >= 0) {
- intptr_t line, column;
- script.GetTokenLocation(token_pos, &line, &column);
- // Only report the line position if we have the original source. We still
- // need to get a valid column so that we can report the ^ mark below the
- // snippet.
- if (script.HasSource()) {
- result = String::NewFormatted("'%s': %s: line %" Pd " pos %" Pd ": ",
- script_url.ToCString(),
- message_header,
- line,
- column);
- } else {
- result = String::NewFormatted("'%s': %s: line %" Pd ": ",
- script_url.ToCString(),
- message_header,
- line);
- }
- // Append the formatted error or warning message.
- result = String::Concat(result, msg);
- const String& new_line = String::Handle(String::New("\n"));
- // Append the source line.
- const String& script_line = String::Handle(script.GetLine(line));
- ASSERT(!script_line.IsNull());
- result = String::Concat(result, new_line);
- result = String::Concat(result, script_line);
- result = String::Concat(result, new_line);
- // Append the column marker.
- const String& column_line = String::Handle(
- String::NewFormatted("%*s\n", static_cast<int>(column), "^"));
- result = String::Concat(result, column_line);
- } else {
- // Token position is unknown.
- result = String::NewFormatted("'%s': %s: ",
- script_url.ToCString(),
- message_header);
- result = String::Concat(result, msg);
- }
- } else {
- // Script is unknown.
- // Append the formatted error or warning message.
- result = msg.raw();
- }
- return result.raw();
-}
-
-
-void Parser::PrintMessage(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format, ...) {
- va_list args;
- va_start(args, format);
- const String& buf = String::Handle(
- FormatMessage(script, token_pos, message_header, format, args));
- va_end(args);
- OS::Print("%s", buf.ToCString());
-}
-
-
void Parser::ErrorMsg(intptr_t token_pos, const char* format, ...) const {
va_list args;
va_start(args, format);
- const Error& error = Error::Handle(
- FormatError(script_, token_pos, "Error", format, args));
+ const Error& error = Error::Handle(LanguageError::NewFormattedV(
+ Error::Handle(), script_, token_pos,
+ LanguageError::kError, Heap::kNew, format, args));
va_end(args);
isolate()->long_jump_base()->Jump(1, error);
UNREACHABLE();
@@ -7345,8 +7243,9 @@
void Parser::ErrorMsg(const char* format, ...) {
va_list args;
va_start(args, format);
- const Error& error = Error::Handle(
- FormatError(script_, TokenPos(), "Error", format, args));
+ const Error& error = Error::Handle(LanguageError::NewFormattedV(
+ Error::Handle(), script_, TokenPos(),
+ LanguageError::kError, Heap::kNew, format, args));
va_end(args);
isolate()->long_jump_base()->Jump(1, error);
UNREACHABLE();
@@ -7363,8 +7262,11 @@
const Error& prev_error, intptr_t token_pos, const char* format, ...) {
va_list args;
va_start(args, format);
- const Error& error = Error::Handle(FormatErrorWithAppend(
- prev_error, script_, token_pos, "Error", format, args));
+ const Error& error = Error::Handle(
+ LanguageError::NewFormattedV(
+ prev_error, script_, token_pos,
+ LanguageError::kError, Heap::kNew,
+ format, args));
va_end(args);
isolate()->long_jump_base()->Jump(1, error);
UNREACHABLE();
@@ -7376,7 +7278,10 @@
va_list args;
va_start(args, format);
const Error& error = Error::Handle(
- FormatError(script_, token_pos, "Warning", format, args));
+ LanguageError::NewFormattedV(
+ Error::Handle(), script_, token_pos,
+ LanguageError::kWarning, Heap::kNew,
+ format, args));
va_end(args);
if (FLAG_warning_as_error) {
isolate()->long_jump_base()->Jump(1, error);
@@ -7392,7 +7297,10 @@
va_list args;
va_start(args, format);
const Error& error = Error::Handle(
- FormatError(script_, TokenPos(), "Warning", format, args));
+ LanguageError::NewFormattedV(
+ Error::Handle(), script_, TokenPos(),
+ LanguageError::kWarning, Heap::kNew,
+ format, args));
va_end(args);
if (FLAG_warning_as_error) {
isolate()->long_jump_base()->Jump(1, error);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 41798e3..7b82f6b 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -159,34 +159,6 @@
};
static RawObject* ParseFunctionParameters(const Function& func);
- // Format and print a message with source location.
- // A null script means no source and a negative token_pos means no position.
- static void PrintMessage(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format, ...) PRINTF_ATTRIBUTE(4, 5);
-
- // Build an error object containing a formatted error or warning message.
- // A null script means no source and a negative token_pos means no position.
- static RawError* FormatError(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format,
- va_list args);
- static RawError* FormatErrorMsg(const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format, ...)
- PRINTF_ATTRIBUTE(4, 5);
-
- // Same as FormatError, but appends the new error to the 'prev_error'.
- static RawError* FormatErrorWithAppend(const Error& prev_error,
- const Script& script,
- intptr_t token_pos,
- const char* message_header,
- const char* format,
- va_list args);
-
private:
friend class EffectGraphVisitor; // For BuildNoSuchMethodArguments.
@@ -312,7 +284,7 @@
// A null script means no source and a negative token_pos means no position.
static RawString* FormatMessage(const Script& script,
intptr_t token_pos,
- const char* message_header,
+ LanguageError::Kind kind,
const char* format,
va_list args);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 0d17902..31cd343 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1092,12 +1092,17 @@
RAW_HEAP_OBJECT_IMPLEMENTATION(LanguageError);
RawObject** from() {
- return reinterpret_cast<RawObject**>(&ptr()->message_);
+ return reinterpret_cast<RawObject**>(&ptr()->previous_error_);
}
+ RawError* previous_error_; // May be null.
+ RawScript* script_;
RawString* message_;
+ RawString* formatted_message_; // Incl. previous error's formatted message.
RawObject** to() {
- return reinterpret_cast<RawObject**>(&ptr()->message_);
+ return reinterpret_cast<RawObject**>(&ptr()->formatted_message_);
}
+ intptr_t token_pos_; // Source position in script_.
+ int8_t kind_; // Of type LanguageError::Kind.
};
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index db525ec..e8874af 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1563,6 +1563,10 @@
// Set the object tags.
language_error.set_tags(tags);
+ // Set all non object fields.
+ language_error.set_token_pos(reader->ReadIntptrValue());
+ language_error.set_kind(reader->Read<uint8_t>());
+
// Set all the object fields.
// TODO(5411462): Need to assert No GC can happen here, even though
// allocations may happen.
@@ -1590,6 +1594,10 @@
writer->WriteVMIsolateObject(kLanguageErrorCid);
writer->WriteIntptrValue(writer->GetObjectTags(this));
+ // Write out all the non object fields.
+ writer->WriteIntptrValue(ptr()->token_pos_);
+ writer->Write<uint8_t>(ptr()->kind_);
+
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer);
visitor.VisitPointers(from(), to());
diff --git a/tools/VERSION b/tools/VERSION
index eb9f7be..ef4495b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 1
MINOR 0
BUILD 0
-PATCH 5
+PATCH 6