diff --git a/src/ast/ast.h b/src/ast/ast.h index 41a72f894e..ced9f775dd 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -1405,7 +1405,6 @@ class ObjectLiteral final : public AggregateLiteral { void set_has_null_protoype(bool has_null_prototype) { bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype); } - uint32_t boilerplate_properties_; Handle boilerplate_description_; ZoneList properties_; diff --git a/src/ast/prettyprinter.cc b/src/ast/prettyprinter.cc index 84a8a38baa..581517ee4e 100644 --- a/src/ast/prettyprinter.cc +++ b/src/ast/prettyprinter.cc @@ -27,6 +27,8 @@ CallPrinter::CallPrinter(Isolate* isolate, bool is_user_js) is_call_error_ = false; is_iterator_error_ = false; is_async_iterator_error_ = false; + destructuring_prop_ = nullptr; + destructuring_assignment_ = nullptr; is_user_js_ = is_user_js; function_kind_ = kNormalFunction; InitializeAstVisitor(isolate); @@ -299,24 +301,50 @@ void CallPrinter::VisitVariableProxy(VariableProxy* node) { void CallPrinter::VisitAssignment(Assignment* node) { - Find(node->target()); - if (node->target()->IsArrayLiteral()) { - // Special case the visit for destructuring array assignment. - bool was_found = false; - if (node->value()->position() == position_) { - is_iterator_error_ = true; + bool was_found = false; + if (node->target()->IsObjectLiteral()) { + ObjectLiteral* target = node->target()->AsObjectLiteral(); + if (target->position() == position_) { was_found = !found_; - if (was_found) { - found_ = true; + found_ = true; + destructuring_assignment_ = node; + } else { + for (ObjectLiteralProperty* prop : *target->properties()) { + if (prop->value()->position() == position_) { + was_found = !found_; + found_ = true; + destructuring_prop_ = prop; + destructuring_assignment_ = node; + break; + } } } - Find(node->value(), true); - if (was_found) { - done_ = true; - found_ = false; + } + if (!was_found) { + Find(node->target()); + if (node->target()->IsArrayLiteral()) { + // Special case the visit for destructuring array assignment. + bool was_found = false; + if (node->value()->position() == position_) { + is_iterator_error_ = true; + was_found = !found_; + found_ = true; + } + Find(node->value(), true); + if (was_found) { + done_ = true; + found_ = false; + } + } else { + Find(node->value()); } } else { - Find(node->value()); + Find(node->value(), true); + } + + if (was_found) { + done_ = true; + found_ = false; } } diff --git a/src/ast/prettyprinter.h b/src/ast/prettyprinter.h index cceb5fc269..322fd9fb14 100644 --- a/src/ast/prettyprinter.h +++ b/src/ast/prettyprinter.h @@ -31,6 +31,12 @@ class CallPrinter final : public AstVisitor { kCallAndAsyncIterator }; ErrorHint GetErrorHint() const; + ObjectLiteralProperty* destructuring_prop() const { + return destructuring_prop_; + } + Assignment* destructuring_assignment() const { + return destructuring_assignment_; + } // Individual nodes #define DECLARE_VISIT(type) void Visit##type(type* node); @@ -54,6 +60,8 @@ class CallPrinter final : public AstVisitor { bool is_iterator_error_; bool is_async_iterator_error_; bool is_call_error_; + ObjectLiteralProperty* destructuring_prop_; + Assignment* destructuring_assignment_; FunctionKind function_kind_; DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); diff --git a/src/common/message-template.h b/src/common/message-template.h index 6a8c315c48..e3307a525c 100644 --- a/src/common/message-template.h +++ b/src/common/message-template.h @@ -118,9 +118,9 @@ namespace internal { T(NoAccess, "no access") \ T(NonCallableInInstanceOfCheck, \ "Right-hand side of 'instanceof' is not callable") \ - T(NonCoercible, "Cannot destructure 'undefined' or 'null'.") \ + T(NonCoercible, "Cannot destructure '%' as it is %.") \ T(NonCoercibleWithProperty, \ - "Cannot destructure property `%` of 'undefined' or 'null'.") \ + "Cannot destructure property '%' of '%' as it is %.") \ T(NonExtensibleProto, "% is not extensible") \ T(NonObjectInInstanceOfCheck, \ "Right-hand side of 'instanceof' is not an object") \ diff --git a/src/execution/messages.cc b/src/execution/messages.cc index f0a0f07761..63d1e2be1f 100644 --- a/src/execution/messages.cc +++ b/src/execution/messages.cc @@ -7,8 +7,11 @@ #include #include "src/api/api-inl.h" +#include "src/ast/ast.h" +#include "src/ast/prettyprinter.h" #include "src/base/v8-fallthrough.h" #include "src/execution/execution.h" +#include "src/execution/frames-inl.h" #include "src/execution/frames.h" #include "src/execution/isolate-inl.h" #include "src/logging/counters.h" @@ -18,6 +21,9 @@ #include "src/objects/keys.h" #include "src/objects/stack-frame-info-inl.h" #include "src/objects/struct-inl.h" +#include "src/parsing/parse-info.h" +#include "src/parsing/parsing.h" +#include "src/roots/roots.h" #include "src/strings/string-builder-inl.h" #include "src/wasm/wasm-code-manager.h" #include "src/wasm/wasm-objects.h" @@ -1166,5 +1172,232 @@ MaybeHandle ErrorUtils::MakeGenericError( no_caller, StackTraceCollection::kDetailed); } +namespace { + +bool ComputeLocation(Isolate* isolate, MessageLocation* target) { + JavaScriptFrameIterator it(isolate); + if (!it.done()) { + // Compute the location from the function and the relocation info of the + // baseline code. For optimized code this will use the deoptimization + // information to get canonical location information. + std::vector frames; + it.frame()->Summarize(&frames); + auto& summary = frames.back().AsJavaScript(); + Handle shared(summary.function()->shared(), isolate); + Handle script(shared->script(), isolate); + SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared); + int pos = summary.abstract_code()->SourcePosition(summary.code_offset()); + if (script->IsScript() && + !(Handle