Skip to content

Commit ce03b17

Browse files
committed
feat: logScriptLoading - this may be unnecessary really, added for alpha testing largely
1 parent e66a428 commit ce03b17

File tree

3 files changed

+112
-23
lines changed

3 files changed

+112
-23
lines changed

test-app/runtime/src/main/cpp/ModuleInternalCallbacks.cpp

Lines changed: 88 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <string>
99
#include <vector>
1010
#include <algorithm>
11+
#include <atomic>
1112

1213
using namespace v8;
1314
using namespace std;
@@ -16,6 +17,39 @@ using namespace tns;
1617
// External global module registry declared in ModuleInternal.cpp
1718
extern std::unordered_map<std::string, v8::Global<v8::Module>> g_moduleRegistry;
1819

20+
// Forward declaration used by logging helper
21+
std::string GetApplicationPath();
22+
23+
// Cached toggle for verbose script loading logs sourced from Java AppConfig via JNI
24+
static bool ShouldLogScriptLoading() {
25+
static std::atomic<int> cached{-1}; // -1 unknown, 0 false, 1 true
26+
int v = cached.load(std::memory_order_acquire);
27+
if (v != -1) {
28+
return v == 1;
29+
}
30+
31+
static std::once_flag initFlag;
32+
std::call_once(initFlag, []() {
33+
bool enabled = false;
34+
try {
35+
JEnv env;
36+
jclass runtimeClass = env.FindClass("com/tns/Runtime");
37+
if (runtimeClass != nullptr) {
38+
jmethodID mid = env.GetStaticMethodID(runtimeClass, "getLogScriptLoadingEnabled", "()Z");
39+
if (mid != nullptr) {
40+
jboolean res = env.CallStaticBooleanMethod(runtimeClass, mid);
41+
enabled = (res == JNI_TRUE);
42+
}
43+
}
44+
} catch (...) {
45+
// ignore and keep default false
46+
}
47+
cached.store(enabled ? 1 : 0, std::memory_order_release);
48+
});
49+
50+
return cached.load(std::memory_order_acquire) == 1;
51+
}
52+
1953
// Import meta callback to support import.meta.url and import.meta.dirname
2054
void InitializeImportMetaObject(Local<Context> context, Local<Module> module, Local<Object> meta) {
2155
Isolate* isolate = context->GetIsolate();
@@ -41,9 +75,11 @@ void InitializeImportMetaObject(Local<Context> context, Local<Module> module, Lo
4175
modulePath = ""; // Will use fallback path
4276
}
4377

44-
DEBUG_WRITE("InitializeImportMetaObject: Module lookup: found path = %s",
45-
modulePath.empty() ? "(empty)" : modulePath.c_str());
46-
DEBUG_WRITE("InitializeImportMetaObject: Registry size: %zu", g_moduleRegistry.size());
78+
if (ShouldLogScriptLoading()) {
79+
DEBUG_WRITE("InitializeImportMetaObject: Module lookup: found path = %s",
80+
modulePath.empty() ? "(empty)" : modulePath.c_str());
81+
DEBUG_WRITE("InitializeImportMetaObject: Registry size: %zu", g_moduleRegistry.size());
82+
}
4783

4884
// Convert file path to file:// URL
4985
std::string moduleUrl;
@@ -55,7 +91,9 @@ void InitializeImportMetaObject(Local<Context> context, Local<Module> module, Lo
5591
moduleUrl = "file:///android_asset/app/";
5692
}
5793

58-
DEBUG_WRITE("InitializeImportMetaObject: Final URL: %s", moduleUrl.c_str());
94+
if (ShouldLogScriptLoading()) {
95+
DEBUG_WRITE("InitializeImportMetaObject: Final URL: %s", moduleUrl.c_str());
96+
}
5997

6098
Local<String> url = ArgConverter::ConvertToV8String(isolate, moduleUrl);
6199

@@ -128,8 +166,9 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
128166
}
129167

130168
// Debug logging
131-
DEBUG_WRITE("ResolveModuleCallback: Resolving '%s'", spec.c_str());
132-
__android_log_print(ANDROID_LOG_DEBUG, "TNS.ResolveCallback", "Resolving module: '%s'", spec.c_str());
169+
if (ShouldLogScriptLoading()) {
170+
DEBUG_WRITE("ResolveModuleCallback: Resolving '%s'", spec.c_str());
171+
}
133172

134173
// 2) Find which filepath the referrer was compiled under
135174
std::string referrerPath;
@@ -161,8 +200,10 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
161200
std::string cleanSpec = spec.substr(0, 2) == "./" ? spec.substr(2) : spec;
162201
std::string candidate = baseDir + cleanSpec;
163202
candidateBases.push_back(candidate);
164-
DEBUG_WRITE("ResolveModuleCallback: Relative import: '%s' + '%s' -> '%s'",
165-
baseDir.c_str(), cleanSpec.c_str(), candidate.c_str());
203+
if (ShouldLogScriptLoading()) {
204+
DEBUG_WRITE("ResolveModuleCallback: Relative import: '%s' + '%s' -> '%s'",
205+
baseDir.c_str(), cleanSpec.c_str(), candidate.c_str());
206+
}
166207
} else if (spec.size() > 7 && spec.substr(0, 7) == "file://") {
167208
// Absolute file URL
168209
std::string tail = spec.substr(7); // strip file://
@@ -178,19 +219,27 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
178219
if (tail.rfind(appVirtualRoot, 0) == 0) {
179220
// Drop the leading "/app/" and prepend real appPath
180221
candidate = appPath + "/" + tail.substr(appVirtualRoot.size());
181-
DEBUG_WRITE("ResolveModuleCallback: file:// to appPath mapping: '%s' -> '%s'", tail.c_str(), candidate.c_str());
222+
if (ShouldLogScriptLoading()) {
223+
DEBUG_WRITE("ResolveModuleCallback: file:// to appPath mapping: '%s' -> '%s'", tail.c_str(), candidate.c_str());
224+
}
182225
} else if (tail.rfind(androidAssetAppRoot, 0) == 0) {
183226
// Replace "/android_asset/app/" with the real appPath
184227
candidate = appPath + "/" + tail.substr(androidAssetAppRoot.size());
185-
DEBUG_WRITE("ResolveModuleCallback: file:// android_asset mapping: '%s' -> '%s'", tail.c_str(), candidate.c_str());
228+
if (ShouldLogScriptLoading()) {
229+
DEBUG_WRITE("ResolveModuleCallback: file:// android_asset mapping: '%s' -> '%s'", tail.c_str(), candidate.c_str());
230+
}
186231
} else if (tail.rfind(appPath, 0) == 0) {
187232
// Already an absolute on-disk path to the app folder
188233
candidate = tail;
189-
DEBUG_WRITE("ResolveModuleCallback: file:// absolute path preserved: '%s'", candidate.c_str());
234+
if (ShouldLogScriptLoading()) {
235+
DEBUG_WRITE("ResolveModuleCallback: file:// absolute path preserved: '%s'", candidate.c_str());
236+
}
190237
} else {
191238
// Fallback: treat as absolute on-disk path
192239
candidate = tail;
193-
DEBUG_WRITE("ResolveModuleCallback: file:// generic absolute: '%s'", candidate.c_str());
240+
if (ShouldLogScriptLoading()) {
241+
DEBUG_WRITE("ResolveModuleCallback: file:// generic absolute: '%s'", candidate.c_str());
242+
}
194243
}
195244

196245
candidateBases.push_back(candidate);
@@ -423,7 +472,9 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
423472

424473
// 7) Handle JSON modules
425474
if (absPath.size() >= 5 && absPath.compare(absPath.size() - 5, 5, ".json") == 0) {
426-
DEBUG_WRITE("ResolveModuleCallback: Handling JSON module '%s'", absPath.c_str());
475+
if (ShouldLogScriptLoading()) {
476+
DEBUG_WRITE("ResolveModuleCallback: Handling JSON module '%s'", absPath.c_str());
477+
}
427478

428479
// Read JSON file content
429480
std::string jsonText = Runtime::GetRuntime(isolate)->ReadFileText(absPath);
@@ -475,12 +526,16 @@ v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
475526
// 8) Check if we've already compiled this module
476527
auto it = g_moduleRegistry.find(absPath);
477528
if (it != g_moduleRegistry.end()) {
478-
DEBUG_WRITE("ResolveModuleCallback: Found cached module '%s'", absPath.c_str());
529+
if (ShouldLogScriptLoading()) {
530+
DEBUG_WRITE("ResolveModuleCallback: Found cached module '%s'", absPath.c_str());
531+
}
479532
return v8::MaybeLocal<v8::Module>(it->second.Get(isolate));
480533
}
481534

482535
// 9) Compile and register the new module
483-
DEBUG_WRITE("ResolveModuleCallback: Compiling new module '%s'", absPath.c_str());
536+
if (ShouldLogScriptLoading()) {
537+
DEBUG_WRITE("ResolveModuleCallback: Compiling new module '%s'", absPath.c_str());
538+
}
484539
try {
485540
// Use our existing LoadESModule function to compile the module
486541
tns::ModuleInternal::LoadESModule(isolate, absPath);
@@ -513,8 +568,9 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
513568
v8::String::Utf8Value specUtf8(isolate, specifier);
514569
std::string spec = *specUtf8 ? *specUtf8 : "";
515570

516-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Dynamic import for '%s'", spec.c_str());
517-
__android_log_print(ANDROID_LOG_DEBUG, "TNS.ImportCallback", "Dynamic import: '%s'", spec.c_str());
571+
if (ShouldLogScriptLoading()) {
572+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Dynamic import for '%s'", spec.c_str());
573+
}
518574

519575
v8::EscapableHandleScope scope(isolate);
520576

@@ -537,7 +593,9 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
537593
v8::Local<v8::Module> module;
538594
if (!maybeModule.ToLocal(&module)) {
539595
// Resolution failed; reject to avoid leaving a pending Promise (white screen)
540-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Resolution failed for '%s'", spec.c_str());
596+
if (ShouldLogScriptLoading()) {
597+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Resolution failed for '%s'", spec.c_str());
598+
}
541599
v8::Local<v8::Value> ex = v8::Exception::Error(
542600
ArgConverter::ConvertToV8String(isolate, std::string("Failed to resolve module: ") + spec));
543601
resolver->Reject(context, ex).Check();
@@ -547,7 +605,9 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
547605
// If not yet instantiated/evaluated, do it now
548606
if (module->GetStatus() == v8::Module::kUninstantiated) {
549607
if (!module->InstantiateModule(context, &ResolveModuleCallback).FromMaybe(false)) {
550-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Instantiate failed for '%s'", spec.c_str());
608+
if (ShouldLogScriptLoading()) {
609+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Instantiate failed for '%s'", spec.c_str());
610+
}
551611
resolver
552612
->Reject(context,
553613
v8::Exception::Error(ArgConverter::ConvertToV8String(isolate, "Failed to instantiate module")))
@@ -558,7 +618,9 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
558618

559619
if (module->GetStatus() != v8::Module::kEvaluated) {
560620
if (module->Evaluate(context).IsEmpty()) {
561-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Evaluation failed for '%s'", spec.c_str());
621+
if (ShouldLogScriptLoading()) {
622+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Evaluation failed for '%s'", spec.c_str());
623+
}
562624
v8::Local<v8::Value> ex =
563625
v8::Exception::Error(ArgConverter::ConvertToV8String(isolate, "Evaluation failed"));
564626
resolver->Reject(context, ex).Check();
@@ -567,10 +629,14 @@ v8::MaybeLocal<v8::Promise> ImportModuleDynamicallyCallback(
567629
}
568630

569631
resolver->Resolve(context, module->GetModuleNamespace()).Check();
570-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Successfully resolved '%s'", spec.c_str());
632+
if (ShouldLogScriptLoading()) {
633+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Successfully resolved '%s'", spec.c_str());
634+
}
571635
} catch (NativeScriptException& ex) {
572636
ex.ReThrowToV8();
573-
DEBUG_WRITE("ImportModuleDynamicallyCallback: Native exception for '%s'", spec.c_str());
637+
if (ShouldLogScriptLoading()) {
638+
DEBUG_WRITE("ImportModuleDynamicallyCallback: Native exception for '%s'", spec.c_str());
639+
}
574640
resolver
575641
->Reject(context, v8::Exception::Error(
576642
ArgConverter::ConvertToV8String(isolate, "Native error during dynamic import")))

test-app/runtime/src/main/java/com/tns/AppConfig.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ protected enum KnownKeys {
2020
ForceLog("forceLog", false),
2121
DiscardUncaughtJsExceptions("discardUncaughtJsExceptions", false),
2222
EnableLineBreakpoins("enableLineBreakpoints", false),
23-
EnableMultithreadedJavascript("enableMultithreadedJavascript", false);
23+
EnableMultithreadedJavascript("enableMultithreadedJavascript", false),
24+
LogScriptLoading("logScriptLoading", false);
2425

2526
private final String name;
2627
private final Object defaultValue;
@@ -57,6 +58,9 @@ public AppConfig(File appDir) {
5758
String profiling = rootObject.getString(KnownKeys.Profiling.getName());
5859
values[KnownKeys.Profiling.ordinal()] = profiling;
5960
}
61+
if (rootObject.has(KnownKeys.LogScriptLoading.getName())) {
62+
values[KnownKeys.LogScriptLoading.ordinal()] = rootObject.getBoolean(KnownKeys.LogScriptLoading.getName());
63+
}
6064
if (rootObject.has(KnownKeys.DiscardUncaughtJsExceptions.getName())) {
6165
values[KnownKeys.DiscardUncaughtJsExceptions.ordinal()] = rootObject.getBoolean(KnownKeys.DiscardUncaughtJsExceptions.getName());
6266
}
@@ -171,4 +175,9 @@ public boolean getDiscardUncaughtJsExceptions() {
171175
public boolean getEnableMultithreadedJavascript() {
172176
return (boolean)values[KnownKeys.EnableMultithreadedJavascript.ordinal()];
173177
}
178+
179+
public boolean getLogScriptLoading() {
180+
Object v = values[KnownKeys.LogScriptLoading.ordinal()];
181+
return (v instanceof Boolean) ? ((Boolean)v).booleanValue() : false;
182+
}
174183
}

test-app/runtime/src/main/java/com/tns/Runtime.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ public Runtime(StaticConfiguration config, DynamicConfiguration dynamicConfigura
222222
runtimeCache.put(this.runtimeId, this);
223223

224224
gcListener = GcListener.getInstance(config.appConfig.getGcThrottleTime(), config.appConfig.getMemoryCheckInterval(), config.appConfig.getFreeMemoryRatio());
225+
// capture static configuration to allow native lookups when currentRuntime is unavailable
226+
Runtime.staticConfiguration = config;
225227
} finally {
226228
frame.close();
227229
}
@@ -254,6 +256,18 @@ public static boolean isDebuggable() {
254256
}
255257
}
256258

259+
// Expose logScriptLoading flag for native code without re-reading package.json
260+
public static boolean getLogScriptLoadingEnabled() {
261+
Runtime runtime = com.tns.Runtime.getCurrentRuntime();
262+
if (runtime != null && runtime.config != null && runtime.config.appConfig != null) {
263+
return runtime.config.appConfig.getLogScriptLoading();
264+
}
265+
if (staticConfiguration != null && staticConfiguration.appConfig != null) {
266+
return staticConfiguration.appConfig.getLogScriptLoading();
267+
}
268+
return false;
269+
}
270+
257271
private static Runtime getObjectRuntime(Object object) {
258272
Runtime runtime = null;
259273

0 commit comments

Comments
 (0)