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: Omer Katz <omerkatz@chromium.org> Cr-Commit-Position: refs/heads/master@{#70527}
This commit is contained in:
parent
193cfbf011
commit
86facf07b2
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user