Commit 86facf07 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

cppgc: Fix TraceTrait for JSMember

Template specializations must use exact types to match.

Bug: chromium:1056170
Change-Id: I2278e9b40712fc209044fe565023029cc5ae3ff3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2474776
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70527}
parent 193cfbf0
......@@ -66,6 +66,9 @@ class V8_EXPORT JSMemberBase {
friend class v8::JSMember;
friend class v8::JSVisitor;
friend class v8::internal::JSMemberBaseExtractor;
template <typename U>
friend bool operator==(const internal::JSMemberBase&, const Local<U>&);
};
JSMemberBase& JSMemberBase::CopyImpl(const JSMemberBase& other) {
......@@ -93,6 +96,21 @@ void JSMemberBase::Reset() {
SetSlotThreadSafe(nullptr);
}
template <typename U>
inline bool operator==(const v8::internal::JSMemberBase& lhs,
const v8::Local<U>& rhs) {
v8::internal::Address* a = reinterpret_cast<v8::internal::Address*>(lhs.val_);
v8::internal::Address* b = reinterpret_cast<v8::internal::Address*>(*rhs);
if (a == nullptr) return b == nullptr;
if (b == nullptr) return false;
return *a == *b;
}
template <typename U>
inline bool operator!=(const v8::internal::JSMemberBase& lhs, const U& rhs) {
return !(lhs == rhs);
}
} // namespace internal
/**
......@@ -225,9 +243,9 @@ class JSVisitor : public cppgc::Visitor {
namespace cppgc {
template <>
struct TraceTrait<v8::internal::JSMemberBase> {
static void Trace(Visitor* visitor, const v8::internal::JSMemberBase* self) {
template <typename T>
struct TraceTrait<v8::JSMember<T>> {
static void Trace(Visitor* visitor, const v8::JSMember<T>* self) {
static_cast<v8::JSVisitor*>(visitor)->Trace(*self);
}
};
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "include/v8-cppgc.h"
#include "src/heap/cppgc/visitor.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -160,5 +161,44 @@ TEST_F(JSMemberTest, EqualityHeterogenous) {
}
}
namespace {
// Must be used on stack.
class JSVisitorForTesting final : public JSVisitor {
public:
explicit JSVisitorForTesting(v8::Local<v8::Object> expected_object)
: JSVisitor(cppgc::internal::VisitorFactory::CreateKey()),
expected_object_(expected_object) {}
void Visit(const internal::JSMemberBase& ref) final {
EXPECT_EQ(ref, expected_object_);
visit_count_++;
}
size_t visit_count() const { return visit_count_; }
private:
v8::Local<v8::Object> expected_object_;
size_t visit_count_ = 0;
};
} // namespace
TEST_F(JSMemberTest, JSMemberTrace) {
v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
v8::Context::Scope context_scope(context);
{
v8::HandleScope handles(v8_isolate());
v8::Local<v8::Object> local =
v8::Local<v8::Object>::New(v8_isolate(), v8::Object::New(v8_isolate()));
v8::JSMember<v8::Object> js_member(v8_isolate(), local);
JSVisitorForTesting visitor(local);
// Cast to cppgc::Visitor to ensure that we dispatch through the base
// visitor and use traits.
static_cast<cppgc::Visitor&>(visitor).Trace(js_member);
EXPECT_EQ(1u, visitor.visit_count());
}
}
} // namespace internal
} // namespace v8
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