mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
PR-URL: https://github.com/nodejs/node/pull/23302 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
134 lines
4.0 KiB
C++
134 lines
4.0 KiB
C++
#include "sharedarraybuffer_metadata.h"
|
|
#include "base_object.h"
|
|
#include "base_object-inl.h"
|
|
#include "node_errors.h"
|
|
|
|
using v8::Context;
|
|
using v8::Function;
|
|
using v8::FunctionTemplate;
|
|
using v8::Local;
|
|
using v8::Maybe;
|
|
using v8::MaybeLocal;
|
|
using v8::Nothing;
|
|
using v8::Object;
|
|
using v8::SharedArrayBuffer;
|
|
using v8::Value;
|
|
|
|
namespace node {
|
|
namespace worker {
|
|
|
|
namespace {
|
|
|
|
// Yield a JS constructor for SABLifetimePartner objects in the form of a
|
|
// standard API object, that has a single field for containing the raw
|
|
// SABLifetimePartner* pointer.
|
|
Local<Function> GetSABLifetimePartnerConstructor(
|
|
Environment* env, Local<Context> context) {
|
|
Local<FunctionTemplate> templ;
|
|
templ = env->sab_lifetimepartner_constructor_template();
|
|
if (!templ.IsEmpty())
|
|
return templ->GetFunction(context).ToLocalChecked();
|
|
|
|
templ = BaseObject::MakeLazilyInitializedJSTemplate(env);
|
|
templ->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(),
|
|
"SABLifetimePartner"));
|
|
env->set_sab_lifetimepartner_constructor_template(templ);
|
|
|
|
return GetSABLifetimePartnerConstructor(env, context);
|
|
}
|
|
|
|
class SABLifetimePartner : public BaseObject {
|
|
public:
|
|
SABLifetimePartner(Environment* env,
|
|
Local<Object> obj,
|
|
SharedArrayBufferMetadataReference r)
|
|
: BaseObject(env, obj),
|
|
reference(r) {
|
|
MakeWeak();
|
|
}
|
|
|
|
SET_NO_MEMORY_INFO()
|
|
SET_MEMORY_INFO_NAME(SABLifetimePartner)
|
|
SET_SELF_SIZE(SABLifetimePartner)
|
|
|
|
SharedArrayBufferMetadataReference reference;
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
SharedArrayBufferMetadataReference
|
|
SharedArrayBufferMetadata::ForSharedArrayBuffer(
|
|
Environment* env,
|
|
Local<Context> context,
|
|
Local<SharedArrayBuffer> source) {
|
|
Local<Value> lifetime_partner;
|
|
|
|
if (!source->GetPrivate(context,
|
|
env->sab_lifetimepartner_symbol())
|
|
.ToLocal(&lifetime_partner)) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (lifetime_partner->IsObject() &&
|
|
env->sab_lifetimepartner_constructor_template()
|
|
->HasInstance(lifetime_partner)) {
|
|
CHECK(source->IsExternal());
|
|
SABLifetimePartner* partner =
|
|
Unwrap<SABLifetimePartner>(lifetime_partner.As<Object>());
|
|
CHECK_NE(partner, nullptr);
|
|
return partner->reference;
|
|
}
|
|
|
|
if (source->IsExternal()) {
|
|
// If this is an external SharedArrayBuffer but we do not see a lifetime
|
|
// partner object, it was not us who externalized it. In that case, there
|
|
// is no way to serialize it, because it's unclear how the memory
|
|
// is actually owned.
|
|
THROW_ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER(env);
|
|
return nullptr;
|
|
}
|
|
|
|
SharedArrayBuffer::Contents contents = source->Externalize();
|
|
SharedArrayBufferMetadataReference r(new SharedArrayBufferMetadata(
|
|
contents.Data(), contents.ByteLength()));
|
|
if (r->AssignToSharedArrayBuffer(env, context, source).IsNothing())
|
|
return nullptr;
|
|
return r;
|
|
}
|
|
|
|
Maybe<bool> SharedArrayBufferMetadata::AssignToSharedArrayBuffer(
|
|
Environment* env, Local<Context> context,
|
|
Local<SharedArrayBuffer> target) {
|
|
CHECK(target->IsExternal());
|
|
Local<Function> ctor = GetSABLifetimePartnerConstructor(env, context);
|
|
Local<Object> obj;
|
|
if (!ctor->NewInstance(context).ToLocal(&obj))
|
|
return Nothing<bool>();
|
|
|
|
new SABLifetimePartner(env, obj, shared_from_this());
|
|
return target->SetPrivate(context,
|
|
env->sab_lifetimepartner_symbol(),
|
|
obj);
|
|
}
|
|
|
|
SharedArrayBufferMetadata::SharedArrayBufferMetadata(void* data, size_t size)
|
|
: data(data), size(size) { }
|
|
|
|
SharedArrayBufferMetadata::~SharedArrayBufferMetadata() {
|
|
free(data);
|
|
}
|
|
|
|
MaybeLocal<SharedArrayBuffer> SharedArrayBufferMetadata::GetSharedArrayBuffer(
|
|
Environment* env, Local<Context> context) {
|
|
Local<SharedArrayBuffer> obj =
|
|
SharedArrayBuffer::New(env->isolate(), data, size);
|
|
|
|
if (AssignToSharedArrayBuffer(env, context, obj).IsNothing())
|
|
return MaybeLocal<SharedArrayBuffer>();
|
|
|
|
return obj;
|
|
}
|
|
|
|
} // namespace worker
|
|
} // namespace node
|