Commit e41aedfe authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

XPath: Simplify had_type_conversion_error handling

EvaluationContext had |bool had_type_conversion_error| field, and we had to copy
the field manually whenever we cloned an EvaluationContext object to propagate
an error to the top-level EvaluationContext.
This CL changes the field to a mutable reference to bool, and it is shared
between cloned EvaluationContext objects.

Change-Id: I5f7e71a25337cfaf413ca98fccc9d3f16a04dba4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1975472
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#726634}
parent acfe6534
......@@ -70,11 +70,13 @@ XPathResult* XPathExpression::evaluate(Node* context_node,
return nullptr;
}
xpath::EvaluationContext evaluation_context(*context_node);
bool had_type_conversion_error = false;
xpath::EvaluationContext evaluation_context(*context_node,
had_type_conversion_error);
auto* result = MakeGarbageCollected<XPathResult>(
evaluation_context, top_expression_->Evaluate(evaluation_context));
if (evaluation_context.had_type_conversion_error) {
if (had_type_conversion_error) {
// It is not specified what to do if type conversion fails while evaluating
// an expression.
exception_state.ThrowDOMException(
......
......@@ -31,11 +31,12 @@
namespace blink {
namespace xpath {
EvaluationContext::EvaluationContext(Node& context_node)
EvaluationContext::EvaluationContext(Node& context_node,
bool& had_type_conversion_error)
: node(context_node),
size(1),
position(1),
had_type_conversion_error(false) {}
had_type_conversion_error(had_type_conversion_error) {}
Expression::Expression()
: is_context_node_sensitive_(false),
......
......@@ -43,14 +43,16 @@ struct CORE_EXPORT EvaluationContext {
STACK_ALLOCATED();
public:
explicit EvaluationContext(Node&);
// |had_type_conversion_error| must be a reference to a variable of
// which lifetime is same as this object, or longer than this object.
EvaluationContext(Node&, bool& had_type_conversion_error);
Member<Node> node;
wtf_size_t size;
wtf_size_t position;
HashMap<String, String> variable_bindings;
bool had_type_conversion_error;
bool& had_type_conversion_error;
};
class CORE_EXPORT ParseNode : public GarbageCollected<ParseNode> {
......
......@@ -25,13 +25,15 @@ class XPathContext {
public:
XPathContext()
: document_(MakeGarbageCollected<Document>()), context_(*document_) {}
: document_(MakeGarbageCollected<Document>()),
context_(*document_, had_type_conversion_error_) {}
xpath::EvaluationContext& Context() { return context_; }
Document& GetDocument() { return *document_; }
private:
const Member<Document> document_;
bool had_type_conversion_error_ = false;
xpath::EvaluationContext context_;
};
......
......@@ -237,12 +237,9 @@ Value Union::Evaluate(EvaluationContext& context) const {
EvaluationContext cloned_context = context;
Value lhs_result = SubExpr(0)->Evaluate(context);
Value rhs = SubExpr(1)->Evaluate(cloned_context);
context.had_type_conversion_error |= cloned_context.had_type_conversion_error;
NodeSet& result_set = lhs_result.ModifiableNodeSet(context);
// We should pass |&context|, not |&cloned_context|, in order to propagate
// a type conversion error to the parent context.
const NodeSet& rhs_nodes = rhs.ToNodeSet(&context);
const NodeSet& rhs_nodes = rhs.ToNodeSet(&cloned_context);
HeapHashSet<Member<Node>> nodes;
for (const auto& node : result_set)
......@@ -273,7 +270,6 @@ bool Predicate::Evaluate(EvaluationContext& context) const {
// context node.
EvaluationContext cloned_context = context;
Value result(expr_->Evaluate(cloned_context));
context.had_type_conversion_error |= cloned_context.had_type_conversion_error;
// foo[3] means foo[position()=3]
if (result.IsNumber())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment