@@ -1805,25 +1805,16 @@ void NativeCryptoKey::RegisterExternalReferences(
18051805}
18061806
18071807namespace {
1808- // Brand check: every NativeCryptoKey stores this pointer in its
1809- // kClassTagField slot. Nothing else in the binary can produce the
1810- // same pointer, so HasInstance() can use it to recognize a real
1811- // NativeCryptoKey.
1812- constexpr int kNativeCryptoKeyClassTag = 0 ;
1813- const void * class_tag () {
1814- return &kNativeCryptoKeyClassTag ;
1808+ // Verifies that `value` is a `NativeCryptoKey` by checking whether it
1809+ // was constructed from the Environment's `NativeCryptoKey` template.
1810+ bool IsNativeCryptoKey (Environment* env, Local<Value> value) {
1811+ auto t = env->crypto_cryptokey_constructor_template ();
1812+ return !t.IsEmpty () && t->HasInstance (value);
18151813}
18161814} // namespace
18171815
1818- bool NativeCryptoKey::HasInstance (Local<Value> value) {
1819- if (!value->IsObject ()) return false ;
1820- Local<Object> obj = value.As <Object>();
1821- if (obj->InternalFieldCount () < NativeCryptoKey::kInternalFieldCount ) {
1822- return false ;
1823- }
1824- return obj->GetAlignedPointerFromInternalField (
1825- NativeCryptoKey::kClassTagField , EmbedderDataTag::kDefault ) ==
1826- class_tag ();
1816+ bool NativeCryptoKey::HasInstance (Environment* env, Local<Value> value) {
1817+ return IsNativeCryptoKey (env, value);
18271818}
18281819
18291820void NativeCryptoKey::New (const FunctionCallbackInfo<Value>& args) {
@@ -1848,17 +1839,12 @@ void NativeCryptoKey::New(const FunctionCallbackInfo<Value>& args) {
18481839
18491840 auto * native = new NativeCryptoKey (env, args.This (), handle->Data ());
18501841
1851- // Brand-check tag for HasInstance().
1852- args.This ()->SetAlignedPointerInInternalField (kClassTagField ,
1853- const_cast <void *>(class_tag ()),
1854- EmbedderDataTag::kDefault );
1855-
18561842 if (!args[1 ]->IsUndefined ()) {
18571843 CHECK (args[1 ]->IsObject ());
18581844 CHECK (args[2 ]->IsArray ());
18591845 CHECK (args[3 ]->IsBoolean ());
1860- native-> algorithm_ . Reset (env-> isolate () , args[1 ]. As <Object>() );
1861- native-> usages_ . Reset (env-> isolate () , args[2 ]. As <Array>() );
1846+ args. This ()-> SetInternalField ( kAlgorithmField , args[1 ]);
1847+ args. This ()-> SetInternalField ( kUsagesField , args[2 ]);
18621848 native->extractable_ = args[3 ]->IsTrue ();
18631849 }
18641850}
@@ -1876,6 +1862,8 @@ void NativeCryptoKey::CreateCryptoKeyClass(
18761862 NewFunctionTemplate (isolate, NativeCryptoKey::New);
18771863 t->InstanceTemplate ()->SetInternalFieldCount (
18781864 NativeCryptoKey::kInternalFieldCount );
1865+ CHECK (env->crypto_cryptokey_constructor_template ().IsEmpty ());
1866+ env->set_crypto_cryptokey_constructor_template (t);
18791867
18801868 Local<Value> ctor;
18811869 if (!t->GetFunction (env->context ()).ToLocal (&ctor)) return ;
@@ -1890,6 +1878,7 @@ void NativeCryptoKey::CreateCryptoKeyClass(
18901878 Local<Array> ret = ret_v.As <Array>();
18911879 Local<Value> internal_ctor_v;
18921880 if (!ret->Get (env->context (), 1 ).ToLocal (&internal_ctor_v)) return ;
1881+ CHECK (env->crypto_internal_cryptokey_constructor ().IsEmpty ());
18931882 env->set_crypto_internal_cryptokey_constructor (
18941883 internal_ctor_v.As <Function>());
18951884 args.GetReturnValue ().Set (ret);
@@ -1902,12 +1891,13 @@ void NativeCryptoKey::CreateCryptoKeyClass(
19021891void NativeCryptoKey::GetSlots (const FunctionCallbackInfo<Value>& args) {
19031892 Environment* env = Environment::GetCurrent (args);
19041893 CHECK_EQ (args.Length (), 1 );
1905- if (!HasInstance (args[0 ])) {
1894+ if (!HasInstance (env, args[0 ])) {
19061895 THROW_ERR_INVALID_THIS (env, " Value of \" this\" must be of type CryptoKey" );
19071896 return ;
19081897 }
19091898 Isolate* isolate = env->isolate ();
1910- NativeCryptoKey* native = Unwrap<NativeCryptoKey>(args[0 ].As <Object>());
1899+ Local<Object> obj = args[0 ].As <Object>();
1900+ NativeCryptoKey* native = Unwrap<NativeCryptoKey>(obj);
19111901
19121902 const char * type_str;
19131903 switch (native->handle_data_ .GetKeyType ()) {
@@ -1929,13 +1919,15 @@ void NativeCryptoKey::GetSlots(const FunctionCallbackInfo<Value>& args) {
19291919 return ;
19301920 }
19311921
1932- CHECK (!native->algorithm_ .IsEmpty ());
1933- CHECK (!native->usages_ .IsEmpty ());
1922+ Local<Value> algorithm = obj->GetInternalField (kAlgorithmField ).As <Value>();
1923+ Local<Value> usages = obj->GetInternalField (kUsagesField ).As <Value>();
1924+ CHECK (algorithm->IsObject ());
1925+ CHECK (usages->IsArray ());
19341926 Local<Value> slots[] = {
19351927 OneByteString (isolate, type_str),
19361928 v8::Boolean::New (isolate, native->extractable_ ),
1937- PersistentToLocal::Strong (native-> algorithm_ ) ,
1938- PersistentToLocal::Strong (native-> usages_ ) ,
1929+ algorithm ,
1930+ usages ,
19391931 handle,
19401932 };
19411933 args.GetReturnValue ().Set (Array::New (isolate, slots, arraysize (slots)));
@@ -1948,11 +1940,13 @@ BaseObject::TransferMode NativeCryptoKey::GetTransferMode() const {
19481940std::unique_ptr<worker::TransferData> NativeCryptoKey::CloneForMessaging ()
19491941 const {
19501942 Isolate* isolate = env ()->isolate ();
1951- CHECK (!algorithm_.IsEmpty ());
1952- CHECK (!usages_.IsEmpty ());
1953- v8::Global<Object> algorithm_copy (isolate,
1954- PersistentToLocal::Strong (algorithm_));
1955- v8::Global<Array> usages_copy (isolate, PersistentToLocal::Strong (usages_));
1943+ Local<Object> obj = object ();
1944+ Local<Value> algorithm_v = obj->GetInternalField (kAlgorithmField ).As <Value>();
1945+ Local<Value> usages_v = obj->GetInternalField (kUsagesField ).As <Value>();
1946+ CHECK (algorithm_v->IsObject ());
1947+ CHECK (usages_v->IsArray ());
1948+ v8::Global<Object> algorithm_copy (isolate, algorithm_v.As <Object>());
1949+ v8::Global<Array> usages_copy (isolate, usages_v.As <Array>());
19561950 return std::make_unique<CryptoKeyTransferData>(handle_data_,
19571951 std::move (algorithm_copy),
19581952 std::move (usages_copy),
@@ -1968,22 +1962,29 @@ Maybe<void> NativeCryptoKey::FinalizeTransferRead(
19681962 CHECK (bundle_v->IsObject ());
19691963 Local<Object> bundle = bundle_v.As <Object>();
19701964 Isolate* isolate = env ()->isolate ();
1965+ Local<Object> obj = object ();
1966+
1967+ // The partially-initialized object produced by
1968+ // CryptoKeyTransferData::Deserialize should not have algorithm/usages
1969+ // set yet.
1970+ CHECK (obj->GetInternalField (kAlgorithmField ).As <Value>()->IsUndefined ());
1971+ CHECK (obj->GetInternalField (kUsagesField ).As <Value>()->IsUndefined ());
19711972
19721973 Local<Value> algorithm_v;
19731974 if (!bundle->Get (context, FIXED_ONE_BYTE_STRING (isolate, " algorithm" ))
19741975 .ToLocal (&algorithm_v)) {
19751976 return Nothing<void >();
19761977 }
19771978 CHECK (algorithm_v->IsObject ());
1978- algorithm_. Reset (isolate , algorithm_v. As <Object>() );
1979+ obj-> SetInternalField ( kAlgorithmField , algorithm_v);
19791980
19801981 Local<Value> usages_v;
19811982 if (!bundle->Get (context, FIXED_ONE_BYTE_STRING (isolate, " usages" ))
19821983 .ToLocal (&usages_v)) {
19831984 return Nothing<void >();
19841985 }
19851986 CHECK (usages_v->IsArray ());
1986- usages_. Reset (isolate , usages_v. As <Array>() );
1987+ obj-> SetInternalField ( kUsagesField , usages_v);
19871988
19881989 Local<Value> extractable_v;
19891990 if (!bundle->Get (context, FIXED_ONE_BYTE_STRING (isolate, " extractable" ))
@@ -2067,8 +2068,6 @@ BaseObjectPtr<BaseObject> NativeCryptoKey::CryptoKeyTransferData::Deserialize(
20672068
20682069void NativeCryptoKey::MemoryInfo (MemoryTracker* tracker) const {
20692070 tracker->TrackField (" handle_data" , handle_data_);
2070- tracker->TrackField (" algorithm" , algorithm_);
2071- tracker->TrackField (" usages" , usages_);
20722071}
20732072
20742073void NativeCryptoKey::CryptoKeyTransferData::MemoryInfo (
0 commit comments