@@ -40,15 +40,25 @@ static void InitializeImportMetaObject(Local<Context> context, Local<Module> mod
40
40
Local<Object> meta) {
41
41
Isolate* isolate = context->GetIsolate ();
42
42
43
- // Look up the module path in the global module registry
43
+ // Look up the module path in the global module registry (with safety checks)
44
44
std::string modulePath;
45
45
46
- for (auto & kv : tns::g_moduleRegistry) {
47
- Local<Module> registered = kv.second .Get (isolate);
48
- if (registered == module ) {
49
- modulePath = kv.first ;
50
- break ;
46
+ try {
47
+ for (auto & kv : tns::g_moduleRegistry) {
48
+ // Check if Global handle is empty before accessing
49
+ if (kv.second .IsEmpty ()) {
50
+ continue ;
51
+ }
52
+
53
+ Local<Module> registered = kv.second .Get (isolate);
54
+ if (!registered.IsEmpty () && registered == module ) {
55
+ modulePath = kv.first ;
56
+ break ;
57
+ }
51
58
}
59
+ } catch (...) {
60
+ NSLog (@" [import.meta] Exception during module registry lookup, using fallback" );
61
+ modulePath = " " ; // Will use fallback path
52
62
}
53
63
54
64
// Debug logging
@@ -77,6 +87,28 @@ static void InitializeImportMetaObject(Local<Context> context, Local<Module> mod
77
87
context, String::NewFromUtf8 (isolate, " url" , NewStringType::kNormal ).ToLocalChecked (),
78
88
url)
79
89
.Check ();
90
+
91
+ // Add import.meta.dirname support (extract directory from path)
92
+ std::string dirname;
93
+ if (!modulePath.empty ()) {
94
+ size_t lastSlash = modulePath.find_last_of (" /\\ " );
95
+ if (lastSlash != std::string::npos) {
96
+ dirname = modulePath.substr (0 , lastSlash);
97
+ } else {
98
+ dirname = " /app" ; // fallback
99
+ }
100
+ } else {
101
+ dirname = " /app" ; // fallback
102
+ }
103
+
104
+ Local<String> dirnameStr =
105
+ String::NewFromUtf8 (isolate, dirname.c_str (), NewStringType::kNormal ).ToLocalChecked ();
106
+
107
+ // Set import.meta.dirname property
108
+ meta->CreateDataProperty (
109
+ context, String::NewFromUtf8 (isolate, " dirname" , NewStringType::kNormal ).ToLocalChecked (),
110
+ dirnameStr)
111
+ .Check ();
80
112
}
81
113
82
114
namespace tns {
@@ -159,6 +191,15 @@ void DisposeIsolateWhenPossible(Isolate* isolate) {
159
191
160
192
{
161
193
v8::Locker lock (isolate_);
194
+
195
+ // Clear module registry before disposing other handles
196
+ // This prevents crashes during g_moduleRegistry cleanup
197
+ extern std::unordered_map<std::string, v8::Global<v8::Module>> g_moduleRegistry;
198
+ for (auto & kv : g_moduleRegistry) {
199
+ kv.second .Reset ();
200
+ }
201
+ g_moduleRegistry.clear ();
202
+
162
203
DisposerPHV phv (isolate_);
163
204
isolate_->VisitHandlesWithClassIds (&phv);
164
205
@@ -420,6 +461,12 @@ void DisposeIsolateWhenPossible(Isolate* isolate) {
420
461
.FromMaybe (false )) {
421
462
tns::Assert (false , isolate);
422
463
}
464
+
465
+ if (isWorker) {
466
+ // Register proper interop types for worker context
467
+ // Worker bundles need full interop functionality, not just simple stubs
468
+ tns::Interop::RegisterInteropTypes (context);
469
+ }
423
470
}
424
471
425
472
void Runtime::DefineCollectFunction (Local<Context> context) {
0 commit comments