Skip to content

Commit 31befe5

Browse files
committed
SandBox, feat: support async import.
1 parent 6081d12 commit 31befe5

File tree

3 files changed

+84
-30
lines changed

3 files changed

+84
-30
lines changed

fibjs/include/SandBox.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ class SandBox : public SandBox_base {
226226
return false;
227227
}
228228

229+
public:
230+
static v8::MaybeLocal<v8::Promise> ImportModuleDynamically(v8::Local<v8::Context> context,
231+
v8::Local<v8::Data> host_defined_options, v8::Local<v8::Value> resource_name,
232+
v8::Local<v8::String> specifier, v8::Local<v8::FixedArray> import_assertions);
233+
v8::MaybeLocal<v8::Promise> async_import(exlib::string id, exlib::string base);
234+
229235
public:
230236
static const char* worker_args;
231237
static const char* module_args;

fibjs/src/base/Isolate.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -240,30 +240,6 @@ static void _PromiseRejectCallback(v8::PromiseRejectMessage data)
240240
}
241241
}
242242

243-
v8::MaybeLocal<v8::Promise> _HostImportModuleDynamically(v8::Local<v8::Context> context,
244-
v8::Local<v8::Data> host_defined_options, v8::Local<v8::Value> resource_name,
245-
v8::Local<v8::String> specifier, v8::Local<v8::FixedArray> import_assertions)
246-
{
247-
puts("_HostImportModuleDynamically");
248-
Isolate* isolate = Isolate::current(context);
249-
250-
v8::Local<v8::PrimitiveArray> _host_options = host_defined_options.As<v8::PrimitiveArray>();
251-
uint32_t id = _host_options->Get(isolate->m_isolate, 0)->Uint32Value(context).FromMaybe(0);
252-
253-
v8::String::Utf8Value _resource_name(isolate->m_isolate, resource_name);
254-
v8::String::Utf8Value _specifier(isolate->m_isolate, specifier);
255-
256-
printf("id: %d, resource_name: %s, specifier: %s, import_assertions: %d\n", id, *_resource_name, *_specifier, import_assertions->Length());
257-
258-
for (int i = 0; i < import_assertions->Length(); i++) {
259-
v8::Local<v8::Value> import_assertion = v8::Local<v8::Value>::Cast(import_assertions->Get(context, i));
260-
v8::String::Utf8Value _value(isolate->m_isolate, import_assertion);
261-
printf("value: %s\n", *_value);
262-
}
263-
264-
return v8::MaybeLocal<v8::Promise>();
265-
}
266-
267243
void Isolate::init()
268244
{
269245
v8::Locker locker(m_isolate);
@@ -316,7 +292,7 @@ void Isolate::init()
316292
m_AssertionError.Reset(m_isolate, AssertionError);
317293

318294
m_isolate->SetPromiseRejectCallback(_PromiseRejectCallback);
319-
m_isolate->SetHostImportModuleDynamicallyCallback(_HostImportModuleDynamically);
295+
m_isolate->SetHostImportModuleDynamicallyCallback(SandBox::ImportModuleDynamically);
320296

321297
init_process_ipc(this);
322298
}

fibjs/src/sandbox/loaders/mjs_loader.cpp

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,86 @@
88
#include "object.h"
99
#include "path.h"
1010
#include "SandBox.h"
11+
#include "Fiber.h"
1112
#include "loaders.h"
1213
#include "ifs/util.h"
13-
14+
#include "Path.h"
1415
namespace fibjs {
1516

1617
static v8::MaybeLocal<v8::Module> resolveModule(
1718
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
1819
v8::Local<v8::FixedArray> import_assertions, v8::Local<v8::Module> referrer)
1920
{
21+
Isolate* isolate = Isolate::current(context);
22+
23+
for (int i = 0; i < import_assertions->Length(); i++) {
24+
v8::Local<v8::String> v8_assertion_key = import_assertions->Get(context, i).As<v8::String>();
25+
puts(isolate->toString(v8_assertion_key).c_str());
26+
}
27+
28+
ThrowError(isolate->NewString("import is not supported in sandbox"));
2029
return v8::MaybeLocal<v8::Module>();
2130
}
2231

32+
class async_import_data {
33+
public:
34+
obj_ptr<SandBox> m_sb;
35+
exlib::string id;
36+
exlib::string base;
37+
v8::Global<v8::Promise::Resolver> m_resolver;
38+
};
39+
40+
static result_t sync_import(async_import_data* data)
41+
{
42+
JSFiber::EnterJsScope s;
43+
Isolate* isolate = data->m_sb->holder();
44+
v8::Local<v8::Context> context = isolate->context();
45+
46+
v8::Local<v8::Value> retVal;
47+
puts(data->id.c_str());
48+
puts(data->base.c_str());
49+
result_t hr = data->m_sb->run_module(data->id, data->base, retVal);
50+
if (hr < 0)
51+
data->m_resolver.Get(isolate->m_isolate)->Reject(context, FillError(hr));
52+
else
53+
data->m_resolver.Get(isolate->m_isolate)->Resolve(context, retVal);
54+
55+
delete data;
56+
return 0;
57+
}
58+
59+
v8::MaybeLocal<v8::Promise> SandBox::async_import(exlib::string id, exlib::string base)
60+
{
61+
Isolate* isolate = holder();
62+
v8::Local<v8::Context> context = isolate->context();
63+
64+
async_import_data* data = new async_import_data();
65+
data->m_sb = this;
66+
data->id = id;
67+
os_dirname(base, data->base);
68+
69+
v8::Local<v8::Promise::Resolver> resolver = v8::Promise::Resolver::New(context).FromMaybe(v8::Local<v8::Promise::Resolver>());
70+
data->m_resolver.Reset(isolate->m_isolate, resolver);
71+
72+
syncCall(isolate, sync_import, data);
73+
74+
return resolver->GetPromise();
75+
}
76+
77+
v8::MaybeLocal<v8::Promise> SandBox::ImportModuleDynamically(v8::Local<v8::Context> context,
78+
v8::Local<v8::Data> host_defined_options, v8::Local<v8::Value> resource_name,
79+
v8::Local<v8::String> specifier, v8::Local<v8::FixedArray> import_assertions)
80+
{
81+
Isolate* isolate = Isolate::current(context);
82+
v8::Local<v8::PrimitiveArray> _host_options = host_defined_options.As<v8::PrimitiveArray>();
83+
uint32_t id = _host_options->Get(isolate->m_isolate, 0)->Uint32Value(context).FromMaybe(0);
84+
85+
v8::String::Utf8Value _resource_name(isolate->m_isolate, resource_name);
86+
v8::String::Utf8Value _specifier(isolate->m_isolate, specifier);
87+
88+
return isolate->m_sandboxes.find(id)->second->async_import(*_specifier, *_resource_name);
89+
}
90+
2391
result_t mjs_Loader::run(SandBox::Context* ctx, Buffer_base* src, exlib::string name,
2492
exlib::string arg_names, std::vector<v8::Local<v8::Value>>& args)
2593
{
@@ -48,12 +116,16 @@ result_t mjs_Loader::run(SandBox::Context* ctx, Buffer_base* src, exlib::string
48116
module->InstantiateModule(context, resolveModule).IsJust();
49117

50118
v8::Local<v8::Value> promise = module->Evaluate(context).FromMaybe(v8::Local<v8::Value>());
51-
if (promise.IsEmpty())
52-
return throwSyntaxError(try_catch);
119+
if (promise.IsEmpty()) {
120+
try_catch.ReThrow();
121+
return CALL_E_JAVASCRIPT;
122+
}
53123

54124
v8::Local<v8::Value> result = isolate->WaitPromise(promise);
55-
if (result.IsEmpty())
56-
return throwSyntaxError(try_catch);
125+
if (result.IsEmpty()) {
126+
try_catch.ReThrow();
127+
return CALL_E_JAVASCRIPT;
128+
}
57129

58130
v8::Local<v8::Object>::Cast(args[2])->Set(context, isolate->NewString("exports"), module->GetModuleNamespace()).IsJust();
59131

0 commit comments

Comments
 (0)