Tags: NativeScript/android
Tags
fix: keep the query on relative and root-absolute imports from served… … modules (#2038) ResolveSpecifierToPath dropped `?query#fragment` from every non-http specifier before consulting the import map or the referrer. A module served over HTTP that imports `/ns/asm?path=%2Fsrc%2FHome.vue` therefore resolved to `http://host/ns/asm`, which the Vite dev server answers with 400 because the query is the module's identity. Any root-relative or relative `/ns/...` specifier carrying a query hit the same wall (`?path=`, `&mode=inline`, `?vue&type=`, `?ns_worker=1`), so every framework on the Vite dev flow was exposed; Vue merely hit it first. The seam now strips the query only once every HTTP outcome has returned, which is the iOS runtime's ordering: import-map lookup and HTTP-referrer resolution see the full specifier, and only filesystem probing sees the bare path. import() hands its specifier to the seam verbatim and routes on the resolved URL when the seam makes a relative or root-absolute spec HTTP, so those imports stay on the async graph walk instead of the blocking fallback.
fix: lock the remaining process-global state shared across isolates The caches #2020 named (Console timers, ArgConverter, MetadataNode / MetadataReader) were already covered by #2013: Console and ArgConverter moved to per-runtime RuntimeState, MetadataNode got s_nodeCacheMutex, MetadataReader its own StateMutex, and JEnv / MethodCache a shared_mutex each. Auditing the runtime for what actually remained in that class turned up four more. File::Buffer was a single process-wide 1MB scratch buffer that ReadText filled and returned a pointer into. Main and worker runtimes read modules concurrently from their own threads, so one thread's fread overwrote bytes another was still copying out - silent module-source corruption rather than a crash, which is why it never showed up in a tombstone. The buffer also never saved the allocation it appears to save: every caller goes through the std::string overload, which copies out of it on the next line. Reads now go straight into the returned string, and the borrowing overload, which had no callers, is gone. JType::EnsureInstance published *instance before Init had filled clazz, ctor and valueMethodId, so a second thread could find the pointer non-null and call through uninitialised JNI ids - on the hot boxing path. CallbackHandlers::Init runs once per runtime from PrepareV8Runtime, so every worker start rewrote the process-global class and method-id statics, and re-ran MethodCache::Init, while the isolates already running were reading them. MetadataNode::IsJavascriptKeyword filled a function-local static set behind an empty() check, racing reads from every runtime's thread. Also adds the missing ftell < 0 guard on the read path. Verified: arm64-v8a native build, full test suite 1038/1038.
PreviousNext