@nativescript/windows-quickjs 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.
Files changed (30) hide show
  1. package/README.md +3 -27
  2. package/framework/__PROJECT_NAME__/App.xaml +13 -13
  3. package/framework/__PROJECT_NAME__/Package.appxmanifest +35 -35
  4. package/framework/__PROJECT_NAME__/Program.cs +34 -34
  5. package/framework/__PROJECT_NAME__/Properties/Default.rd.xml +9 -9
  6. package/framework/__PROJECT_NAME__/RuntimeHost.cs +54 -11
  7. package/framework/__PROJECT_NAME__/__PROJECT_NAME__.csproj +6 -1
  8. package/framework/dotnet-bridge/BinaryProtocol.cs +161 -161
  9. package/framework/dotnet-bridge/Bridge.JsDelegate.cs +244 -244
  10. package/framework/dotnet-bridge/Bridge.TaskHelper.cs +207 -207
  11. package/framework/dotnet-bridge/DispatchTypes.cs +333 -333
  12. package/framework/dotnet-bridge/DotNetBridge.csproj +30 -30
  13. package/framework/libs/x64/nativescript.dll +0 -0
  14. package/framework/tools/ManifestMerger/ManifestMerger.dll +0 -0
  15. package/framework/tools/ManifestMerger/ManifestMerger.pdb +0 -0
  16. package/framework/tools/dotnet-tool-arm64.exe +0 -0
  17. package/framework/tools/dotnet-tool-x64.exe +0 -0
  18. package/framework/tools/dotnet-tool.exe +0 -0
  19. package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.dll +0 -0
  20. package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.exe +0 -0
  21. package/framework/tools/dotnet-typings-gen/dotnet-typings-gen.pdb +0 -0
  22. package/framework/tools/nsbundle_pack-x64.exe +0 -0
  23. package/framework/tools/nsbundle_pack.exe +0 -0
  24. package/framework/tools/sbg-arm64.exe +0 -0
  25. package/framework/tools/sbg-x64.exe +0 -0
  26. package/framework/tools/sbg.exe +0 -0
  27. package/framework/tools/typings-generator-arm64.exe +0 -0
  28. package/framework/tools/typings-generator-x64.exe +0 -0
  29. package/framework/tools/typings-generator.exe +0 -0
  30. 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
+ }