From d02c8e4f874563ad62fe0dd0fc2cf141fb4d1d36 Mon Sep 17 00:00:00 2001 From: Adrian Niculescu <15037449+adrian-niculescu@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:10:55 +0300 Subject: [PATCH 1/2] feat(runtime): add nullability annotations to NativeScript.h Without them every pointer in the embedder API imports into Swift as implicitly unwrapped, which hides the contract the implementation already has: BaseDir, the script string and the Config argument are required (their UTF8String feeds a std::string), while ApplicationPath, MetadataPtr and Arguments are optional with defaults (BaseDir/app, the __TNSMetadata section, no inspector arguments). initWithConfig: never returns nil. --- NativeScript/NativeScript.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/NativeScript/NativeScript.h b/NativeScript/NativeScript.h index f9bcc9f1..85b56f9e 100644 --- a/NativeScript/NativeScript.h +++ b/NativeScript/NativeScript.h @@ -1,14 +1,16 @@ #import +NS_ASSUME_NONNULL_BEGIN + @interface Config : NSObject @property (nonatomic, retain) NSString* BaseDir; -@property (nonatomic, retain) NSString* ApplicationPath; -@property (nonatomic) void* MetadataPtr; +@property (nonatomic, retain, nullable) NSString* ApplicationPath; +@property (nonatomic, nullable) void* MetadataPtr; @property BOOL IsDebug; @property BOOL LogToSystemConsole; @property int ArgumentsCount; -@property (nonatomic) char** Arguments; +@property (nonatomic) char* _Nullable* _Nullable Arguments; @end @@ -26,3 +28,5 @@ - (bool)liveSync; @end + +NS_ASSUME_NONNULL_END From 036fe4e0676cb4865245fc51cb517254f1e7b0ea Mon Sep 17 00:00:00 2001 From: Adrian Niculescu <15037449+adrian-niculescu@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:27:16 +0300 Subject: [PATCH 2/2] fix(runtime): read no inspector flags from a nil Arguments array Config.Arguments is optional, but ArgumentsCount was handed to the inspector as is, so a nil array with a count above one made debug startup index a null argv. Pass a count of 0 when the array is nil; the argv loop keeps the C contract and trusts the count it is given. --- NativeScript/NativeScript.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/NativeScript/NativeScript.mm b/NativeScript/NativeScript.mm index 0ac0e10e..4efc7223 100644 --- a/NativeScript/NativeScript.mm +++ b/NativeScript/NativeScript.mm @@ -184,7 +184,9 @@ - (instancetype)initializeWithConfig:(Config*)config { new v8_inspector::JsV8InspectorClient(runtime_.get()); inspectorClient->init(); inspectorClient->registerModules(); - inspectorClient->connect([config ArgumentsCount], [config Arguments]); + // A nil Arguments array carries no inspector flags, whatever ArgumentsCount says. + inspectorClient->connect(config.Arguments != nullptr ? config.ArgumentsCount : 0, + config.Arguments); Console::AttachInspectorClient(inspectorClient); } }