summaryrefslogtreecommitdiff
path: root/src/node_worker.cc
diff options
context:
space:
mode:
authorYael Hermon <yaelhe@wix.com>2019-01-04 20:02:25 +0200
committerDaniel Bevenius <daniel.bevenius@gmail.com>2019-01-18 05:39:58 +0100
commit01cd21973b26a2cbacbe143c5983cb4adf8e7681 (patch)
tree16d2712ba9e73dfdb9612acbcde6e0bd8423e097 /src/node_worker.cc
parent74562356db6964f8057ef4bd897725793e55d513 (diff)
downloadandroid-node-v8-01cd21973b26a2cbacbe143c5983cb4adf8e7681.tar.gz
android-node-v8-01cd21973b26a2cbacbe143c5983cb4adf8e7681.tar.bz2
android-node-v8-01cd21973b26a2cbacbe143c5983cb4adf8e7681.zip
worker: enable passing command line flags
This PR adds the ability to provide Workers with their own execArgv flags in replacement of the main thread's execArgv. Only per-Isolate/per-Environment options are allowed. Per-Process options and V8 flags are not allowed. Passing an empty execArgv array will reset per-Isolate and per-Environment options of the Worker to their defaults. If execArgv option is not passed, the Worker will get the same flags as the main thread. Usage example: ``` const worker = new Worker(__filename, { execArgv: ['--trace-warnings'], }); ``` PR-URL: https://github.com/nodejs/node/pull/25467 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src/node_worker.cc')
-rw-r--r--src/node_worker.cc67
1 files changed, 64 insertions, 3 deletions
diff --git a/src/node_worker.cc b/src/node_worker.cc
index dab7945aae..30004957a4 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -10,7 +10,9 @@
#include "async_wrap-inl.h"
#include <string>
+#include <vector>
+using node::options_parser::kDisallowedInEnvironment;
using v8::ArrayBuffer;
using v8::Context;
using v8::Function;
@@ -68,7 +70,10 @@ void WaitForWorkerInspectorToStop(Environment* child) {}
} // anonymous namespace
-Worker::Worker(Environment* env, Local<Object> wrap, const std::string& url)
+Worker::Worker(Environment* env,
+ Local<Object> wrap,
+ const std::string& url,
+ std::shared_ptr<PerIsolateOptions> per_isolate_opts)
: AsyncWrap(env, wrap, AsyncWrap::PROVIDER_WORKER), url_(url) {
// Generate a new thread id.
{
@@ -113,6 +118,9 @@ Worker::Worker(Environment* env, Local<Object> wrap, const std::string& url)
&loop_,
env->isolate_data()->platform(),
array_buffer_allocator_.get()));
+ if (per_isolate_opts != nullptr) {
+ isolate_data_->set_options(per_isolate_opts);
+ }
CHECK(isolate_data_);
Local<Context> context = NewContext(isolate_);
@@ -391,14 +399,67 @@ void Worker::New(const FunctionCallbackInfo<Value>& args) {
}
std::string url;
+ std::shared_ptr<PerIsolateOptions> per_isolate_opts = nullptr;
+
// Argument might be a string or URL
- if (args.Length() == 1 && !args[0]->IsNullOrUndefined()) {
+ if (args.Length() > 0 && !args[0]->IsNullOrUndefined()) {
Utf8Value value(
args.GetIsolate(),
args[0]->ToString(env->context()).FromMaybe(v8::Local<v8::String>()));
url.append(value.out(), value.length());
+
+ if (args.Length() > 1 && args[1]->IsArray()) {
+ v8::Local<v8::Array> array = args[1].As<v8::Array>();
+ // The first argument is reserved for program name, but we don't need it
+ // in workers.
+ std::vector<std::string> exec_argv = {""};
+ uint32_t length = array->Length();
+ for (uint32_t i = 0; i < length; i++) {
+ v8::Local<v8::Value> arg;
+ if (!array->Get(env->context(), i).ToLocal(&arg)) {
+ return;
+ }
+ v8::MaybeLocal<v8::String> arg_v8_string =
+ arg->ToString(env->context());
+ if (arg_v8_string.IsEmpty()) {
+ return;
+ }
+ Utf8Value arg_utf8_value(
+ args.GetIsolate(),
+ arg_v8_string.FromMaybe(v8::Local<v8::String>()));
+ std::string arg_string(arg_utf8_value.out(), arg_utf8_value.length());
+ exec_argv.push_back(arg_string);
+ }
+
+ std::vector<std::string> invalid_args{};
+ std::vector<std::string> errors{};
+ per_isolate_opts.reset(new PerIsolateOptions());
+
+ // Using invalid_args as the v8_args argument as it stores unknown
+ // options for the per isolate parser.
+ options_parser::PerIsolateOptionsParser::instance.Parse(
+ &exec_argv,
+ nullptr,
+ &invalid_args,
+ per_isolate_opts.get(),
+ kDisallowedInEnvironment,
+ &errors);
+
+ // The first argument is program name.
+ invalid_args.erase(invalid_args.begin());
+ if (errors.size() > 0 || invalid_args.size() > 0) {
+ v8::Local<v8::Value> value =
+ ToV8Value(env->context(),
+ errors.size() > 0 ? errors : invalid_args)
+ .ToLocalChecked();
+ Local<String> key =
+ FIXED_ONE_BYTE_STRING(env->isolate(), "invalidExecArgv");
+ args.This()->Set(env->context(), key, value).FromJust();
+ return;
+ }
+ }
}
- new Worker(env, args.This(), url);
+ new Worker(env, args.This(), url, per_isolate_opts);
}
void Worker::StartThread(const FunctionCallbackInfo<Value>& args) {