12 using v8::ArrayBuffer;
15 using v8::FunctionCallbackInfo;
16 using v8::FunctionTemplate;
25 using v8::SharedArrayBuffer;
28 using v8::ValueDeserializer;
29 using v8::ValueSerializer;
33 class SerializerContext :
public BaseObject,
34 public ValueSerializer::Delegate {
36 SerializerContext(Environment* env,
39 ~SerializerContext() {}
41 void ThrowDataCloneError(Local<String> message)
override;
42 Maybe<bool> WriteHostObject(Isolate* isolate, Local<Object>
object)
override;
43 Maybe<uint32_t> GetSharedArrayBufferId(
44 Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer)
override;
46 static void SetTreatArrayBufferViewsAsHostObjects(
47 const FunctionCallbackInfo<Value>& args);
49 static void New(
const FunctionCallbackInfo<Value>& args);
50 static void WriteHeader(
const FunctionCallbackInfo<Value>& args);
51 static void WriteValue(
const FunctionCallbackInfo<Value>& args);
52 static void ReleaseBuffer(
const FunctionCallbackInfo<Value>& args);
53 static void TransferArrayBuffer(
const FunctionCallbackInfo<Value>& args);
54 static void WriteUint32(
const FunctionCallbackInfo<Value>& args);
55 static void WriteUint64(
const FunctionCallbackInfo<Value>& args);
56 static void WriteDouble(
const FunctionCallbackInfo<Value>& args);
57 static void WriteRawBytes(
const FunctionCallbackInfo<Value>& args);
59 ValueSerializer serializer_;
62 class DeserializerContext :
public BaseObject,
63 public ValueDeserializer::Delegate {
65 DeserializerContext(Environment* env,
69 ~DeserializerContext() {}
71 MaybeLocal<Object> ReadHostObject(Isolate* isolate)
override;
73 static void New(
const FunctionCallbackInfo<Value>& args);
74 static void ReadHeader(
const FunctionCallbackInfo<Value>& args);
75 static void ReadValue(
const FunctionCallbackInfo<Value>& args);
76 static void TransferArrayBuffer(
const FunctionCallbackInfo<Value>& args);
77 static void GetWireFormatVersion(
const FunctionCallbackInfo<Value>& args);
78 static void ReadUint32(
const FunctionCallbackInfo<Value>& args);
79 static void ReadUint64(
const FunctionCallbackInfo<Value>& args);
80 static void ReadDouble(
const FunctionCallbackInfo<Value>& args);
81 static void ReadRawBytes(
const FunctionCallbackInfo<Value>& args);
86 ValueDeserializer deserializer_;
89 SerializerContext::SerializerContext(Environment* env, Local<Object>
wrap)
90 : BaseObject(env, wrap),
91 serializer_(env->isolate(), this) {
92 MakeWeak<SerializerContext>(
this);
95 void SerializerContext::ThrowDataCloneError(Local<String> message) {
96 Local<Value> args[1] = { message };
97 Local<Value> get_data_clone_error =
98 object()->Get(env()->context(),
99 env()->get_data_clone_error_string())
102 CHECK(get_data_clone_error->IsFunction());
103 MaybeLocal<Value> error =
104 get_data_clone_error.As<Function>()->Call(env()->context(),
109 if (error.IsEmpty())
return;
111 env()->isolate()->ThrowException(error.ToLocalChecked());
114 Maybe<uint32_t> SerializerContext::GetSharedArrayBufferId(
115 Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer) {
116 Local<Value> args[1] = { shared_array_buffer };
117 Local<Value> get_shared_array_buffer_id =
118 object()->Get(env()->context(),
119 env()->get_shared_array_buffer_id_string())
122 if (!get_shared_array_buffer_id->IsFunction()) {
123 return ValueSerializer::Delegate::GetSharedArrayBufferId(
124 isolate, shared_array_buffer);
127 MaybeLocal<Value>
id =
128 get_shared_array_buffer_id.As<Function>()->Call(env()->context(),
133 if (
id.IsEmpty())
return Nothing<uint32_t>();
135 return id.ToLocalChecked()->Uint32Value(env()->context());
138 Maybe<bool> SerializerContext::WriteHostObject(Isolate* isolate,
139 Local<Object> input) {
140 MaybeLocal<Value> ret;
141 Local<Value> args[1] = { input };
143 Local<Value> write_host_object =
144 object()->Get(env()->context(),
145 env()->write_host_object_string()).ToLocalChecked();
147 if (!write_host_object->IsFunction()) {
148 return ValueSerializer::Delegate::WriteHostObject(isolate, input);
151 ret = write_host_object.As<Function>()->Call(env()->context(),
157 return Nothing<bool>();
163 Environment* env = Environment::GetCurrent(args);
165 new SerializerContext(env, args.This());
168 void SerializerContext::WriteHeader(
const FunctionCallbackInfo<Value>& args) {
169 SerializerContext*
ctx;
170 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
171 ctx->serializer_.WriteHeader();
174 void SerializerContext::WriteValue(
const FunctionCallbackInfo<Value>& args) {
175 SerializerContext*
ctx;
176 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
178 ctx->serializer_.WriteValue(ctx->env()->context(), args[0]);
180 if (ret.IsJust()) args.GetReturnValue().Set(ret.FromJust());
183 void SerializerContext::SetTreatArrayBufferViewsAsHostObjects(
184 const FunctionCallbackInfo<Value>& args) {
185 SerializerContext*
ctx;
186 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
188 Maybe<bool> value = args[0]->BooleanValue(ctx->env()->context());
189 if (value.IsNothing())
return;
190 ctx->serializer_.SetTreatArrayBufferViewsAsHostObjects(value.FromJust());
193 void SerializerContext::ReleaseBuffer(
const FunctionCallbackInfo<Value>& args) {
194 SerializerContext*
ctx;
195 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
197 std::pair<uint8_t*, size_t> ret = ctx->serializer_.Release();
199 reinterpret_cast<char*
>(ret.first),
202 if (!
buf.IsEmpty()) {
203 args.GetReturnValue().Set(
buf.ToLocalChecked());
207 void SerializerContext::TransferArrayBuffer(
208 const FunctionCallbackInfo<Value>& args) {
209 SerializerContext*
ctx;
210 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
212 Maybe<uint32_t>
id = args[0]->Uint32Value(ctx->env()->context());
213 if (
id.IsNothing())
return;
215 if (!args[1]->IsArrayBuffer())
216 return ctx->env()->ThrowTypeError(
"arrayBuffer must be an ArrayBuffer");
218 Local<ArrayBuffer> ab = args[1].As<ArrayBuffer>();
219 ctx->serializer_.TransferArrayBuffer(
id.FromJust(), ab);
223 void SerializerContext::WriteUint32(
const FunctionCallbackInfo<Value>& args) {
224 SerializerContext*
ctx;
225 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
227 Maybe<uint32_t> value = args[0]->Uint32Value(ctx->env()->context());
228 if (value.IsNothing())
return;
230 ctx->serializer_.WriteUint32(value.FromJust());
233 void SerializerContext::WriteUint64(
const FunctionCallbackInfo<Value>& args) {
234 SerializerContext*
ctx;
235 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
237 Maybe<uint32_t> arg0 = args[0]->Uint32Value(ctx->env()->context());
238 Maybe<uint32_t> arg1 = args[1]->Uint32Value(ctx->env()->context());
239 if (arg0.IsNothing() || arg1.IsNothing())
242 uint64_t hi = arg0.FromJust();
243 uint64_t lo = arg1.FromJust();
244 ctx->serializer_.WriteUint64((hi << 32) | lo);
247 void SerializerContext::WriteDouble(
const FunctionCallbackInfo<Value>& args) {
248 SerializerContext*
ctx;
249 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
251 Maybe<double> value = args[0]->NumberValue(ctx->env()->context());
252 if (value.IsNothing())
return;
254 ctx->serializer_.WriteDouble(value.FromJust());
257 void SerializerContext::WriteRawBytes(
const FunctionCallbackInfo<Value>& args) {
258 SerializerContext*
ctx;
259 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
261 if (!args[0]->IsUint8Array()) {
262 return ctx->env()->ThrowTypeError(
"source must be a Uint8Array");
269 DeserializerContext::DeserializerContext(Environment* env,
272 : BaseObject(env, wrap),
273 data_(reinterpret_cast<const uint8_t*>(Buffer::
Data(buffer))),
274 length_(Buffer::
Length(buffer)),
275 deserializer_(env->isolate(), data_, length_, this) {
276 object()->Set(env->context(), env->buffer_string(), buffer).FromJust();
278 MakeWeak<DeserializerContext>(
this);
281 MaybeLocal<Object> DeserializerContext::ReadHostObject(Isolate* isolate) {
282 Local<Value> read_host_object =
283 object()->Get(env()->context(),
284 env()->read_host_object_string()).ToLocalChecked();
286 if (!read_host_object->IsFunction()) {
287 return ValueDeserializer::Delegate::ReadHostObject(isolate);
290 MaybeLocal<Value> ret =
291 read_host_object.As<Function>()->Call(env()->context(),
297 return MaybeLocal<Object>();
299 Local<Value> return_value = ret.ToLocalChecked();
300 if (!return_value->IsObject()) {
301 env()->ThrowTypeError(
"readHostObject must return an object");
302 return MaybeLocal<Object>();
305 return return_value.As<Object>();
309 Environment* env = Environment::GetCurrent(args);
311 if (!args[0]->IsUint8Array()) {
312 return env->ThrowTypeError(
"buffer must be a Uint8Array");
315 new DeserializerContext(env, args.This(), args[0]);
318 void DeserializerContext::ReadHeader(
const FunctionCallbackInfo<Value>& args) {
319 DeserializerContext*
ctx;
320 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
322 Maybe<bool> ret = ctx->deserializer_.ReadHeader(ctx->env()->context());
324 if (ret.IsJust()) args.GetReturnValue().Set(ret.FromJust());
327 void DeserializerContext::ReadValue(
const FunctionCallbackInfo<Value>& args) {
328 DeserializerContext*
ctx;
329 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
331 MaybeLocal<Value> ret = ctx->deserializer_.ReadValue(ctx->env()->context());
333 if (!ret.IsEmpty()) args.GetReturnValue().Set(ret.ToLocalChecked());
336 void DeserializerContext::TransferArrayBuffer(
337 const FunctionCallbackInfo<Value>& args) {
338 DeserializerContext*
ctx;
339 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
341 Maybe<uint32_t>
id = args[0]->Uint32Value(ctx->env()->context());
342 if (
id.IsNothing())
return;
344 if (args[1]->IsArrayBuffer()) {
345 Local<ArrayBuffer> ab = args[1].As<ArrayBuffer>();
346 ctx->deserializer_.TransferArrayBuffer(
id.FromJust(), ab);
350 if (args[1]->IsSharedArrayBuffer()) {
351 Local<SharedArrayBuffer> sab = args[1].As<SharedArrayBuffer>();
352 ctx->deserializer_.TransferSharedArrayBuffer(
id.FromJust(), sab);
356 return ctx->env()->ThrowTypeError(
"arrayBuffer must be an ArrayBuffer or " 357 "SharedArrayBuffer");
360 void DeserializerContext::GetWireFormatVersion(
361 const FunctionCallbackInfo<Value>& args) {
362 DeserializerContext*
ctx;
363 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
365 args.GetReturnValue().Set(ctx->deserializer_.GetWireFormatVersion());
368 void DeserializerContext::ReadUint32(
const FunctionCallbackInfo<Value>& args) {
369 DeserializerContext*
ctx;
370 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
373 bool ok = ctx->deserializer_.ReadUint32(&value);
374 if (!ok)
return ctx->env()->ThrowError(
"ReadUint32() failed");
375 return args.GetReturnValue().Set(value);
378 void DeserializerContext::ReadUint64(
const FunctionCallbackInfo<Value>& args) {
379 DeserializerContext*
ctx;
380 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
383 bool ok = ctx->deserializer_.ReadUint64(&value);
384 if (!ok)
return ctx->env()->ThrowError(
"ReadUint64() failed");
386 uint32_t hi =
static_cast<uint32_t
>(value >> 32);
387 uint32_t lo =
static_cast<uint32_t
>(value);
389 Isolate* isolate = ctx->env()->isolate();
390 Local<Context> context = ctx->env()->context();
393 ret->Set(context, 0, Integer::NewFromUnsigned(isolate, hi)).FromJust();
394 ret->Set(context, 1, Integer::NewFromUnsigned(isolate, lo)).FromJust();
395 return args.GetReturnValue().Set(ret);
398 void DeserializerContext::ReadDouble(
const FunctionCallbackInfo<Value>& args) {
399 DeserializerContext*
ctx;
400 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
403 bool ok = ctx->deserializer_.ReadDouble(&value);
404 if (!ok)
return ctx->env()->ThrowError(
"ReadDouble() failed");
405 return args.GetReturnValue().Set(value);
408 void DeserializerContext::ReadRawBytes(
409 const FunctionCallbackInfo<Value>& args) {
410 DeserializerContext*
ctx;
411 ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
413 Maybe<int64_t> length_arg = args[0]->IntegerValue(ctx->env()->context());
414 if (length_arg.IsNothing())
return;
415 size_t length = length_arg.FromJust();
418 bool ok = ctx->deserializer_.ReadRawBytes(length, &data);
419 if (!ok)
return ctx->env()->ThrowError(
"ReadRawBytes() failed");
421 const uint8_t*
position =
reinterpret_cast<const uint8_t*
>(
data);
422 CHECK_GE(position, ctx->data_);
423 CHECK_LE(position + length, ctx->data_ + ctx->length_);
425 const uint32_t offset = position - ctx->data_;
426 CHECK_EQ(ctx->data_ + offset, position);
428 args.GetReturnValue().Set(offset);
431 void InitializeSerdesBindings(Local<Object> target,
433 Local<Context> context) {
434 Environment* env = Environment::GetCurrent(context);
435 Local<FunctionTemplate> ser =
438 ser->InstanceTemplate()->SetInternalFieldCount(1);
440 env->SetProtoMethod(ser,
"writeHeader", SerializerContext::WriteHeader);
441 env->SetProtoMethod(ser,
"writeValue", SerializerContext::WriteValue);
442 env->SetProtoMethod(ser,
"releaseBuffer", SerializerContext::ReleaseBuffer);
443 env->SetProtoMethod(ser,
444 "transferArrayBuffer",
445 SerializerContext::TransferArrayBuffer);
446 env->SetProtoMethod(ser,
"writeUint32", SerializerContext::WriteUint32);
447 env->SetProtoMethod(ser,
"writeUint64", SerializerContext::WriteUint64);
448 env->SetProtoMethod(ser,
"writeDouble", SerializerContext::WriteDouble);
449 env->SetProtoMethod(ser,
"writeRawBytes", SerializerContext::WriteRawBytes);
450 env->SetProtoMethod(ser,
451 "_setTreatArrayBufferViewsAsHostObjects",
452 SerializerContext::SetTreatArrayBufferViewsAsHostObjects);
454 Local<String> serializerString =
455 FIXED_ONE_BYTE_STRING(env->isolate(),
"Serializer");
456 ser->SetClassName(serializerString);
457 target->Set(env->context(),
459 ser->GetFunction(env->context()).ToLocalChecked()).FromJust();
461 Local<FunctionTemplate> des =
464 des->InstanceTemplate()->SetInternalFieldCount(1);
466 env->SetProtoMethod(des,
"readHeader", DeserializerContext::ReadHeader);
467 env->SetProtoMethod(des,
"readValue", DeserializerContext::ReadValue);
468 env->SetProtoMethod(des,
469 "getWireFormatVersion",
470 DeserializerContext::GetWireFormatVersion);
471 env->SetProtoMethod(des,
472 "transferArrayBuffer",
473 DeserializerContext::TransferArrayBuffer);
474 env->SetProtoMethod(des,
"readUint32", DeserializerContext::ReadUint32);
475 env->SetProtoMethod(des,
"readUint64", DeserializerContext::ReadUint64);
476 env->SetProtoMethod(des,
"readDouble", DeserializerContext::ReadDouble);
477 env->SetProtoMethod(des,
"_readRawBytes", DeserializerContext::ReadRawBytes);
479 Local<String> deserializerString =
480 FIXED_ONE_BYTE_STRING(env->isolate(),
"Deserializer");
481 des->SetClassName(deserializerString);
482 target->Set(env->context(),
484 des->GetFunction(env->context()).ToLocalChecked()).FromJust();
NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, node::inspector::Agent::InitInspector)
union node::cares_wrap::@8::CaresAsyncData::@0 data
size_t Length(Local< Value > val)
char * Data(Local< Value > val)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)