@nativescript/windows-v8 0.1.0-alpha.0 → 0.1.0-alpha.138
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/__PROJECT_NAME__/RuntimeHost.cs +54 -11
- package/framework/__PROJECT_NAME__/__PROJECT_NAME__.csproj +6 -1
- 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/nsbundle_pack-x64.exe +0 -0
- package/framework/tools/nsbundle_pack.exe +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
|
@@ -1,244 +1,244 @@
|
|
|
1
|
-
using System;
|
|
2
|
-
using System.Buffers;
|
|
3
|
-
using System.Linq;
|
|
4
|
-
using System.Linq.Expressions;
|
|
5
|
-
using System.Reflection;
|
|
6
|
-
using System.Reflection.Emit;
|
|
7
|
-
using System.Runtime.InteropServices;
|
|
8
|
-
using System.Threading;
|
|
9
|
-
|
|
10
|
-
namespace NativeScriptBridge;
|
|
11
|
-
|
|
12
|
-
public static partial class Bridge
|
|
13
|
-
{
|
|
14
|
-
// opcode 0x09: given a delegate type name (or "" for System.Action) and a
|
|
15
|
-
// JS callback id, compile a .NET delegate that serialises its parameters as
|
|
16
|
-
// binary and calls back into V8 via the s_jsInvoker function pointer.
|
|
17
|
-
|
|
18
|
-
private static DispatchResult CreateJsDelegate(string typeName, int callbackId)
|
|
19
|
-
{
|
|
20
|
-
var delegateType = string.IsNullOrEmpty(typeName)
|
|
21
|
-
? typeof(Action)
|
|
22
|
-
: ResolveType(null, typeName)
|
|
23
|
-
?? throw new TypeLoadException($"Delegate type not found: {typeName}");
|
|
24
|
-
|
|
25
|
-
var invokeMethod = delegateType.GetMethod("Invoke")
|
|
26
|
-
?? throw new MissingMethodException($"No Invoke method on {delegateType}");
|
|
27
|
-
|
|
28
|
-
var parameters = invokeMethod.GetParameters();
|
|
29
|
-
var returnType = invokeMethod.ReturnType;
|
|
30
|
-
|
|
31
|
-
// Build a dynamic method that marshals parameters into an object[] and
|
|
32
|
-
// calls back into JS via CallJsCallback/CallJsCallbackVoid. Expression
|
|
33
|
-
// compilation occasionally generates incorrect code for some delegate
|
|
34
|
-
// shapes; emitting IL here is reliable across signatures.
|
|
35
|
-
var paramTypes = parameters.Select(p => p.ParameterType).ToArray();
|
|
36
|
-
|
|
37
|
-
var dm = new DynamicMethod($"__ns_js_delegate_{callbackId}",
|
|
38
|
-
returnType, paramTypes, typeof(Bridge).Module, skipVisibility: true);
|
|
39
|
-
|
|
40
|
-
var il = dm.GetILGenerator();
|
|
41
|
-
// local: object[] argsArray
|
|
42
|
-
var argsLocal = il.DeclareLocal(typeof(object[]));
|
|
43
|
-
il.Emit(OpCodes.Ldc_I4, paramTypes.Length);
|
|
44
|
-
il.Emit(OpCodes.Newarr, typeof(object));
|
|
45
|
-
il.Emit(OpCodes.Stloc, argsLocal);
|
|
46
|
-
|
|
47
|
-
for (int i = 0; i < paramTypes.Length; i++)
|
|
48
|
-
{
|
|
49
|
-
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
50
|
-
il.Emit(OpCodes.Ldc_I4, i);
|
|
51
|
-
// load argument (Ldarg_0..)
|
|
52
|
-
switch (i + 1)
|
|
53
|
-
{
|
|
54
|
-
case 1: il.Emit(OpCodes.Ldarg_0); break;
|
|
55
|
-
case 2: il.Emit(OpCodes.Ldarg_1); break;
|
|
56
|
-
case 3: il.Emit(OpCodes.Ldarg_2); break;
|
|
57
|
-
case 4: il.Emit(OpCodes.Ldarg_3); break;
|
|
58
|
-
default: il.Emit(OpCodes.Ldarg, i + 1); break;
|
|
59
|
-
}
|
|
60
|
-
if (paramTypes[i].IsValueType) il.Emit(OpCodes.Box, paramTypes[i]);
|
|
61
|
-
il.Emit(OpCodes.Stelem_Ref);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (returnType == typeof(void))
|
|
67
|
-
{
|
|
68
|
-
var callVoid = typeof(Bridge).GetMethod(nameof(CallJsCallbackVoid), BindingFlags.Static | BindingFlags.NonPublic)!;
|
|
69
|
-
il.Emit(OpCodes.Ldc_I4, callbackId);
|
|
70
|
-
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
71
|
-
il.Emit(OpCodes.Call, callVoid);
|
|
72
|
-
il.Emit(OpCodes.Ret);
|
|
73
|
-
}
|
|
74
|
-
else
|
|
75
|
-
{
|
|
76
|
-
var callObj = typeof(Bridge).GetMethod(nameof(CallJsCallback), BindingFlags.Static | BindingFlags.NonPublic)!;
|
|
77
|
-
il.Emit(OpCodes.Ldc_I4, callbackId);
|
|
78
|
-
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
79
|
-
il.Emit(OpCodes.Call, callObj);
|
|
80
|
-
// ignore returned object and return default(returnType)
|
|
81
|
-
if (returnType.IsValueType)
|
|
82
|
-
{
|
|
83
|
-
var loc = il.DeclareLocal(returnType);
|
|
84
|
-
il.Emit(OpCodes.Ldloca_S, loc);
|
|
85
|
-
il.Emit(OpCodes.Initobj, returnType);
|
|
86
|
-
il.Emit(OpCodes.Ldloc, loc);
|
|
87
|
-
}
|
|
88
|
-
else
|
|
89
|
-
{
|
|
90
|
-
il.Emit(OpCodes.Ldnull);
|
|
91
|
-
}
|
|
92
|
-
il.Emit(OpCodes.Ret);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
var del = dm.CreateDelegate(delegateType);
|
|
96
|
-
return Box(del);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
internal static unsafe object? CallJsCallback(int id, object?[] args)
|
|
100
|
-
{
|
|
101
|
-
if (s_jsInvoker == null) return null;
|
|
102
|
-
|
|
103
|
-
var buf = new ArrayBufferWriter<byte>(64);
|
|
104
|
-
var w = new BinWriter(buf);
|
|
105
|
-
w.WriteByte((byte)Math.Min(args.Length, 255));
|
|
106
|
-
foreach (var arg in args)
|
|
107
|
-
WriteCallbackArg(ref w, arg);
|
|
108
|
-
|
|
109
|
-
var bytes = buf.WrittenSpan;
|
|
110
|
-
byte* respPtr = null;
|
|
111
|
-
int respLen = 0;
|
|
112
|
-
fixed (byte* p = bytes)
|
|
113
|
-
s_jsInvoker(id, p, bytes.Length, &respPtr, &respLen);
|
|
114
|
-
|
|
115
|
-
object? result = null;
|
|
116
|
-
// Response is only set for non-void delegates; parse and free when present.
|
|
117
|
-
if (respPtr != null && respLen > 0)
|
|
118
|
-
{
|
|
119
|
-
try
|
|
120
|
-
{
|
|
121
|
-
var span = new ReadOnlySpan<byte>(respPtr, respLen);
|
|
122
|
-
result = ParseCallbackResponse(span);
|
|
123
|
-
}
|
|
124
|
-
catch { result = null; }
|
|
125
|
-
finally
|
|
126
|
-
{
|
|
127
|
-
Marshal.FreeHGlobal((IntPtr)respPtr);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return result;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Serialises a single delegate argument in response-binary tag format so
|
|
135
|
-
// the Rust side can reuse its existing bin_read_value parser.
|
|
136
|
-
private static void WriteCallbackArg(ref BinWriter w, object? arg)
|
|
137
|
-
{
|
|
138
|
-
// Allow existing handle references to be forwarded without re-boxing.
|
|
139
|
-
if (arg is HandleRef hr)
|
|
140
|
-
{
|
|
141
|
-
w.WriteByte(0x06);
|
|
142
|
-
w.WriteI32(hr.Id);
|
|
143
|
-
try
|
|
144
|
-
{
|
|
145
|
-
if (s_handles.TryGetValue(hr.Id, out var obj) && obj != null)
|
|
146
|
-
{
|
|
147
|
-
var objTypeName = obj.GetType().FullName ?? obj.GetType().Name;
|
|
148
|
-
w.WriteString16(objTypeName);
|
|
149
|
-
}
|
|
150
|
-
else
|
|
151
|
-
{
|
|
152
|
-
w.WriteString16("");
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
catch
|
|
156
|
-
{
|
|
157
|
-
w.WriteString16("");
|
|
158
|
-
}
|
|
159
|
-
if (Bridge.s_nativePtrs.TryGetValue(hr.Id, out var nativePtr))
|
|
160
|
-
{
|
|
161
|
-
w.WriteByte(1);
|
|
162
|
-
w.WriteI64(nativePtr.ToInt64());
|
|
163
|
-
}
|
|
164
|
-
else
|
|
165
|
-
{
|
|
166
|
-
w.WriteByte(0);
|
|
167
|
-
}
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (arg is null) { w.WriteByte(0x00); return; }
|
|
172
|
-
if (arg is bool b) { w.WriteByte(b ? (byte)0x02 : (byte)0x01); return; }
|
|
173
|
-
if (arg is int i) { w.WriteByte(0x03); w.WriteI32(i); return; }
|
|
174
|
-
if (arg is uint u) { w.WriteByte(0x03); w.WriteI32((int)u); return; }
|
|
175
|
-
if (arg is long l) { w.WriteByte(0x04); w.WriteF64((double)l); return; }
|
|
176
|
-
if (arg is float f) { w.WriteByte(0x04); w.WriteF64((double)f); return; }
|
|
177
|
-
if (arg is double d){ w.WriteByte(0x04); w.WriteF64(d); return; }
|
|
178
|
-
if (arg is string s){ w.WriteByte(0x05); w.WriteString32(s); return; }
|
|
179
|
-
|
|
180
|
-
// Object: box in the handle map and send as a handle reference.
|
|
181
|
-
// The JS side receives {__handle, __type} which can be turned into a
|
|
182
|
-
// proxy via NSWinRT.dotnet.fromHandle(...).
|
|
183
|
-
var handleId = Interlocked.Increment(ref s_nextHandle);
|
|
184
|
-
s_handles[handleId] = arg;
|
|
185
|
-
var typeName = arg.GetType().FullName ?? arg.GetType().Name;
|
|
186
|
-
w.WriteByte(0x06);
|
|
187
|
-
w.WriteI32(handleId);
|
|
188
|
-
w.WriteString16(typeName);
|
|
189
|
-
if (Bridge.s_nativePtrs.TryGetValue(handleId, out var nativePtr2)) {
|
|
190
|
-
w.WriteByte(1);
|
|
191
|
-
w.WriteI64(nativePtr2.ToInt64());
|
|
192
|
-
} else {
|
|
193
|
-
w.WriteByte(0);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private static object? ParseCallbackResponse(ReadOnlySpan<byte> span)
|
|
198
|
-
{
|
|
199
|
-
if (span.IsEmpty) return null;
|
|
200
|
-
var r = new BinReader(span);
|
|
201
|
-
var tag = r.ReadByte();
|
|
202
|
-
switch (tag)
|
|
203
|
-
{
|
|
204
|
-
case 0x00: return null;
|
|
205
|
-
case 0x01: return (object)false;
|
|
206
|
-
case 0x02: return (object)true;
|
|
207
|
-
case 0x03: return (object)r.ReadI32();
|
|
208
|
-
case 0x04: return (object)r.ReadF64();
|
|
209
|
-
case 0x05: return (object)r.ReadString32();
|
|
210
|
-
case 0x06: return (object)new HandleRef(r.ReadI32());
|
|
211
|
-
case 0x0A: return (object)new WinRtRef(r.ReadI64());
|
|
212
|
-
case 0x07: // array: u32 count + N tagged items
|
|
213
|
-
{
|
|
214
|
-
var count = (int)r.ReadU32();
|
|
215
|
-
var arr = new object?[count];
|
|
216
|
-
for (int i = 0; i < count; i++)
|
|
217
|
-
{
|
|
218
|
-
var t = r.ReadByte();
|
|
219
|
-
switch (t)
|
|
220
|
-
{
|
|
221
|
-
case 0x00: arr[i] = null; break;
|
|
222
|
-
case 0x01: arr[i] = false; break;
|
|
223
|
-
case 0x02: arr[i] = true; break;
|
|
224
|
-
case 0x03: arr[i] = r.ReadI32(); break;
|
|
225
|
-
case 0x04: arr[i] = r.ReadF64(); break;
|
|
226
|
-
case 0x05: arr[i] = r.ReadString32(); break;
|
|
227
|
-
case 0x06: arr[i] = new HandleRef(r.ReadI32()); break;
|
|
228
|
-
case 0x0A: arr[i] = new WinRtRef(r.ReadI64()); break;
|
|
229
|
-
default: arr[i] = null; break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return arr;
|
|
233
|
-
}
|
|
234
|
-
default: return null;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
internal static unsafe void CallJsCallbackVoid(int id, object?[] args)
|
|
239
|
-
{
|
|
240
|
-
CallJsCallback(id, args);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
}
|
|
1
|
+
using System;
|
|
2
|
+
using System.Buffers;
|
|
3
|
+
using System.Linq;
|
|
4
|
+
using System.Linq.Expressions;
|
|
5
|
+
using System.Reflection;
|
|
6
|
+
using System.Reflection.Emit;
|
|
7
|
+
using System.Runtime.InteropServices;
|
|
8
|
+
using System.Threading;
|
|
9
|
+
|
|
10
|
+
namespace NativeScriptBridge;
|
|
11
|
+
|
|
12
|
+
public static partial class Bridge
|
|
13
|
+
{
|
|
14
|
+
// opcode 0x09: given a delegate type name (or "" for System.Action) and a
|
|
15
|
+
// JS callback id, compile a .NET delegate that serialises its parameters as
|
|
16
|
+
// binary and calls back into V8 via the s_jsInvoker function pointer.
|
|
17
|
+
|
|
18
|
+
private static DispatchResult CreateJsDelegate(string typeName, int callbackId)
|
|
19
|
+
{
|
|
20
|
+
var delegateType = string.IsNullOrEmpty(typeName)
|
|
21
|
+
? typeof(Action)
|
|
22
|
+
: ResolveType(null, typeName)
|
|
23
|
+
?? throw new TypeLoadException($"Delegate type not found: {typeName}");
|
|
24
|
+
|
|
25
|
+
var invokeMethod = delegateType.GetMethod("Invoke")
|
|
26
|
+
?? throw new MissingMethodException($"No Invoke method on {delegateType}");
|
|
27
|
+
|
|
28
|
+
var parameters = invokeMethod.GetParameters();
|
|
29
|
+
var returnType = invokeMethod.ReturnType;
|
|
30
|
+
|
|
31
|
+
// Build a dynamic method that marshals parameters into an object[] and
|
|
32
|
+
// calls back into JS via CallJsCallback/CallJsCallbackVoid. Expression
|
|
33
|
+
// compilation occasionally generates incorrect code for some delegate
|
|
34
|
+
// shapes; emitting IL here is reliable across signatures.
|
|
35
|
+
var paramTypes = parameters.Select(p => p.ParameterType).ToArray();
|
|
36
|
+
|
|
37
|
+
var dm = new DynamicMethod($"__ns_js_delegate_{callbackId}",
|
|
38
|
+
returnType, paramTypes, typeof(Bridge).Module, skipVisibility: true);
|
|
39
|
+
|
|
40
|
+
var il = dm.GetILGenerator();
|
|
41
|
+
// local: object[] argsArray
|
|
42
|
+
var argsLocal = il.DeclareLocal(typeof(object[]));
|
|
43
|
+
il.Emit(OpCodes.Ldc_I4, paramTypes.Length);
|
|
44
|
+
il.Emit(OpCodes.Newarr, typeof(object));
|
|
45
|
+
il.Emit(OpCodes.Stloc, argsLocal);
|
|
46
|
+
|
|
47
|
+
for (int i = 0; i < paramTypes.Length; i++)
|
|
48
|
+
{
|
|
49
|
+
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
50
|
+
il.Emit(OpCodes.Ldc_I4, i);
|
|
51
|
+
// load argument (Ldarg_0..)
|
|
52
|
+
switch (i + 1)
|
|
53
|
+
{
|
|
54
|
+
case 1: il.Emit(OpCodes.Ldarg_0); break;
|
|
55
|
+
case 2: il.Emit(OpCodes.Ldarg_1); break;
|
|
56
|
+
case 3: il.Emit(OpCodes.Ldarg_2); break;
|
|
57
|
+
case 4: il.Emit(OpCodes.Ldarg_3); break;
|
|
58
|
+
default: il.Emit(OpCodes.Ldarg, i + 1); break;
|
|
59
|
+
}
|
|
60
|
+
if (paramTypes[i].IsValueType) il.Emit(OpCodes.Box, paramTypes[i]);
|
|
61
|
+
il.Emit(OpCodes.Stelem_Ref);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if (returnType == typeof(void))
|
|
67
|
+
{
|
|
68
|
+
var callVoid = typeof(Bridge).GetMethod(nameof(CallJsCallbackVoid), BindingFlags.Static | BindingFlags.NonPublic)!;
|
|
69
|
+
il.Emit(OpCodes.Ldc_I4, callbackId);
|
|
70
|
+
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
71
|
+
il.Emit(OpCodes.Call, callVoid);
|
|
72
|
+
il.Emit(OpCodes.Ret);
|
|
73
|
+
}
|
|
74
|
+
else
|
|
75
|
+
{
|
|
76
|
+
var callObj = typeof(Bridge).GetMethod(nameof(CallJsCallback), BindingFlags.Static | BindingFlags.NonPublic)!;
|
|
77
|
+
il.Emit(OpCodes.Ldc_I4, callbackId);
|
|
78
|
+
il.Emit(OpCodes.Ldloc, argsLocal);
|
|
79
|
+
il.Emit(OpCodes.Call, callObj);
|
|
80
|
+
// ignore returned object and return default(returnType)
|
|
81
|
+
if (returnType.IsValueType)
|
|
82
|
+
{
|
|
83
|
+
var loc = il.DeclareLocal(returnType);
|
|
84
|
+
il.Emit(OpCodes.Ldloca_S, loc);
|
|
85
|
+
il.Emit(OpCodes.Initobj, returnType);
|
|
86
|
+
il.Emit(OpCodes.Ldloc, loc);
|
|
87
|
+
}
|
|
88
|
+
else
|
|
89
|
+
{
|
|
90
|
+
il.Emit(OpCodes.Ldnull);
|
|
91
|
+
}
|
|
92
|
+
il.Emit(OpCodes.Ret);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
var del = dm.CreateDelegate(delegateType);
|
|
96
|
+
return Box(del);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
internal static unsafe object? CallJsCallback(int id, object?[] args)
|
|
100
|
+
{
|
|
101
|
+
if (s_jsInvoker == null) return null;
|
|
102
|
+
|
|
103
|
+
var buf = new ArrayBufferWriter<byte>(64);
|
|
104
|
+
var w = new BinWriter(buf);
|
|
105
|
+
w.WriteByte((byte)Math.Min(args.Length, 255));
|
|
106
|
+
foreach (var arg in args)
|
|
107
|
+
WriteCallbackArg(ref w, arg);
|
|
108
|
+
|
|
109
|
+
var bytes = buf.WrittenSpan;
|
|
110
|
+
byte* respPtr = null;
|
|
111
|
+
int respLen = 0;
|
|
112
|
+
fixed (byte* p = bytes)
|
|
113
|
+
s_jsInvoker(id, p, bytes.Length, &respPtr, &respLen);
|
|
114
|
+
|
|
115
|
+
object? result = null;
|
|
116
|
+
// Response is only set for non-void delegates; parse and free when present.
|
|
117
|
+
if (respPtr != null && respLen > 0)
|
|
118
|
+
{
|
|
119
|
+
try
|
|
120
|
+
{
|
|
121
|
+
var span = new ReadOnlySpan<byte>(respPtr, respLen);
|
|
122
|
+
result = ParseCallbackResponse(span);
|
|
123
|
+
}
|
|
124
|
+
catch { result = null; }
|
|
125
|
+
finally
|
|
126
|
+
{
|
|
127
|
+
Marshal.FreeHGlobal((IntPtr)respPtr);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Serialises a single delegate argument in response-binary tag format so
|
|
135
|
+
// the Rust side can reuse its existing bin_read_value parser.
|
|
136
|
+
private static void WriteCallbackArg(ref BinWriter w, object? arg)
|
|
137
|
+
{
|
|
138
|
+
// Allow existing handle references to be forwarded without re-boxing.
|
|
139
|
+
if (arg is HandleRef hr)
|
|
140
|
+
{
|
|
141
|
+
w.WriteByte(0x06);
|
|
142
|
+
w.WriteI32(hr.Id);
|
|
143
|
+
try
|
|
144
|
+
{
|
|
145
|
+
if (s_handles.TryGetValue(hr.Id, out var obj) && obj != null)
|
|
146
|
+
{
|
|
147
|
+
var objTypeName = obj.GetType().FullName ?? obj.GetType().Name;
|
|
148
|
+
w.WriteString16(objTypeName);
|
|
149
|
+
}
|
|
150
|
+
else
|
|
151
|
+
{
|
|
152
|
+
w.WriteString16("");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch
|
|
156
|
+
{
|
|
157
|
+
w.WriteString16("");
|
|
158
|
+
}
|
|
159
|
+
if (Bridge.s_nativePtrs.TryGetValue(hr.Id, out var nativePtr))
|
|
160
|
+
{
|
|
161
|
+
w.WriteByte(1);
|
|
162
|
+
w.WriteI64(nativePtr.ToInt64());
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
{
|
|
166
|
+
w.WriteByte(0);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (arg is null) { w.WriteByte(0x00); return; }
|
|
172
|
+
if (arg is bool b) { w.WriteByte(b ? (byte)0x02 : (byte)0x01); return; }
|
|
173
|
+
if (arg is int i) { w.WriteByte(0x03); w.WriteI32(i); return; }
|
|
174
|
+
if (arg is uint u) { w.WriteByte(0x03); w.WriteI32((int)u); return; }
|
|
175
|
+
if (arg is long l) { w.WriteByte(0x04); w.WriteF64((double)l); return; }
|
|
176
|
+
if (arg is float f) { w.WriteByte(0x04); w.WriteF64((double)f); return; }
|
|
177
|
+
if (arg is double d){ w.WriteByte(0x04); w.WriteF64(d); return; }
|
|
178
|
+
if (arg is string s){ w.WriteByte(0x05); w.WriteString32(s); return; }
|
|
179
|
+
|
|
180
|
+
// Object: box in the handle map and send as a handle reference.
|
|
181
|
+
// The JS side receives {__handle, __type} which can be turned into a
|
|
182
|
+
// proxy via NSWinRT.dotnet.fromHandle(...).
|
|
183
|
+
var handleId = Interlocked.Increment(ref s_nextHandle);
|
|
184
|
+
s_handles[handleId] = arg;
|
|
185
|
+
var typeName = arg.GetType().FullName ?? arg.GetType().Name;
|
|
186
|
+
w.WriteByte(0x06);
|
|
187
|
+
w.WriteI32(handleId);
|
|
188
|
+
w.WriteString16(typeName);
|
|
189
|
+
if (Bridge.s_nativePtrs.TryGetValue(handleId, out var nativePtr2)) {
|
|
190
|
+
w.WriteByte(1);
|
|
191
|
+
w.WriteI64(nativePtr2.ToInt64());
|
|
192
|
+
} else {
|
|
193
|
+
w.WriteByte(0);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private static object? ParseCallbackResponse(ReadOnlySpan<byte> span)
|
|
198
|
+
{
|
|
199
|
+
if (span.IsEmpty) return null;
|
|
200
|
+
var r = new BinReader(span);
|
|
201
|
+
var tag = r.ReadByte();
|
|
202
|
+
switch (tag)
|
|
203
|
+
{
|
|
204
|
+
case 0x00: return null;
|
|
205
|
+
case 0x01: return (object)false;
|
|
206
|
+
case 0x02: return (object)true;
|
|
207
|
+
case 0x03: return (object)r.ReadI32();
|
|
208
|
+
case 0x04: return (object)r.ReadF64();
|
|
209
|
+
case 0x05: return (object)r.ReadString32();
|
|
210
|
+
case 0x06: return (object)new HandleRef(r.ReadI32());
|
|
211
|
+
case 0x0A: return (object)new WinRtRef(r.ReadI64());
|
|
212
|
+
case 0x07: // array: u32 count + N tagged items
|
|
213
|
+
{
|
|
214
|
+
var count = (int)r.ReadU32();
|
|
215
|
+
var arr = new object?[count];
|
|
216
|
+
for (int i = 0; i < count; i++)
|
|
217
|
+
{
|
|
218
|
+
var t = r.ReadByte();
|
|
219
|
+
switch (t)
|
|
220
|
+
{
|
|
221
|
+
case 0x00: arr[i] = null; break;
|
|
222
|
+
case 0x01: arr[i] = false; break;
|
|
223
|
+
case 0x02: arr[i] = true; break;
|
|
224
|
+
case 0x03: arr[i] = r.ReadI32(); break;
|
|
225
|
+
case 0x04: arr[i] = r.ReadF64(); break;
|
|
226
|
+
case 0x05: arr[i] = r.ReadString32(); break;
|
|
227
|
+
case 0x06: arr[i] = new HandleRef(r.ReadI32()); break;
|
|
228
|
+
case 0x0A: arr[i] = new WinRtRef(r.ReadI64()); break;
|
|
229
|
+
default: arr[i] = null; break;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return arr;
|
|
233
|
+
}
|
|
234
|
+
default: return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
internal static unsafe void CallJsCallbackVoid(int id, object?[] args)
|
|
239
|
+
{
|
|
240
|
+
CallJsCallback(id, args);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
}
|