@@ -414,6 +414,86 @@ RtnValue RunScript(ContextPtr ctx_ptr, const char* source, const char* origin) {
414414 return rtn;
415415}
416416
417+ static MaybeLocal<Module> ResolveCallback (Local<Context> context,
418+ Local<String> specifier,
419+ Local<Module> referrer) {
420+ Isolate* isolate = context->GetIsolate ();
421+ isolate->ThrowException (String::NewFromUtf8 (isolate, " import not supported" ).ToLocalChecked ());
422+ return MaybeLocal<Module>();
423+ }
424+
425+ RtnValue RunModule (ContextPtr ctx_ptr, const char * source, const char * origin) {
426+ LOCAL_CONTEXT (ctx_ptr);
427+
428+ Local<String> src =
429+ String::NewFromUtf8 (iso, source, NewStringType::kNormal ).ToLocalChecked ();
430+ Local<String> ogn =
431+ String::NewFromUtf8 (iso, origin, NewStringType::kNormal ).ToLocalChecked ();
432+ RtnValue rtn = {nullptr , nullptr };
433+
434+ ScriptOrigin script_origin (ogn, 0 , 0 , false , -1 , Local<Value>(), false , false , true );
435+ ScriptCompiler::Source csrc (src, script_origin);
436+ MaybeLocal<Module> mmodule = ScriptCompiler::CompileModule (iso, &csrc);
437+ if (mmodule.IsEmpty ()) {
438+ rtn.error = ExceptionError (try_catch, iso, local_ctx);
439+ return rtn;
440+ }
441+
442+ Local<Module> root_module = mmodule.ToLocalChecked ();
443+ if (!root_module->InstantiateModule (local_ctx, &ResolveCallback).FromMaybe (false )) {
444+ rtn.error = ExceptionError (try_catch, iso, local_ctx);
445+ return rtn;
446+ }
447+
448+ Local<Value> result;
449+ if (!root_module->Evaluate (local_ctx).ToLocal (&result)) {
450+ rtn.error = ExceptionError (try_catch, iso, local_ctx);
451+ return rtn;
452+ }
453+
454+ // result is a Promise if the module has imports that need to be resolved
455+ // OR has a top-level await. imports are not supported yet, but awaits are.
456+ //
457+ // If await was not used, the result is undefined, and the module's status
458+ // should already be kEvaluated.
459+ if (result->IsPromise ()) {
460+ // We have to wait. Just busy-loop and poll for completion.
461+ Local<Promise> result_promise (Local<Promise>::Cast (result));
462+ while (result_promise->State () == Promise::kPending ) {
463+ iso->PerformMicrotaskCheckpoint ();
464+ }
465+ if (result_promise->State () == Promise::kRejected ) {
466+ if (!try_catch.HasCaught ()) {
467+ iso->ThrowException (result_promise->Result ());
468+ }
469+ rtn.error = ExceptionError (try_catch, iso, local_ctx);
470+ return rtn;
471+ }
472+ } else if (!result->IsUndefined ()) {
473+ // Verify the invariant that result is either a Promise or undefined.
474+ RtnError err = {nullptr , nullptr , nullptr };
475+ err.msg = CopyString (" expected promise or undefined" );
476+ rtn.error = err;
477+ return rtn;
478+ }
479+
480+ // Verify that the module is now evaluated.
481+ if (root_module->GetStatus () != Module::kEvaluated ) {
482+ RtnError err = {nullptr , nullptr , nullptr };
483+ err.msg = CopyString (" module not evaluated" );
484+ rtn.error = err;
485+ return rtn;
486+ }
487+
488+ m_value* val = new m_value;
489+ val->iso = iso;
490+ val->ctx = ctx;
491+ val->ptr = Persistent<Value, CopyablePersistentTraits<Value>>(iso, root_module->GetModuleNamespace ());
492+
493+ rtn.value = tracked_value (ctx, val);
494+ return rtn;
495+ }
496+
417497RtnValue JSONParse (ContextPtr ctx_ptr, const char * str) {
418498 LOCAL_CONTEXT (ctx_ptr);
419499 RtnValue rtn = {nullptr , nullptr };
@@ -1077,6 +1157,21 @@ int PromiseState(ValuePtr ptr) {
10771157 return promise->State ();
10781158}
10791159
1160+ ValuePtr PromiseThen (ValuePtr ptr, int callback_ref) {
1161+ LOCAL_VALUE (ptr)
1162+ Local<Promise> promise = value.As <Promise>();
1163+ Local<Integer> cbData = Integer::New (iso, callback_ref);
1164+ Local<Function> func = Function::New (local_ctx, FunctionTemplateCallback, cbData)
1165+ .ToLocalChecked ();
1166+ Local<Promise> result = promise->Then (local_ctx, func).ToLocalChecked ();
1167+ m_value* promise_val = new m_value;
1168+ promise_val->iso = iso;
1169+ promise_val->ctx = ctx;
1170+ promise_val->ptr =
1171+ Persistent<Value, CopyablePersistentTraits<Value>>(iso, promise);
1172+ return tracked_value (ctx, promise_val);
1173+ }
1174+
10801175ValuePtr PromiseResult (ValuePtr ptr) {
10811176 LOCAL_VALUE (ptr)
10821177 Local<Promise> promise = value.As <Promise>();
@@ -1091,6 +1186,21 @@ ValuePtr PromiseResult(ValuePtr ptr) {
10911186
10921187/* ********* Function **********/
10931188
1189+ ValuePtr NewFunction (ContextPtr ctx_ptr, int callback_ref) {
1190+ LOCAL_CONTEXT (ctx_ptr);
1191+
1192+ Local<Integer> cbData = Integer::New (iso, callback_ref);
1193+ Local<Function> func = Function::New (local_ctx, FunctionTemplateCallback, cbData)
1194+ .ToLocalChecked ();
1195+
1196+ m_value* val = new m_value;
1197+ val->iso = iso;
1198+ val->ctx = ctx;
1199+ val->ptr = Persistent<Value, CopyablePersistentTraits<Value>>(iso, func);
1200+
1201+ return tracked_value (ctx, val);
1202+ }
1203+
10941204RtnValue FunctionCall (ValuePtr ptr, int argc, ValuePtr args[]) {
10951205 LOCAL_VALUE (ptr)
10961206 RtnValue rtn = {nullptr , nullptr };
0 commit comments