Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 3 additions & 12 deletions src/api/environment.cc
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ void SetIsolateCreateParamsForNode(Isolate::CreateParams* params) {
#endif
}

void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
static void SetIsolateErrorHandlers(v8::Isolate* isolate,
const IsolateSettings& s) {
if (s.flags & MESSAGE_LISTENER_WITH_ERROR_LEVEL)
isolate->AddMessageListenerWithErrorLevel(
errors::PerIsolateMessageListener,
Expand Down Expand Up @@ -350,16 +351,7 @@ Isolate* NewIsolate(Isolate::CreateParams* params,

SetIsolateCreateParamsForNode(params);
Isolate::Initialize(isolate, *params);

Isolate::Scope isolate_scope(isolate);

if (snapshot_data == nullptr) {
// If in deserialize mode, delay until after the deserialization is
// complete.
SetIsolateUpForNode(isolate, settings);
} else {
SetIsolateMiscHandlers(isolate, settings);
}
SetIsolateUpForNode(isolate, settings);

return isolate;
}
Expand Down Expand Up @@ -469,7 +461,6 @@ Environment* CreateEnvironment(
FreeEnvironment(env);
return nullptr;
}
SetIsolateErrorHandlers(isolate, {});
}

Context::Scope context_scope(context);
Expand Down
1 change: 0 additions & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,6 @@ class InitializationResultImpl final : public InitializationResult {
MultiIsolatePlatform* platform_ = nullptr;
};

void SetIsolateErrorHandlers(v8::Isolate* isolate, const IsolateSettings& s);
void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s);
void SetIsolateCreateParamsForNode(v8::Isolate::CreateParams* params);

Expand Down
2 changes: 0 additions & 2 deletions src/node_worker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ class WorkerThreadData {
return;
}

SetIsolateUpForNode(isolate);

// Be sure it's called before Environment::InitializeDiagnostics()
// so that this callback stays when the callback of
// --heapsnapshot-near-heap-limit gets is popped.
Expand Down
79 changes: 79 additions & 0 deletions test/embedding/embedtest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ using node::MultiIsolatePlatform;
using v8::Context;
using v8::HandleScope;
using v8::Isolate;
using v8::Local;
using v8::Locker;
using v8::MaybeLocal;
using v8::V8;
Expand All @@ -27,6 +28,11 @@ using v8::Value;
static int RunNodeInstance(MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);
static int RunSnapshotWithIsolateSettings(
MultiIsolatePlatform* platform,
const node::EmbedderSnapshotData* snapshot,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);

NODE_MAIN(int argc, node::argv_type raw_argv[]) {
char** argv = nullptr;
Expand Down Expand Up @@ -84,6 +90,7 @@ int RunNodeInstance(MultiIsolatePlatform* platform,
// Running snapshot:
// embedtest --embedder-snapshot-blob blob-path
// [--embedder-snapshot-as-file]
// [--embedder-isolate-settings]
// arg1 arg2...
// No snapshot:
// embedtest arg1 arg2...
Expand All @@ -93,6 +100,7 @@ int RunNodeInstance(MultiIsolatePlatform* platform,
std::vector<std::string> filtered_args;
bool is_building_snapshot = false;
bool snapshot_as_file = false;
bool with_isolate_settings = false;
std::optional<node::SnapshotConfig> snapshot_config;
std::string snapshot_blob_path;
for (size_t i = 0; i < args.size(); ++i) {
Expand All @@ -101,6 +109,8 @@ int RunNodeInstance(MultiIsolatePlatform* platform,
is_building_snapshot = true;
} else if (arg == "--embedder-snapshot-as-file") {
snapshot_as_file = true;
} else if (arg == "--embedder-isolate-settings") {
with_isolate_settings = true;
} else if (arg == "--without-code-cache") {
if (!snapshot_config.has_value()) {
snapshot_config = node::SnapshotConfig{};
Expand Down Expand Up @@ -150,6 +160,11 @@ int RunNodeInstance(MultiIsolatePlatform* platform,
node::GetAnonymousMainPath());
}

if (snapshot && with_isolate_settings) {
return RunSnapshotWithIsolateSettings(
platform, snapshot.get(), filtered_args, exec_args);
}

std::vector<std::string> errors;
std::unique_ptr<CommonEnvironmentSetup> setup;

Expand Down Expand Up @@ -233,3 +248,67 @@ int RunNodeInstance(MultiIsolatePlatform* platform,

return exit_code;
}

// CommonEnvironmentSetup does not take IsolateSettings, so this goes through
// NewIsolate()/CreateIsolateData()/CreateEnvironment() directly.
static int RunSnapshotWithIsolateSettings(
MultiIsolatePlatform* platform,
const node::EmbedderSnapshotData* snapshot,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
uv_loop_t loop;
int ret = uv_loop_init(&loop);
assert(ret == 0);

std::shared_ptr<node::ArrayBufferAllocator> allocator =
node::ArrayBufferAllocator::Create();
node::IsolateSettings settings;
settings.prepare_stack_trace_callback = [](Local<Context> context,
Local<Value> exception,
Local<v8::Array> trace) {
return MaybeLocal<Value>(v8::String::NewFromUtf8Literal(
v8::Isolate::GetCurrent(), "stack trace prepared by the embedder"));
};
Isolate* isolate =
node::NewIsolate(allocator, &loop, platform, snapshot, settings);
assert(isolate != nullptr);

int exit_code = 1;
{
Locker locker(isolate);
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);

std::unique_ptr<node::IsolateData, decltype(&node::FreeIsolateData)>
isolate_data(node::CreateIsolateData(
isolate, &loop, platform, allocator.get(), snapshot),
node::FreeIsolateData);
std::unique_ptr<Environment, decltype(&node::FreeEnvironment)> env(
node::CreateEnvironment(
isolate_data.get(), Local<Context>(), args, exec_args),
node::FreeEnvironment);
assert(env);

Context::Scope context_scope(node::GetMainContext(env.get()));
if (!node::LoadEnvironment(env.get(), node::StartExecutionCallback{})
.IsEmpty()) {
exit_code = node::SpinEventLoop(env.get()).FromMaybe(1);
}
node::Stop(env.get());
}

bool platform_finished = false;
platform->AddIsolateFinishedCallback(
isolate,
[](void* data) {
bool* finished = static_cast<bool*>(data);
*finished = true;
},
&platform_finished);
platform->DisposeIsolate(isolate);
while (!platform_finished) uv_run(&loop, UV_RUN_ONCE);
ret = uv_loop_close(&loop);
assert(ret == 0);

return exit_code;
}
38 changes: 38 additions & 0 deletions test/embedding/test-embedding-snapshot-isolate-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use strict';

// IsolateSettings passed to NewIsolate() with a snapshot must survive
// CreateEnvironment(); see RunSnapshotWithIsolateSettings() in embedtest.cc.

const common = require('../common');
const tmpdir = require('../common/tmpdir');

const {
spawnSyncAndAssert,
spawnSyncAndExitWithoutError,
} = require('../common/child_process');

const embedtest = common.resolveBuiltBinary('embedtest');
const snapshotBlobArgs = [
'--embedder-snapshot-blob', tmpdir.resolve('embedder-snapshot.blob'),
];
const buildSnapshotScript = `
require('v8').startupSnapshot.setDeserializeMainFunction(() => {
console.log(new Error('from the snapshot main function').stack);
});
`;

tmpdir.refresh();

spawnSyncAndExitWithoutError(
embedtest,
['--', buildSnapshotScript, ...snapshotBlobArgs, '--embedder-snapshot-create'],
{ cwd: tmpdir.path });

spawnSyncAndAssert(
embedtest,
['--', ...snapshotBlobArgs, '--embedder-isolate-settings'],
{ cwd: tmpdir.path },
{
trim: true,
stdout: 'stack trace prepared by the embedder',
});
Loading