worker: implement worker.moveMessagePortToContext() · nodejs/node@3c6f12c (original) (raw)

`@@ -2,11 +2,13 @@

`

2

2

``

3

3

`#include "async_wrap-inl.h"

`

4

4

`#include "debug_utils.h"

`

``

5

`+

#include "node_contextify.h"

`

5

6

`#include "node_buffer.h"

`

6

7

`#include "node_errors.h"

`

7

8

`#include "node_process.h"

`

8

9

`#include "util.h"

`

9

10

``

``

11

`+

using node::contextify::ContextifyContext;

`

10

12

`using v8::Array;

`

11

13

`using v8::ArrayBuffer;

`

12

14

`using v8::ArrayBufferCreationMode;

`

`@@ -760,6 +762,35 @@ void MessagePort::Drain(const FunctionCallbackInfo& args) {

`

760

762

` port->OnMessage();

`

761

763

`}

`

762

764

``

``

765

`+

void MessagePort::MoveToContext(const FunctionCallbackInfo& args) {

`

``

766

`+

Environment* env = Environment::GetCurrent(args);

`

``

767

`+

if (!args[0]->IsObject() ||

`

``

768

`+

!env->message_port_constructor_template()->HasInstance(args[0])) {

`

``

769

`+

return THROW_ERR_INVALID_ARG_TYPE(env,

`

``

770

`+

"First argument needs to be a MessagePort instance");

`

``

771

`+

}

`

``

772

`+

MessagePort* port = Unwrap(args[0].As());

`

``

773

`+

CHECK_NOT_NULL(port);

`

``

774

+

``

775

`+

Local context_arg = args[1];

`

``

776

`+

ContextifyContext* context_wrapper;

`

``

777

`+

if (!context_arg->IsObject() ||

`

``

778

`+

(context_wrapper = ContextifyContext::ContextFromContextifiedSandbox(

`

``

779

`+

env, context_arg.As())) == nullptr) {

`

``

780

`+

return THROW_ERR_INVALID_ARG_TYPE(env, "Invalid context argument");

`

``

781

`+

}

`

``

782

+

``

783

`+

std::unique_ptr data;

`

``

784

`+

if (!port->IsDetached())

`

``

785

`+

data = port->Detach();

`

``

786

+

``

787

`+

Context::Scope context_scope(context_wrapper->context());

`

``

788

`+

MessagePort* target =

`

``

789

`+

MessagePort::New(env, context_wrapper->context(), std::move(data));

`

``

790

`+

if (target != nullptr)

`

``

791

`+

args.GetReturnValue().Set(target->object());

`

``

792

`+

}

`

``

793

+

763

794

`void MessagePort::Entangle(MessagePort* a, MessagePort* b) {

`

764

795

`Entangle(a, b->data_.get());

`

765

796

`}

`

`@@ -816,9 +847,9 @@ static void MessageChannel(const FunctionCallbackInfo& args) {

`

816

847

` MessagePort* port2 = MessagePort::New(env, context);

`

817

848

`MessagePort::Entangle(port1, port2);

`

818

849

``

819

``

`-

args.This()->Set(env->context(), env->port1_string(), port1->object())

`

``

850

`+

args.This()->Set(context, env->port1_string(), port1->object())

`

820

851

` .FromJust();

`

821

``

`-

args.This()->Set(env->context(), env->port2_string(), port2->object())

`

``

852

`+

args.This()->Set(context, env->port2_string(), port2->object())

`

822

853

` .FromJust();

`

823

854

`}

`

824

855

``

`@@ -833,7 +864,7 @@ static void InitMessaging(Local target,

`

833

864

`FIXED_ONE_BYTE_STRING(env->isolate(), "MessageChannel");

`

834

865

` Local templ = env->NewFunctionTemplate(MessageChannel);

`

835

866

` templ->SetClassName(message_channel_string);

`

836

``

`-

target->Set(env->context(),

`

``

867

`+

target->Set(context,

`

837

868

` message_channel_string,

`

838

869

` templ->GetFunction(context).ToLocalChecked()).FromJust();

`

839

870

` }

`

`@@ -847,6 +878,8 @@ static void InitMessaging(Local target,

`

847

878

`// the browser equivalents do not provide them.

`

848

879

` env->SetMethod(target, "stopMessagePort", MessagePort::Stop);

`

849

880

` env->SetMethod(target, "drainMessagePort", MessagePort::Drain);

`

``

881

`+

env->SetMethod(target, "moveMessagePortToContext",

`

``

882

`+

MessagePort::MoveToContext);

`

850

883

`}

`

851

884

``

852

885

`} // anonymous namespace

`