@nativescript/windows 0.1.0-alpha.51 → 0.1.0-alpha.53
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/framework/dotnet-bridge/BinaryProtocol.cs +15 -0
- package/framework/dotnet-bridge/Bridge.BinaryDispatch.cs +7 -0
- package/framework/dotnet-bridge/Bridge.Dispatch.cs +23 -27
- package/framework/dotnet-bridge/Bridge.JsDelegate.cs +0 -4
- package/framework/dotnet-bridge/Bridge.cs +30 -14
- package/framework/dotnet-bridge/DispatchTypes.cs +27 -21
- package/framework/libs/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/arm64/nativescript.dll +0 -0
- package/framework/libs/devtools/x64/nativescript.dll +0 -0
- package/framework/libs/x64/nativescript.dll +0 -0
- package/package.json +1 -1
|
@@ -10,6 +10,13 @@ internal readonly struct HandleRef(int id)
|
|
|
10
10
|
public readonly int Id = id;
|
|
11
11
|
}
|
|
12
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
|
+
|
|
13
20
|
internal ref struct BinReader(ReadOnlySpan<byte> buf)
|
|
14
21
|
{
|
|
15
22
|
private readonly ReadOnlySpan<byte> _buf = buf;
|
|
@@ -24,6 +31,13 @@ internal ref struct BinReader(ReadOnlySpan<byte> buf)
|
|
|
24
31
|
return v;
|
|
25
32
|
}
|
|
26
33
|
|
|
34
|
+
public long ReadI64()
|
|
35
|
+
{
|
|
36
|
+
var v = BinaryPrimitives.ReadInt64LittleEndian(_buf[_pos..]);
|
|
37
|
+
_pos += 8;
|
|
38
|
+
return v;
|
|
39
|
+
}
|
|
40
|
+
|
|
27
41
|
public ushort ReadU16()
|
|
28
42
|
{
|
|
29
43
|
var v = BinaryPrimitives.ReadUInt16LittleEndian(_buf[_pos..]);
|
|
@@ -65,6 +79,7 @@ internal ref struct BinReader(ReadOnlySpan<byte> buf)
|
|
|
65
79
|
0x04 => (object)ReadF64(),
|
|
66
80
|
0x05 => (object)ReadString16(),
|
|
67
81
|
0x06 => (object)new HandleRef(ReadI32()),
|
|
82
|
+
0x0A => (object)new WinRtRef(ReadI64()),
|
|
68
83
|
_ => null,
|
|
69
84
|
};
|
|
70
85
|
}
|
|
@@ -158,6 +158,13 @@ public static partial class Bridge
|
|
|
158
158
|
s_handles.TryGetValue(hr.Id, out var obj);
|
|
159
159
|
return obj;
|
|
160
160
|
}
|
|
161
|
+
if (value is WinRtRef wr && wr.Ptr != 0)
|
|
162
|
+
{
|
|
163
|
+
// Marshal.GetObjectForIUnknown calls AddRef internally; the RCW will
|
|
164
|
+
// Release when GC'd.
|
|
165
|
+
try { return Marshal.GetObjectForIUnknown(new IntPtr(wr.Ptr)); }
|
|
166
|
+
catch { return null; }
|
|
167
|
+
}
|
|
161
168
|
if (value.GetType() == targetType) return value;
|
|
162
169
|
try { return Convert.ChangeType(value, targetType); }
|
|
163
170
|
catch { return value; }
|
|
@@ -86,8 +86,6 @@ public static partial class Bridge
|
|
|
86
86
|
finally { if (builtArgs.Length > 0) ReturnArgs(builtArgs); }
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
// ── compiled dispatch cache ───────────────────────────────────────────────
|
|
90
|
-
|
|
91
89
|
private static DispatchEntry GetCachedMethod(Type type, string name, int argCount, BindingFlags flags)
|
|
92
90
|
=> s_methodCache.GetOrAdd(
|
|
93
91
|
new MethodKey(type, name, argCount, flags),
|
|
@@ -148,8 +146,6 @@ public static partial class Bridge
|
|
|
148
146
|
new PropKey(type, method[prefixLen..], flags),
|
|
149
147
|
static k => k.Type.GetProperty(k.Name, k.Flags));
|
|
150
148
|
|
|
151
|
-
// ── argument coercion ─────────────────────────────────────────────────────
|
|
152
|
-
|
|
153
149
|
// Pooled: rented array passed to the compiled delegate (which accesses by index,
|
|
154
150
|
// not by Length). Caller must return via ReturnArgs immediately after invoke.
|
|
155
151
|
private static object?[] BuildArgs(JsonElement[] elements, ParameterInfo[] parameters)
|
|
@@ -186,8 +182,6 @@ public static partial class Bridge
|
|
|
186
182
|
return el.Deserialize(targetType, s_coerceOpts);
|
|
187
183
|
}
|
|
188
184
|
|
|
189
|
-
// ── async unwrapping ──────────────────────────────────────────────────────
|
|
190
|
-
|
|
191
185
|
private static object? AwaitIfTask(object? value)
|
|
192
186
|
{
|
|
193
187
|
if (value is null) return null;
|
|
@@ -216,8 +210,6 @@ public static partial class Bridge
|
|
|
216
210
|
return value;
|
|
217
211
|
}
|
|
218
212
|
|
|
219
|
-
// ── result boxing ─────────────────────────────────────────────────────────
|
|
220
|
-
|
|
221
213
|
private static DispatchResult Box(object? value)
|
|
222
214
|
{
|
|
223
215
|
if (value is null) return DispatchResult.Void;
|
|
@@ -239,17 +231,24 @@ public static partial class Bridge
|
|
|
239
231
|
return DispatchResult.Handle(id, t.FullName ?? t.Name);
|
|
240
232
|
}
|
|
241
233
|
|
|
242
|
-
// ── type/member resolution ────────────────────────────────────────────────
|
|
243
|
-
|
|
244
234
|
internal static DispatchResult BuildMembersResult(Type t)
|
|
245
235
|
{
|
|
246
236
|
const BindingFlags inst = BindingFlags.Public | BindingFlags.Instance;
|
|
247
237
|
const BindingFlags stat = BindingFlags.Public | BindingFlags.Static;
|
|
238
|
+
|
|
239
|
+
var instProps = t.GetProperties(inst);
|
|
240
|
+
var statProps = t.GetProperties(stat);
|
|
241
|
+
|
|
248
242
|
return DispatchResult.Members(
|
|
249
|
-
t.GetMethods(inst).Where(m => !m.IsSpecialName).Select(m => m.Name).Distinct().ToArray(),
|
|
250
|
-
|
|
251
|
-
t.GetMethods(stat).Where(m => !m.IsSpecialName).Select(m => m.Name).Distinct().ToArray(),
|
|
252
|
-
|
|
243
|
+
methods: t.GetMethods(inst).Where(m => !m.IsSpecialName).Select(m => m.Name).Distinct().ToArray(),
|
|
244
|
+
props: instProps.Where(p => p.GetGetMethod() != null).Select(p => p.Name).Distinct().ToArray(),
|
|
245
|
+
staticMethods: t.GetMethods(stat).Where(m => !m.IsSpecialName).Select(m => m.Name).Distinct().ToArray(),
|
|
246
|
+
staticProps: statProps.Where(p => p.GetGetMethod() != null).Select(p => p.Name).Distinct().ToArray(),
|
|
247
|
+
readonlyProps: instProps.Where(p => p.GetGetMethod() != null && p.GetSetMethod() == null).Select(p => p.Name).Distinct().ToArray(),
|
|
248
|
+
readonlyStaticProps: statProps.Where(p => p.GetGetMethod() != null && p.GetSetMethod() == null).Select(p => p.Name).Distinct().ToArray(),
|
|
249
|
+
writeonlyProps: instProps.Where(p => p.GetGetMethod() == null && p.GetSetMethod() != null).Select(p => p.Name).Distinct().ToArray(),
|
|
250
|
+
writeonlyStaticProps: statProps.Where(p => p.GetGetMethod() == null && p.GetSetMethod() != null).Select(p => p.Name).Distinct().ToArray()
|
|
251
|
+
);
|
|
253
252
|
}
|
|
254
253
|
|
|
255
254
|
internal static Type? ResolveType(string? assemblyName, string? typeName)
|
|
@@ -288,12 +287,14 @@ public static partial class Bridge
|
|
|
288
287
|
// we catch and continue.
|
|
289
288
|
foreach (var ty in asm.GetTypes())
|
|
290
289
|
{
|
|
291
|
-
if (string.Equals(ty.FullName, typeName, StringComparison.Ordinal)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
290
|
+
if (string.Equals(ty.FullName, typeName, StringComparison.Ordinal))
|
|
291
|
+
return ty;
|
|
292
|
+
// Short-name match only when input has no namespace prefix (e.g. "Stopwatch").
|
|
293
|
+
// Guarding on lastDot < 0 prevents matching unrelated types in other namespaces
|
|
294
|
+
// (e.g. "NativeScript.Widgets.FlexboxLayout" must not match a different
|
|
295
|
+
// FlexboxLayout that happens to live in another namespace).
|
|
296
|
+
if (lastDot < 0 && string.Equals(ty.Name, shortName, StringComparison.Ordinal))
|
|
295
297
|
return ty;
|
|
296
|
-
}
|
|
297
298
|
}
|
|
298
299
|
}
|
|
299
300
|
catch (ReflectionTypeLoadException) { }
|
|
@@ -315,12 +316,10 @@ public static partial class Bridge
|
|
|
315
316
|
{
|
|
316
317
|
foreach (var ty in asm.GetTypes())
|
|
317
318
|
{
|
|
318
|
-
if (string.Equals(ty.FullName, typeName, StringComparison.Ordinal)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
{
|
|
319
|
+
if (string.Equals(ty.FullName, typeName, StringComparison.Ordinal))
|
|
320
|
+
return ty;
|
|
321
|
+
if (lastDot < 0 && string.Equals(ty.Name, shortName, StringComparison.Ordinal))
|
|
322
322
|
return ty;
|
|
323
|
-
}
|
|
324
323
|
}
|
|
325
324
|
}
|
|
326
325
|
catch (ReflectionTypeLoadException) { }
|
|
@@ -342,7 +341,6 @@ public static partial class Bridge
|
|
|
342
341
|
internal static Exception Unwrap(Exception ex) =>
|
|
343
342
|
ex is TargetInvocationException { InnerException: { } inner } ? Unwrap(inner) : ex;
|
|
344
343
|
|
|
345
|
-
// ── full-pipeline helpers (parse + dispatch + serialise) ──────────────────
|
|
346
344
|
// Used by benchmarks to give a fair end-to-end comparison of protocols.
|
|
347
345
|
|
|
348
346
|
internal static byte[] PipelineJson(ReadOnlySpan<byte> jsonRequest)
|
|
@@ -368,8 +366,6 @@ public static partial class Bridge
|
|
|
368
366
|
return buf.WrittenSpan.ToArray();
|
|
369
367
|
}
|
|
370
368
|
|
|
371
|
-
// ── JSON response writers ─────────────────────────────────────────────────
|
|
372
|
-
|
|
373
369
|
private static unsafe void WriteResult(DispatchResult res, byte** outPtr, int* outLen)
|
|
374
370
|
{
|
|
375
371
|
var buf = new ArrayBufferWriter<byte>(256);
|
|
@@ -10,8 +10,6 @@ namespace NativeScriptBridge;
|
|
|
10
10
|
|
|
11
11
|
public static partial class Bridge
|
|
12
12
|
{
|
|
13
|
-
// ── JS delegate creation ──────────────────────────────────────────────────
|
|
14
|
-
//
|
|
15
13
|
// opcode 0x09: given a delegate type name (or "" for System.Action) and a
|
|
16
14
|
// JS callback id, compile a .NET delegate that serialises its parameters as
|
|
17
15
|
// binary and calls back into V8 via the s_jsInvoker function pointer.
|
|
@@ -51,8 +49,6 @@ public static partial class Bridge
|
|
|
51
49
|
return Box(del);
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
// ── Callback invocation helper ────────────────────────────────────────────
|
|
55
|
-
|
|
56
52
|
internal static unsafe void CallJsCallback(int id, object?[] args)
|
|
57
53
|
{
|
|
58
54
|
if (s_jsInvoker == null) return;
|
|
@@ -51,24 +51,13 @@ public static partial class Bridge
|
|
|
51
51
|
|
|
52
52
|
// Returns a JSON object mapping top-level namespace roots (e.g. "NativeScript")
|
|
53
53
|
// to the assembly simple-name that most likely contains that namespace's types.
|
|
54
|
-
//
|
|
55
|
-
// inspects exported types. The result is safe-to-call and tolerant of
|
|
56
|
-
// non-.NET DLLs.
|
|
54
|
+
// Reuses s_assemblySearchDirs so plugin and NuGet assemblies are included.
|
|
57
55
|
public static string GetNamespaceAssemblyMapJson()
|
|
58
56
|
{
|
|
59
57
|
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
60
58
|
try
|
|
61
59
|
{
|
|
62
|
-
var
|
|
63
|
-
var dirs = new List<string> { baseDir };
|
|
64
|
-
var libs = Path.Combine(baseDir, "libs");
|
|
65
|
-
if (Directory.Exists(libs))
|
|
66
|
-
{
|
|
67
|
-
dirs.Add(libs);
|
|
68
|
-
try { dirs.AddRange(Directory.GetDirectories(libs, "*", SearchOption.AllDirectories)); } catch { }
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
foreach (var dir in dirs.Where(d => !string.IsNullOrEmpty(d) && Directory.Exists(d)))
|
|
60
|
+
foreach (var dir in s_assemblySearchDirs.Where(Directory.Exists))
|
|
72
61
|
{
|
|
73
62
|
try
|
|
74
63
|
{
|
|
@@ -108,19 +97,46 @@ public static partial class Bridge
|
|
|
108
97
|
try { return JsonSerializer.Serialize(map); } catch { return "{}"; }
|
|
109
98
|
}
|
|
110
99
|
|
|
111
|
-
// Static ctor: initialize assembly search directories and register resolver.
|
|
112
100
|
static Bridge()
|
|
113
101
|
{
|
|
114
102
|
try
|
|
115
103
|
{
|
|
116
104
|
var baseDir = AppContext.BaseDirectory ?? AppDomain.CurrentDomain.BaseDirectory;
|
|
117
105
|
var dirs = new List<string> { baseDir };
|
|
106
|
+
|
|
107
|
+
// libs/ subtree relative to the bridge's own directory.
|
|
118
108
|
var libs = Path.Combine(baseDir, "libs");
|
|
119
109
|
if (Directory.Exists(libs))
|
|
120
110
|
{
|
|
121
111
|
dirs.Add(libs);
|
|
122
112
|
try { dirs.AddRange(Directory.GetDirectories(libs, "*", SearchOption.AllDirectories)); } catch { }
|
|
123
113
|
}
|
|
114
|
+
|
|
115
|
+
// The bridge DLL lives at dotnet-bridge/publish/ inside the app output root.
|
|
116
|
+
// Plugin assemblies (added via plugin.props) land at plugins/**/*.dll and NuGet
|
|
117
|
+
// assemblies land at the app output root itself — both outside the bridge subtree.
|
|
118
|
+
// Use the host process directory to reach them.
|
|
119
|
+
try
|
|
120
|
+
{
|
|
121
|
+
var processDir = Path.GetDirectoryName(
|
|
122
|
+
System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName);
|
|
123
|
+
if (!string.IsNullOrEmpty(processDir))
|
|
124
|
+
{
|
|
125
|
+
dirs.Add(processDir);
|
|
126
|
+
|
|
127
|
+
// plugins/ subtree: CLI-managed plugin DLLs live here.
|
|
128
|
+
var pluginsDir = Path.Combine(processDir, "plugins");
|
|
129
|
+
if (Directory.Exists(pluginsDir))
|
|
130
|
+
try { dirs.AddRange(Directory.GetDirectories(pluginsDir, "*", SearchOption.AllDirectories)); } catch { }
|
|
131
|
+
|
|
132
|
+
// libs/ relative to the app root (alternative convention).
|
|
133
|
+
var processLibs = Path.Combine(processDir, "libs");
|
|
134
|
+
if (Directory.Exists(processLibs))
|
|
135
|
+
try { dirs.AddRange(Directory.GetDirectories(processLibs, "*", SearchOption.AllDirectories)); } catch { }
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch { }
|
|
139
|
+
|
|
124
140
|
s_assemblySearchDirs = dirs.Where(d => !string.IsNullOrEmpty(d)).Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
|
|
125
141
|
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
|
|
126
142
|
}
|
|
@@ -12,14 +12,10 @@ using System.Threading.Tasks;
|
|
|
12
12
|
|
|
13
13
|
namespace NativeScriptBridge;
|
|
14
14
|
|
|
15
|
-
// ── JSON source-gen context ───────────────────────────────────────────────────
|
|
16
|
-
|
|
17
15
|
[JsonSerializable(typeof(InvokeRequest))]
|
|
18
16
|
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
|
19
17
|
internal partial class BridgeJsonContext : JsonSerializerContext { }
|
|
20
18
|
|
|
21
|
-
// ── JSON wire type ────────────────────────────────────────────────────────────
|
|
22
|
-
|
|
23
19
|
internal sealed record InvokeRequest(
|
|
24
20
|
string? Assembly,
|
|
25
21
|
string? TypeName,
|
|
@@ -28,7 +24,6 @@ internal sealed record InvokeRequest(
|
|
|
28
24
|
JsonElement[]? Args
|
|
29
25
|
);
|
|
30
26
|
|
|
31
|
-
// ── cache key structs ─────────────────────────────────────────────────────────
|
|
32
27
|
//
|
|
33
28
|
// Using Type as the key field (rather than Type.FullName) is correct and faster:
|
|
34
29
|
// Type instances are singletons within an AssemblyLoadContext, so reference
|
|
@@ -38,8 +33,6 @@ internal readonly record struct MethodKey(Type Type, string Name, int ArgCount,
|
|
|
38
33
|
internal readonly record struct PropKey(Type Type, string Name, BindingFlags Flags);
|
|
39
34
|
internal readonly record struct CtorKey(Type Type, int ArgCount);
|
|
40
35
|
|
|
41
|
-
// ── cache value types ─────────────────────────────────────────────────────────
|
|
42
|
-
|
|
43
36
|
internal readonly struct DispatchEntry(Func<object?, object?[], object?>? invoke, ParameterInfo[] parameters)
|
|
44
37
|
{
|
|
45
38
|
public readonly Func<object?, object?[], object?>? Invoke = invoke;
|
|
@@ -53,8 +46,6 @@ internal readonly struct CtorEntry(ConstructorInfo? ctor, ParameterInfo[] parame
|
|
|
53
46
|
public readonly ParameterInfo[] Parameters = parameters;
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
// ── dispatch result ───────────────────────────────────────────────────────────
|
|
57
|
-
|
|
58
49
|
internal enum DispatchKind : byte { Void, Primitive, Handle, Collection, Members }
|
|
59
50
|
|
|
60
51
|
internal readonly struct DispatchResult
|
|
@@ -71,14 +62,22 @@ internal readonly struct DispatchResult
|
|
|
71
62
|
private readonly string[]? _properties;
|
|
72
63
|
private readonly string[]? _staticMethods;
|
|
73
64
|
private readonly string[]? _staticProperties;
|
|
65
|
+
private readonly string[]? _readonlyProperties;
|
|
66
|
+
private readonly string[]? _readonlyStaticProperties;
|
|
67
|
+
private readonly string[]? _writeonlyProperties;
|
|
68
|
+
private readonly string[]? _writeonlyStaticProperties;
|
|
74
69
|
|
|
75
70
|
private DispatchResult(DispatchKind kind, object? value, Type? type, int handle,
|
|
76
71
|
string? typeName, string[]? methods, string[]? props,
|
|
77
|
-
string[]? staticMethods, string[]? staticProps
|
|
72
|
+
string[]? staticMethods, string[]? staticProps,
|
|
73
|
+
string[]? readonlyProps = null, string[]? readonlyStaticProps = null,
|
|
74
|
+
string[]? writeonlyProps = null, string[]? writeonlyStaticProps = null)
|
|
78
75
|
{
|
|
79
76
|
_kind = kind; _value = value; _type = type; _handle = handle;
|
|
80
77
|
_typeName = typeName; _methods = methods; _properties = props;
|
|
81
78
|
_staticMethods = staticMethods; _staticProperties = staticProps;
|
|
79
|
+
_readonlyProperties = readonlyProps; _readonlyStaticProperties = readonlyStaticProps;
|
|
80
|
+
_writeonlyProperties = writeonlyProps; _writeonlyStaticProperties = writeonlyStaticProps;
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
public static DispatchResult Primitive(object value, Type type)
|
|
@@ -91,13 +90,15 @@ internal readonly struct DispatchResult
|
|
|
91
90
|
=> new(DispatchKind.Collection, items, null, 0, null, null, null, null, null);
|
|
92
91
|
|
|
93
92
|
public static DispatchResult Members(
|
|
94
|
-
string[] methods, string[] props, string[] staticMethods, string[] staticProps
|
|
95
|
-
|
|
93
|
+
string[] methods, string[] props, string[] staticMethods, string[] staticProps,
|
|
94
|
+
string[] readonlyProps, string[] readonlyStaticProps,
|
|
95
|
+
string[] writeonlyProps, string[] writeonlyStaticProps)
|
|
96
|
+
=> new(DispatchKind.Members, null, null, 0, null,
|
|
97
|
+
methods, props, staticMethods, staticProps,
|
|
98
|
+
readonlyProps, readonlyStaticProps, writeonlyProps, writeonlyStaticProps);
|
|
96
99
|
|
|
97
100
|
internal int HandleId() => _handle;
|
|
98
101
|
|
|
99
|
-
// ── JSON serialisation ────────────────────────────────────────────────────
|
|
100
|
-
|
|
101
102
|
public void WriteTo(Utf8JsonWriter w, JsonSerializerOptions opts)
|
|
102
103
|
{
|
|
103
104
|
switch (_kind)
|
|
@@ -126,10 +127,14 @@ internal readonly struct DispatchResult
|
|
|
126
127
|
|
|
127
128
|
case DispatchKind.Members:
|
|
128
129
|
w.WriteStartObject();
|
|
129
|
-
WriteStringArray(w, "methods"u8,
|
|
130
|
-
WriteStringArray(w, "properties"u8,
|
|
131
|
-
WriteStringArray(w, "staticMethods"u8,
|
|
132
|
-
WriteStringArray(w, "staticProperties"u8,
|
|
130
|
+
WriteStringArray(w, "methods"u8, _methods!);
|
|
131
|
+
WriteStringArray(w, "properties"u8, _properties!);
|
|
132
|
+
WriteStringArray(w, "staticMethods"u8, _staticMethods!);
|
|
133
|
+
WriteStringArray(w, "staticProperties"u8, _staticProperties!);
|
|
134
|
+
WriteStringArray(w, "readonlyProperties"u8, _readonlyProperties!);
|
|
135
|
+
WriteStringArray(w, "readonlyStaticProperties"u8, _readonlyStaticProperties!);
|
|
136
|
+
WriteStringArray(w, "writeonlyProperties"u8, _writeonlyProperties!);
|
|
137
|
+
WriteStringArray(w, "writeonlyStaticProperties"u8,_writeonlyStaticProperties!);
|
|
133
138
|
w.WriteEndObject();
|
|
134
139
|
break;
|
|
135
140
|
}
|
|
@@ -142,7 +147,6 @@ internal readonly struct DispatchResult
|
|
|
142
147
|
w.WriteEndArray();
|
|
143
148
|
}
|
|
144
149
|
|
|
145
|
-
// ── binary serialisation ──────────────────────────────────────────────────
|
|
146
150
|
//
|
|
147
151
|
// Response tags:
|
|
148
152
|
// 0x00 = null 0x01 = false 0x02 = true
|
|
@@ -185,6 +189,10 @@ internal readonly struct DispatchResult
|
|
|
185
189
|
WriteStringArrayBin(ref w, _properties!);
|
|
186
190
|
WriteStringArrayBin(ref w, _staticMethods!);
|
|
187
191
|
WriteStringArrayBin(ref w, _staticProperties!);
|
|
192
|
+
WriteStringArrayBin(ref w, _readonlyProperties!);
|
|
193
|
+
WriteStringArrayBin(ref w, _readonlyStaticProperties!);
|
|
194
|
+
WriteStringArrayBin(ref w, _writeonlyProperties!);
|
|
195
|
+
WriteStringArrayBin(ref w, _writeonlyStaticProperties!);
|
|
188
196
|
break;
|
|
189
197
|
}
|
|
190
198
|
}
|
|
@@ -242,8 +250,6 @@ internal readonly struct DispatchResult
|
|
|
242
250
|
}
|
|
243
251
|
}
|
|
244
252
|
|
|
245
|
-
// ── async result helpers ──────────────────────────────────────────────────────
|
|
246
|
-
|
|
247
253
|
internal static class TaskResultCache
|
|
248
254
|
{
|
|
249
255
|
private static readonly ConcurrentDictionary<Type, Func<Task, object?>> s_cache = new();
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|