@@ -177,6 +177,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
177177
178178 meta_lookup : [Types .len ]TypeMeta ,
179179
180+ context_id : usize ,
181+
180182 const Self = @This ();
181183
182184 const TYPE_LOOKUP = TypeLookup {};
@@ -222,6 +224,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
222224 errdefer allocator .destroy (env );
223225
224226 env .* = .{
227+ .context_id = 0 ,
225228 .platform = platform ,
226229 .isolate = isolate ,
227230 .templates = undefined ,
@@ -528,9 +531,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
528531 return error .ConsoleDeleteError ;
529532 }
530533 }
534+ const context_id = env .context_id ;
535+ env .context_id = context_id + 1 ;
531536
532537 self .js_context = JsContext {
533538 .state = state ,
539+ .id = context_id ,
534540 .isolate = isolate ,
535541 .v8_context = v8_context ,
536542 .templates = & env .templates ,
@@ -634,6 +640,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
634640
635641 // Loosely maps to a Browser Page.
636642 pub const JsContext = struct {
643+ id : usize ,
637644 state : State ,
638645 isolate : v8.Isolate ,
639646 // This context is a persistent object. The persistent needs to be recovered and reset.
@@ -1700,6 +1707,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
17001707 // Will get passed to ScriptManager and then passed back to us when
17011708 // the src of the module is loaded
17021709 const DynamicModuleResolveState = struct {
1710+ // this is what we're trying to get from the module and resolve
1711+ // on our promise
1712+ namespace : ? v8.Value ,
1713+ context_id : usize ,
17031714 js_context : * JsContext ,
17041715 specifier : [:0 ]const u8 ,
17051716 resolver : v8.PromiseResolver ,
@@ -1725,6 +1736,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
17251736 .js_context = self ,
17261737 .resolver = resolver ,
17271738 .specifier = specifier ,
1739+ .context_id = self .id ,
1740+ .namespace = null ,
17281741 };
17291742
17301743 const promise = resolver .getPromise ();
@@ -1817,10 +1830,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
18171830
18181831 // we can only be here if the module has been evaluated and if
18191832 // we have a resolve loading this asynchronously.
1820- std .debug .assert (module_entry .module != null );
18211833 std .debug .assert (module_entry .module_promise != null );
18221834 std .debug .assert (module_entry .resolver_promise != null );
18231835 std .debug .assert (self .module_cache .contains (state .specifier ));
1836+ state .namespace = module_entry .module .? .castToModule ().getModuleNamespace ();
18241837
18251838 // We've gotten the source for the module and are evaluating it.
18261839 // You might thing we're done, but the module evaluation is
@@ -1831,23 +1844,36 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
18311844
18321845 const then_callback = v8 .Function .initWithData (ctx , struct {
18331846 pub fn callback (raw_info : ? * const v8.c.FunctionCallbackInfo ) callconv (.c ) void {
1834- const info = v8 .FunctionCallbackInfo .initFromV8 (raw_info );
1835- const isolate = info .getIsolate ();
1847+ var info = v8 .FunctionCallbackInfo .initFromV8 (raw_info );
1848+ var caller = Caller (JsContext , State ).init (info );
1849+ defer caller .deinit ();
18361850
18371851 const s : * DynamicModuleResolveState = @ptrCast (@alignCast (info .getExternalValue ()));
1838- const js_context = s .js_context ;
1839- const me = js_context .module_cache .getPtr (s .specifier ).? ;
1840- const namespace = me .module .? .castToModule ().getModuleNamespace ();
1841- _ = s .resolver .resolve (isolate .getCurrentContext (), namespace );
1852+
1853+ if (s .context_id != caller .js_context .id ) {
1854+ // The microtask is tied to the isolate, not the context
1855+ // it can be resolved while another context is active
1856+ // (Which seems crazy to me). If that happens, then
1857+ // another page was loaded and we MUST ignore thise
1858+ // (most of the fields in state are not valid)
1859+ return ;
1860+ }
1861+
1862+ _ = s .resolver .resolve (caller .js_context .v8_context , s .namespace .? );
18421863 }
18431864 }.callback , external );
18441865
18451866 const catch_callback = v8 .Function .initWithData (ctx , struct {
18461867 pub fn callback (raw_info : ? * const v8.c.FunctionCallbackInfo ) callconv (.c ) void {
1847- const info = v8 .FunctionCallbackInfo .initFromV8 (raw_info );
1848- const isolate = info .getIsolate ();
1849- const data : * DynamicModuleResolveState = @ptrCast (@alignCast (info .getExternalValue ()));
1850- _ = data .resolver .reject (isolate .getCurrentContext (), info .getData ());
1868+ var info = v8 .FunctionCallbackInfo .initFromV8 (raw_info );
1869+ var caller = Caller (JsContext , State ).init (info );
1870+ defer caller .deinit ();
1871+
1872+ const s : * DynamicModuleResolveState = @ptrCast (@alignCast (info .getExternalValue ()));
1873+ if (s .context_id != caller .js_context .id ) {
1874+ return ;
1875+ }
1876+ _ = s .resolver .reject (caller .js_context .v8_context , info .getData ());
18511877 }
18521878 }.callback , external );
18531879
0 commit comments