| 337 | } |
| 338 | |
| 339 | Local<Object> ModuleInternal::LoadModule(Isolate* isolate, const string& modulePath, const string& moduleCacheKey) { |
| 340 | string frameName("LoadModule " + modulePath); |
| 341 | tns::instrumentation::Frame frame(frameName); |
| 342 | Local<Object> result; |
| 343 | |
| 344 | auto context = isolate->GetCurrentContext(); |
| 345 | auto moduleObj = Object::New(isolate); |
| 346 | auto exportsObj = Object::New(isolate); |
| 347 | auto exportsPropName = ArgConverter::ConvertToV8String(isolate, "exports"); |
| 348 | moduleObj->Set(context, exportsPropName, exportsObj); |
| 349 | auto fullRequiredModulePath = ArgConverter::ConvertToV8String(isolate, modulePath); |
| 350 | moduleObj->Set(context, ArgConverter::ConvertToV8String(isolate, "filename"), fullRequiredModulePath); |
| 351 | |
| 352 | auto poModuleObj = new Persistent<Object>(isolate, moduleObj); |
| 353 | TempModule tempModule(this, modulePath, moduleCacheKey, poModuleObj); |
| 354 | |
| 355 | TryCatch tc(isolate); |
| 356 | |
| 357 | // Check if this is an ES module (.mjs) |
| 358 | if (Util::EndsWith(modulePath, ".mjs")) { |
| 359 | // For ES modules, load using the ES module system |
| 360 | Local<Value> moduleNamespace = LoadESModule(isolate, modulePath); |
| 361 | |
| 362 | // Create a wrapper object that behaves like a CommonJS module |
| 363 | // but exports the ES module namespace |
| 364 | moduleObj->Set(context, ArgConverter::ConvertToV8String(isolate, "exports"), moduleNamespace); |
| 365 | |
| 366 | tempModule.SaveToCache(); |
| 367 | result = moduleObj; |
| 368 | return result; |
| 369 | } |
| 370 | |
| 371 | Local<Function> moduleFunc; |
| 372 | |
| 373 | if (Util::EndsWith(modulePath, ".js")) { |
| 374 | auto script = LoadScript(isolate, modulePath, fullRequiredModulePath); |
| 375 | |
| 376 | moduleFunc = script->Run(context).ToLocalChecked().As<Function>(); |
| 377 | if (tc.HasCaught()) { |
| 378 | throw NativeScriptException(tc, "Error running script " + modulePath); |
| 379 | } |
| 380 | } else if (Util::EndsWith(modulePath, ".so")) { |
| 381 | auto handle = dlopen(modulePath.c_str(), RTLD_LAZY); |
| 382 | if (handle == nullptr) { |
| 383 | auto error = dlerror(); |
| 384 | string errMsg(error); |
| 385 | throw NativeScriptException(errMsg); |
| 386 | } |
| 387 | auto func = dlsym(handle, "NSMain"); |
| 388 | if (func == nullptr) { |
| 389 | string errMsg("Cannot find 'NSMain' in " + modulePath); |
| 390 | throw NativeScriptException(errMsg); |
| 391 | } |
| 392 | auto extFunc = External::New(isolate, func); |
| 393 | auto ft = FunctionTemplate::New(isolate, RequireNativeCallback, extFunc); |
| 394 | auto maybeFunc = ft->GetFunction(context); |
| 395 | if (maybeFunc.IsEmpty() || tc.HasCaught()) { |
| 396 | throw NativeScriptException(tc, "Cannot create native module function callback"); |
nothing calls this directly
no test coverage detected