@nativescript/windows-v8 0.1.0-alpha.0 → 0.1.0-next.2026-08-03-30819078286
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -55
- package/framework/__PROJECT_NAME__/App.xaml +13 -13
- package/framework/__PROJECT_NAME__/Package.appxmanifest +35 -35
- package/framework/__PROJECT_NAME__/Program.cs +34 -34
- package/framework/__PROJECT_NAME__/Properties/Default.rd.xml +9 -9
- package/framework/dotnet-bridge/BinaryProtocol.cs +161 -161
- package/framework/dotnet-bridge/Bridge.JsDelegate.cs +244 -244
- package/framework/dotnet-bridge/Bridge.TaskHelper.cs +207 -207
- package/framework/dotnet-bridge/DispatchTypes.cs +333 -333
- package/framework/dotnet-bridge/DotNetBridge.csproj +30 -30
- package/framework/libs/x64/nativescript.dll +0 -0
- package/framework/tools/ManifestMerger/ManifestMerger.dll +0 -0
- package/framework/tools/ManifestMerger/ManifestMerger.pdb +0 -0
- package/framework/tools/dotnet-tool-arm64.exe +0 -0
- package/framework/tools/dotnet-tool-x64.exe +0 -0
- package/framework/tools/dotnet-tool.exe +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.dll +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.exe +0 -0
- package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.pdb +0 -0
- package/framework/tools/sbg-arm64.exe +0 -0
- package/framework/tools/sbg-x64.exe +0 -0
- package/framework/tools/sbg.exe +0 -0
- package/framework/tools/typings-generator-arm64.exe +0 -0
- package/framework/tools/typings-generator-x64.exe +0 -0
- package/framework/tools/typings-generator.exe +0 -0
- package/package.json +43 -43
package/README.md
CHANGED
|
@@ -1,55 +1,3 @@
|
|
|
1
|
-
# @nativescript/windows-v8
|
|
2
|
-
|
|
3
|
-
NativeScript Windows runtime on **V8**
|
|
4
|
-
|
|
5
|
-
## As an app runtime (drop-in for `@nativescript/windows`)
|
|
6
|
-
Publishes as `@nativescript/windows-v8`, the **same** WinUI 3 framework as `@nativescript/windows`
|
|
7
|
-
with a napi-backed V8 runtime DLL — swap the dependency and an app runs unchanged. Build the
|
|
8
|
-
framework with the engine flag:
|
|
9
|
-
```sh
|
|
10
|
-
pwsh -File ../../template/build.ps1 -Engine v8 # or: npm run build
|
|
11
|
-
```
|
|
12
|
-
The engine → runtime-DLL adapter (the C ABI the WinUI 3 host P/Invokes) follows the reference
|
|
13
|
-
implementation in `../windows-quickjs/src/abi.rs`. See `../README.md` for the full contract.
|
|
14
|
-
|
|
15
|
-
## Standalone host
|
|
16
|
-
Reuses napi-android's `v8-api.cpp` (napi over V8's C++ API), **ported to V8 14.7**, compiled against
|
|
17
|
-
the `v8` crate's bundled headers and linked against its prebuilt rusty_v8 (V8 14.7). The Android
|
|
18
|
-
bring-up (`jsr.cpp`) is replaced by `csrc/win_jsr.cpp`. Full WinRT demo passes (`exit 0`):
|
|
19
|
-
static-method resolution, typed WinRT calls, a 20-call stress loop, and a `JsonObject` round-trip.
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
cargo build --release --manifest-path packages/windows-v8/Cargo.toml
|
|
23
|
-
target/release/nativescript-windows.exe
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Why this was tractable (no ABI nightmare)
|
|
27
|
-
The `v8` crate's default config has **pointer compression and the sandbox OFF** (they're opt-in
|
|
28
|
-
cargo features we don't enable), so V8 uses plain/uncompressed pointers — there are **no ABI-matching
|
|
29
|
-
defines** and none of the corruption risk that config would bring. The port was therefore a bounded
|
|
30
|
-
API migration, not an ABI hunt.
|
|
31
|
-
|
|
32
|
-
## What the port involved (V8 13 → 14.7)
|
|
33
|
-
- Build recipe: C++20 + `/Zc:__cplusplus` (MSVC reports the real `__cplusplus`), locate the crate's
|
|
34
|
-
`v8/include`, stub `<android/log.h>`, `NAPI_EXTERN` → `__declspec(dllexport)`, define `__V8_13__`
|
|
35
|
-
(take the shim's modern `SetAccessorProperty` etc. paths). No pointer-compression/sandbox defines.
|
|
36
|
-
- API migrations: `String::Write/WriteUtf8/WriteOneByte` → `*V2` (+ `WriteFlags`); mandatory pointer
|
|
37
|
-
**type tags** on internal fields / `External` (safe defaults `kEmbedderDataTypeTagDefault` /
|
|
38
|
-
`kExternalPointerTypeTagDefault`); `Context::GetIsolate()` removed → `Isolate::GetCurrent()`;
|
|
39
|
-
interceptor setters return `v8::Intercepted` (`ReturnValue<void>`).
|
|
40
|
-
- Platform init done from **Rust** (`v8::new_default_platform` → `V8::initialize`) because
|
|
41
|
-
`NewDefaultPlatform`'s `std::unique_ptr<Platform>` return can't be linked from the MSVC-STL shim
|
|
42
|
-
(rusty_v8 uses V8's bundled libc++). See below.
|
|
43
|
-
|
|
44
|
-
## The libc++ boundary — solved, including zero-copy
|
|
45
|
-
rusty_v8 is built with V8's bundled libc++, so V8 API methods whose signatures involve
|
|
46
|
-
`std::shared_ptr`/`unique_ptr<BackingStore>` can't be linked directly from this MSVC-STL shim.
|
|
47
|
-
Handled without any copy:
|
|
48
|
-
- Reads use `ArrayBuffer::Data()` (the direct `void*` accessor — no `BackingStore`).
|
|
49
|
-
- `napi_create_external_arraybuffer` is **true zero-copy**: it goes through rusty_v8's own
|
|
50
|
-
`extern "C"` bindings (`v8__ArrayBuffer__NewBackingStore__with_data`, the unique→shared converter,
|
|
51
|
-
`v8__ArrayBuffer__New__with_backing_store`) which pass the backing store as raw pointers / an
|
|
52
|
-
opaque 16-byte `shared_ptr`, then bridges the returned pointer back to a `Local` (a `Local` is one
|
|
53
|
-
pointer). The buffer aliases the source memory; the napi finalizer runs from the BackingStore
|
|
54
|
-
deleter on GC. **Verified:** `interop.arrayBufferFromBuffer(CryptographicBuffer.GenerateRandom(8))`
|
|
55
|
-
→ `byteLength=8`, `instanceof ArrayBuffer`, no copy. So the IBuffer→ArrayBuffer perf path is intact.
|
|
1
|
+
# @nativescript/windows-v8
|
|
2
|
+
|
|
3
|
+
NativeScript Windows runtime on **V8**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
<Application
|
|
2
|
-
x:Class="__PROJECT_NAME__.App"
|
|
3
|
-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
4
|
-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
5
|
-
xmlns:local="using:__PROJECT_NAME__">
|
|
6
|
-
<Application.Resources>
|
|
7
|
-
<ResourceDictionary>
|
|
8
|
-
<ResourceDictionary.MergedDictionaries>
|
|
9
|
-
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
|
10
|
-
</ResourceDictionary.MergedDictionaries>
|
|
11
|
-
</ResourceDictionary>
|
|
12
|
-
</Application.Resources>
|
|
13
|
-
</Application>
|
|
1
|
+
<Application
|
|
2
|
+
x:Class="__PROJECT_NAME__.App"
|
|
3
|
+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
4
|
+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
5
|
+
xmlns:local="using:__PROJECT_NAME__">
|
|
6
|
+
<Application.Resources>
|
|
7
|
+
<ResourceDictionary>
|
|
8
|
+
<ResourceDictionary.MergedDictionaries>
|
|
9
|
+
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
|
10
|
+
</ResourceDictionary.MergedDictionaries>
|
|
11
|
+
</ResourceDictionary>
|
|
12
|
+
</Application.Resources>
|
|
13
|
+
</Application>
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
-
<Package
|
|
3
|
-
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
4
|
-
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
5
|
-
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
|
6
|
-
IgnorableNamespaces="uap rescap">
|
|
7
|
-
<Identity Name="__APP_IDENTIFIER__" Publisher="CN=__PROJECT_NAME__" Version="1.0.0.0" />
|
|
8
|
-
<Properties>
|
|
9
|
-
<DisplayName>__PROJECT_NAME__</DisplayName>
|
|
10
|
-
<PublisherDisplayName>__PROJECT_NAME__</PublisherDisplayName>
|
|
11
|
-
<Logo>Assets\StoreLogo.png</Logo>
|
|
12
|
-
</Properties>
|
|
13
|
-
<Dependencies>
|
|
14
|
-
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
|
|
15
|
-
<!-- WinUI3 / Windows App SDK 1.6 framework package (framework-dependent). Required so the
|
|
16
|
-
registered app can activate Microsoft.UI.Xaml.* (else REGDB_E_CLASSNOTREG at startup). -->
|
|
17
|
-
<PackageDependency Name="Microsoft.WindowsAppRuntime.1.6" MinVersion="6000.0.0.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
18
|
-
</Dependencies>
|
|
19
|
-
<Resources>
|
|
20
|
-
<Resource Language="en-US" />
|
|
21
|
-
</Resources>
|
|
22
|
-
<Applications>
|
|
23
|
-
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Windows.FullTrustApplication">
|
|
24
|
-
<uap:VisualElements DisplayName="__PROJECT_NAME__" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="A NativeScript Windows application" BackgroundColor="#65ADF1">
|
|
25
|
-
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
|
26
|
-
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
|
27
|
-
</uap:VisualElements>
|
|
28
|
-
</Application>
|
|
29
|
-
</Applications>
|
|
30
|
-
<Capabilities>
|
|
31
|
-
<rescap:Capability Name="runFullTrust" />
|
|
32
|
-
<Capability Name="internetClient" />
|
|
33
|
-
<Capability Name="privateNetworkClientServer" />
|
|
34
|
-
</Capabilities>
|
|
35
|
-
</Package>
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<Package
|
|
3
|
+
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
|
4
|
+
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
|
5
|
+
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
|
6
|
+
IgnorableNamespaces="uap rescap">
|
|
7
|
+
<Identity Name="__APP_IDENTIFIER__" Publisher="CN=__PROJECT_NAME__" Version="1.0.0.0" />
|
|
8
|
+
<Properties>
|
|
9
|
+
<DisplayName>__PROJECT_NAME__</DisplayName>
|
|
10
|
+
<PublisherDisplayName>__PROJECT_NAME__</PublisherDisplayName>
|
|
11
|
+
<Logo>Assets\StoreLogo.png</Logo>
|
|
12
|
+
</Properties>
|
|
13
|
+
<Dependencies>
|
|
14
|
+
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.26100.0" />
|
|
15
|
+
<!-- WinUI3 / Windows App SDK 1.6 framework package (framework-dependent). Required so the
|
|
16
|
+
registered app can activate Microsoft.UI.Xaml.* (else REGDB_E_CLASSNOTREG at startup). -->
|
|
17
|
+
<PackageDependency Name="Microsoft.WindowsAppRuntime.1.6" MinVersion="6000.0.0.0" Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" />
|
|
18
|
+
</Dependencies>
|
|
19
|
+
<Resources>
|
|
20
|
+
<Resource Language="en-US" />
|
|
21
|
+
</Resources>
|
|
22
|
+
<Applications>
|
|
23
|
+
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="Windows.FullTrustApplication">
|
|
24
|
+
<uap:VisualElements DisplayName="__PROJECT_NAME__" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="A NativeScript Windows application" BackgroundColor="#65ADF1">
|
|
25
|
+
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
|
|
26
|
+
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
|
27
|
+
</uap:VisualElements>
|
|
28
|
+
</Application>
|
|
29
|
+
</Applications>
|
|
30
|
+
<Capabilities>
|
|
31
|
+
<rescap:Capability Name="runFullTrust" />
|
|
32
|
+
<Capability Name="internetClient" />
|
|
33
|
+
<Capability Name="privateNetworkClientServer" />
|
|
34
|
+
</Capabilities>
|
|
35
|
+
</Package>
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Threading;
|
|
3
|
-
using Microsoft.UI.Dispatching;
|
|
4
|
-
using Microsoft.UI.Xaml;
|
|
5
|
-
using WinRT;
|
|
6
|
-
|
|
7
|
-
// Windows-only WinUI desktop app. The custom entry point (DISABLE_XAML_GENERATED_MAIN)
|
|
8
|
-
// has no platform attribute, so CA1416 treats every Windows API call site as "reachable
|
|
9
|
-
// on all platforms." Declaring the assembly's supported platform once tells the analyzer
|
|
10
|
-
// the whole assembly only runs on Windows >= 17763, silencing those false positives.
|
|
11
|
-
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.17763.0")]
|
|
12
|
-
|
|
13
|
-
namespace __PROJECT_NAME__
|
|
14
|
-
{
|
|
15
|
-
public static class Program
|
|
16
|
-
{
|
|
17
|
-
[System.STAThread]
|
|
18
|
-
public static void Main(string[] args)
|
|
19
|
-
{
|
|
20
|
-
ComWrappersSupport.InitializeComWrappers();
|
|
21
|
-
|
|
22
|
-
Application.Start((_callbackParams) =>
|
|
23
|
-
{
|
|
24
|
-
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
25
|
-
if (dispatcherQueue != null)
|
|
26
|
-
{
|
|
27
|
-
SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(dispatcherQueue));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
new App();
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Threading;
|
|
3
|
+
using Microsoft.UI.Dispatching;
|
|
4
|
+
using Microsoft.UI.Xaml;
|
|
5
|
+
using WinRT;
|
|
6
|
+
|
|
7
|
+
// Windows-only WinUI desktop app. The custom entry point (DISABLE_XAML_GENERATED_MAIN)
|
|
8
|
+
// has no platform attribute, so CA1416 treats every Windows API call site as "reachable
|
|
9
|
+
// on all platforms." Declaring the assembly's supported platform once tells the analyzer
|
|
10
|
+
// the whole assembly only runs on Windows >= 17763, silencing those false positives.
|
|
11
|
+
[assembly: System.Runtime.Versioning.SupportedOSPlatform("windows10.0.17763.0")]
|
|
12
|
+
|
|
13
|
+
namespace __PROJECT_NAME__
|
|
14
|
+
{
|
|
15
|
+
public static class Program
|
|
16
|
+
{
|
|
17
|
+
[System.STAThread]
|
|
18
|
+
public static void Main(string[] args)
|
|
19
|
+
{
|
|
20
|
+
ComWrappersSupport.InitializeComWrappers();
|
|
21
|
+
|
|
22
|
+
Application.Start((_callbackParams) =>
|
|
23
|
+
{
|
|
24
|
+
var dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
|
25
|
+
if (dispatcherQueue != null)
|
|
26
|
+
{
|
|
27
|
+
SynchronizationContext.SetSynchronizationContext(new DispatcherQueueSynchronizationContext(dispatcherQueue));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
new App();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
Runtime Directives for .NET Native.
|
|
3
|
-
See https://go.microsoft.com/fwlink/?LinkID=391919
|
|
4
|
-
-->
|
|
5
|
-
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
|
6
|
-
<Application>
|
|
7
|
-
<Assembly Name="*Application*" Dynamic="Required All" />
|
|
8
|
-
</Application>
|
|
9
|
-
</Directives>
|
|
1
|
+
<!--
|
|
2
|
+
Runtime Directives for .NET Native.
|
|
3
|
+
See https://go.microsoft.com/fwlink/?LinkID=391919
|
|
4
|
+
-->
|
|
5
|
+
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
|
6
|
+
<Application>
|
|
7
|
+
<Assembly Name="*Application*" Dynamic="Required All" />
|
|
8
|
+
</Application>
|
|
9
|
+
</Directives>
|
|
@@ -1,161 +1,161 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Buffers;
|
|
3
|
-
using System.Buffers.Binary;
|
|
4
|
-
using System.Text;
|
|
5
|
-
|
|
6
|
-
namespace NativeScriptBridge;
|
|
7
|
-
|
|
8
|
-
internal readonly struct HandleRef(int id)
|
|
9
|
-
{
|
|
10
|
-
public readonly int Id = id;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Carries a raw IUnknown/IInspectable pointer from a WinRT proxy (tag 0x0A).
|
|
14
|
-
// CoerceBin calls Marshal.GetObjectForIUnknown to create a managed RCW.
|
|
15
|
-
internal readonly struct WinRtRef(long ptr)
|
|
16
|
-
{
|
|
17
|
-
public readonly long Ptr = ptr;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
internal ref struct BinReader(ReadOnlySpan<byte> buf)
|
|
21
|
-
{
|
|
22
|
-
private readonly ReadOnlySpan<byte> _buf = buf;
|
|
23
|
-
private int _pos = 0;
|
|
24
|
-
|
|
25
|
-
public byte ReadByte() => _buf[_pos++];
|
|
26
|
-
|
|
27
|
-
public int ReadI32()
|
|
28
|
-
{
|
|
29
|
-
var v = BinaryPrimitives.ReadInt32LittleEndian(_buf[_pos..]);
|
|
30
|
-
_pos += 4;
|
|
31
|
-
return v;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
public long ReadI64()
|
|
35
|
-
{
|
|
36
|
-
var v = BinaryPrimitives.ReadInt64LittleEndian(_buf[_pos..]);
|
|
37
|
-
_pos += 8;
|
|
38
|
-
return v;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public ushort ReadU16()
|
|
42
|
-
{
|
|
43
|
-
var v = BinaryPrimitives.ReadUInt16LittleEndian(_buf[_pos..]);
|
|
44
|
-
_pos += 2;
|
|
45
|
-
return v;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public double ReadF64()
|
|
49
|
-
{
|
|
50
|
-
var v = BinaryPrimitives.ReadDoubleLittleEndian(_buf[_pos..]);
|
|
51
|
-
_pos += 8;
|
|
52
|
-
return v;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
public string ReadString16()
|
|
56
|
-
{
|
|
57
|
-
var len = ReadU16();
|
|
58
|
-
var s = Encoding.UTF8.GetString(_buf.Slice(_pos, len));
|
|
59
|
-
_pos += len;
|
|
60
|
-
// Intern so repeated method/type names reuse the same heap string.
|
|
61
|
-
// Eliminates the allocation on every subsequent warm-path call.
|
|
62
|
-
return string.Intern(s);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public string ReadString32()
|
|
66
|
-
{
|
|
67
|
-
var len = BinaryPrimitives.ReadUInt32LittleEndian(_buf.Slice(_pos, 4));
|
|
68
|
-
_pos += 4;
|
|
69
|
-
var s = Encoding.UTF8.GetString(_buf.Slice(_pos, (int)len));
|
|
70
|
-
_pos += (int)len;
|
|
71
|
-
return string.Intern(s);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public uint ReadU32()
|
|
75
|
-
{
|
|
76
|
-
var v = BinaryPrimitives.ReadUInt32LittleEndian(_buf.Slice(_pos, 4));
|
|
77
|
-
_pos += 4;
|
|
78
|
-
return v;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
public object?[] ReadArgs()
|
|
82
|
-
{
|
|
83
|
-
var count = ReadByte();
|
|
84
|
-
if (count == 0) return [];
|
|
85
|
-
var args = new object?[count];
|
|
86
|
-
for (int i = 0; i < count; i++)
|
|
87
|
-
{
|
|
88
|
-
var tag = ReadByte();
|
|
89
|
-
args[i] = tag switch
|
|
90
|
-
{
|
|
91
|
-
0x00 => null,
|
|
92
|
-
0x01 => (object)false,
|
|
93
|
-
0x02 => (object)true,
|
|
94
|
-
0x03 => (object)ReadI32(),
|
|
95
|
-
0x04 => (object)ReadF64(),
|
|
96
|
-
0x05 => (object)ReadString16(),
|
|
97
|
-
0x06 => (object)new HandleRef(ReadI32()),
|
|
98
|
-
0x0A => (object)new WinRtRef(ReadI64()),
|
|
99
|
-
_ => null,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
return args;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
internal ref struct BinWriter(ArrayBufferWriter<byte> buf)
|
|
107
|
-
{
|
|
108
|
-
private readonly ArrayBufferWriter<byte> _buf = buf;
|
|
109
|
-
|
|
110
|
-
public void WriteByte(byte b)
|
|
111
|
-
{
|
|
112
|
-
_buf.GetSpan(1)[0] = b;
|
|
113
|
-
_buf.Advance(1);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
public void WriteI32(int v)
|
|
117
|
-
{
|
|
118
|
-
BinaryPrimitives.WriteInt32LittleEndian(_buf.GetSpan(4), v);
|
|
119
|
-
_buf.Advance(4);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
public void WriteU16(ushort v)
|
|
123
|
-
{
|
|
124
|
-
BinaryPrimitives.WriteUInt16LittleEndian(_buf.GetSpan(2), v);
|
|
125
|
-
_buf.Advance(2);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
public void WriteU32(uint v)
|
|
129
|
-
{
|
|
130
|
-
BinaryPrimitives.WriteUInt32LittleEndian(_buf.GetSpan(4), v);
|
|
131
|
-
_buf.Advance(4);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
public void WriteI64(long v)
|
|
135
|
-
{
|
|
136
|
-
BinaryPrimitives.WriteInt64LittleEndian(_buf.GetSpan(8), v);
|
|
137
|
-
_buf.Advance(8);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
public void WriteF64(double v)
|
|
141
|
-
{
|
|
142
|
-
BinaryPrimitives.WriteDoubleLittleEndian(_buf.GetSpan(8), v);
|
|
143
|
-
_buf.Advance(8);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
public void WriteString32(ReadOnlySpan<char> s)
|
|
147
|
-
{
|
|
148
|
-
var byteCount = Encoding.UTF8.GetByteCount(s);
|
|
149
|
-
WriteU32((uint)byteCount);
|
|
150
|
-
Encoding.UTF8.GetBytes(s, _buf.GetSpan(byteCount));
|
|
151
|
-
_buf.Advance(byteCount);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
public void WriteString16(ReadOnlySpan<char> s)
|
|
155
|
-
{
|
|
156
|
-
var byteCount = Encoding.UTF8.GetByteCount(s);
|
|
157
|
-
WriteU16((ushort)byteCount);
|
|
158
|
-
Encoding.UTF8.GetBytes(s, _buf.GetSpan(byteCount));
|
|
159
|
-
_buf.Advance(byteCount);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Buffers;
|
|
3
|
+
using System.Buffers.Binary;
|
|
4
|
+
using System.Text;
|
|
5
|
+
|
|
6
|
+
namespace NativeScriptBridge;
|
|
7
|
+
|
|
8
|
+
internal readonly struct HandleRef(int id)
|
|
9
|
+
{
|
|
10
|
+
public readonly int Id = id;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Carries a raw IUnknown/IInspectable pointer from a WinRT proxy (tag 0x0A).
|
|
14
|
+
// CoerceBin calls Marshal.GetObjectForIUnknown to create a managed RCW.
|
|
15
|
+
internal readonly struct WinRtRef(long ptr)
|
|
16
|
+
{
|
|
17
|
+
public readonly long Ptr = ptr;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
internal ref struct BinReader(ReadOnlySpan<byte> buf)
|
|
21
|
+
{
|
|
22
|
+
private readonly ReadOnlySpan<byte> _buf = buf;
|
|
23
|
+
private int _pos = 0;
|
|
24
|
+
|
|
25
|
+
public byte ReadByte() => _buf[_pos++];
|
|
26
|
+
|
|
27
|
+
public int ReadI32()
|
|
28
|
+
{
|
|
29
|
+
var v = BinaryPrimitives.ReadInt32LittleEndian(_buf[_pos..]);
|
|
30
|
+
_pos += 4;
|
|
31
|
+
return v;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public long ReadI64()
|
|
35
|
+
{
|
|
36
|
+
var v = BinaryPrimitives.ReadInt64LittleEndian(_buf[_pos..]);
|
|
37
|
+
_pos += 8;
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public ushort ReadU16()
|
|
42
|
+
{
|
|
43
|
+
var v = BinaryPrimitives.ReadUInt16LittleEndian(_buf[_pos..]);
|
|
44
|
+
_pos += 2;
|
|
45
|
+
return v;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public double ReadF64()
|
|
49
|
+
{
|
|
50
|
+
var v = BinaryPrimitives.ReadDoubleLittleEndian(_buf[_pos..]);
|
|
51
|
+
_pos += 8;
|
|
52
|
+
return v;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public string ReadString16()
|
|
56
|
+
{
|
|
57
|
+
var len = ReadU16();
|
|
58
|
+
var s = Encoding.UTF8.GetString(_buf.Slice(_pos, len));
|
|
59
|
+
_pos += len;
|
|
60
|
+
// Intern so repeated method/type names reuse the same heap string.
|
|
61
|
+
// Eliminates the allocation on every subsequent warm-path call.
|
|
62
|
+
return string.Intern(s);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public string ReadString32()
|
|
66
|
+
{
|
|
67
|
+
var len = BinaryPrimitives.ReadUInt32LittleEndian(_buf.Slice(_pos, 4));
|
|
68
|
+
_pos += 4;
|
|
69
|
+
var s = Encoding.UTF8.GetString(_buf.Slice(_pos, (int)len));
|
|
70
|
+
_pos += (int)len;
|
|
71
|
+
return string.Intern(s);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public uint ReadU32()
|
|
75
|
+
{
|
|
76
|
+
var v = BinaryPrimitives.ReadUInt32LittleEndian(_buf.Slice(_pos, 4));
|
|
77
|
+
_pos += 4;
|
|
78
|
+
return v;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public object?[] ReadArgs()
|
|
82
|
+
{
|
|
83
|
+
var count = ReadByte();
|
|
84
|
+
if (count == 0) return [];
|
|
85
|
+
var args = new object?[count];
|
|
86
|
+
for (int i = 0; i < count; i++)
|
|
87
|
+
{
|
|
88
|
+
var tag = ReadByte();
|
|
89
|
+
args[i] = tag switch
|
|
90
|
+
{
|
|
91
|
+
0x00 => null,
|
|
92
|
+
0x01 => (object)false,
|
|
93
|
+
0x02 => (object)true,
|
|
94
|
+
0x03 => (object)ReadI32(),
|
|
95
|
+
0x04 => (object)ReadF64(),
|
|
96
|
+
0x05 => (object)ReadString16(),
|
|
97
|
+
0x06 => (object)new HandleRef(ReadI32()),
|
|
98
|
+
0x0A => (object)new WinRtRef(ReadI64()),
|
|
99
|
+
_ => null,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return args;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
internal ref struct BinWriter(ArrayBufferWriter<byte> buf)
|
|
107
|
+
{
|
|
108
|
+
private readonly ArrayBufferWriter<byte> _buf = buf;
|
|
109
|
+
|
|
110
|
+
public void WriteByte(byte b)
|
|
111
|
+
{
|
|
112
|
+
_buf.GetSpan(1)[0] = b;
|
|
113
|
+
_buf.Advance(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public void WriteI32(int v)
|
|
117
|
+
{
|
|
118
|
+
BinaryPrimitives.WriteInt32LittleEndian(_buf.GetSpan(4), v);
|
|
119
|
+
_buf.Advance(4);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public void WriteU16(ushort v)
|
|
123
|
+
{
|
|
124
|
+
BinaryPrimitives.WriteUInt16LittleEndian(_buf.GetSpan(2), v);
|
|
125
|
+
_buf.Advance(2);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public void WriteU32(uint v)
|
|
129
|
+
{
|
|
130
|
+
BinaryPrimitives.WriteUInt32LittleEndian(_buf.GetSpan(4), v);
|
|
131
|
+
_buf.Advance(4);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public void WriteI64(long v)
|
|
135
|
+
{
|
|
136
|
+
BinaryPrimitives.WriteInt64LittleEndian(_buf.GetSpan(8), v);
|
|
137
|
+
_buf.Advance(8);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public void WriteF64(double v)
|
|
141
|
+
{
|
|
142
|
+
BinaryPrimitives.WriteDoubleLittleEndian(_buf.GetSpan(8), v);
|
|
143
|
+
_buf.Advance(8);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public void WriteString32(ReadOnlySpan<char> s)
|
|
147
|
+
{
|
|
148
|
+
var byteCount = Encoding.UTF8.GetByteCount(s);
|
|
149
|
+
WriteU32((uint)byteCount);
|
|
150
|
+
Encoding.UTF8.GetBytes(s, _buf.GetSpan(byteCount));
|
|
151
|
+
_buf.Advance(byteCount);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public void WriteString16(ReadOnlySpan<char> s)
|
|
155
|
+
{
|
|
156
|
+
var byteCount = Encoding.UTF8.GetByteCount(s);
|
|
157
|
+
WriteU16((ushort)byteCount);
|
|
158
|
+
Encoding.UTF8.GetBytes(s, _buf.GetSpan(byteCount));
|
|
159
|
+
_buf.Advance(byteCount);
|
|
160
|
+
}
|
|
161
|
+
}
|