Skip to content

Commit 9c0a787

Browse files
committed
BridgeJS: Extend snapshot test setup for exports <-> global this by including mixed module test case
1 parent aca6946 commit 9c0a787

File tree

13 files changed

+1225
-0
lines changed

13 files changed

+1225
-0
lines changed

Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,25 @@ import Testing
9191
let bridgeJSLink: BridgeJSLink = BridgeJSLink(exportedSkeletons: [outputSkeleton], sharedMemory: false)
9292
try snapshot(bridgeJSLink: bridgeJSLink, name: name + ".Global.Export")
9393
}
94+
95+
@Test
96+
func snapshotMixedModuleExposure() throws {
97+
let globalURL = Self.inputsDirectory.appendingPathComponent("MixedGlobal.swift")
98+
let globalSourceFile = Parser.parse(source: try String(contentsOf: globalURL, encoding: .utf8))
99+
let globalAPI = ExportSwift(progress: .silent, moduleName: "GlobalModule", exposeToGlobal: true)
100+
try globalAPI.addSourceFile(globalSourceFile, "MixedGlobal.swift")
101+
let (_, globalSkeleton) = try #require(try globalAPI.finalize())
102+
103+
let privateURL = Self.inputsDirectory.appendingPathComponent("MixedPrivate.swift")
104+
let privateSourceFile = Parser.parse(source: try String(contentsOf: privateURL, encoding: .utf8))
105+
let privateAPI = ExportSwift(progress: .silent, moduleName: "PrivateModule", exposeToGlobal: false)
106+
try privateAPI.addSourceFile(privateSourceFile, "MixedPrivate.swift")
107+
let (_, privateSkeleton) = try #require(try privateAPI.finalize())
108+
109+
let bridgeJSLink = BridgeJSLink(
110+
exportedSkeletons: [globalSkeleton, privateSkeleton],
111+
sharedMemory: false
112+
)
113+
try snapshot(bridgeJSLink: bridgeJSLink, name: "MixedModules.Export")
114+
}
94115
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@JS(namespace: "GlobalAPI")
2+
func globalFunction() -> String
3+
4+
@JS(namespace: "GlobalAPI")
5+
class GlobalClass {
6+
@JS public init()
7+
@JS public func greet() -> String
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@JS(namespace: "PrivateAPI")
2+
func privateFunction() -> String
3+
4+
@JS(namespace: "PrivateAPI")
5+
class PrivateClass {
6+
@JS public init()
7+
@JS public func greet() -> String
8+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
/// Represents a Swift heap object like a class instance or an actor instance.
8+
export interface SwiftHeapObject {
9+
/// Release the heap object.
10+
///
11+
/// Note: Calling this method will release the heap object and it will no longer be accessible.
12+
release(): void;
13+
}
14+
export interface GlobalClass extends SwiftHeapObject {
15+
greet(): string;
16+
}
17+
export type Exports = {
18+
GlobalAPI: {
19+
GlobalClass: {
20+
new(): GlobalClass;
21+
}
22+
globalFunction(): string;
23+
},
24+
}
25+
export type Imports = {
26+
}
27+
export function createInstantiator(options: {
28+
imports: Imports;
29+
}, swift: any): Promise<{
30+
addImports: (importObject: WebAssembly.Imports) => void;
31+
setInstance: (instance: WebAssembly.Instance) => void;
32+
createExports: (instance: WebAssembly.Instance) => Exports;
33+
}>;
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
export async function createInstantiator(options, swift) {
8+
let instance;
9+
let memory;
10+
let setException;
11+
const textDecoder = new TextDecoder("utf-8");
12+
const textEncoder = new TextEncoder("utf-8");
13+
let tmpRetString;
14+
let tmpRetBytes;
15+
let tmpRetException;
16+
let tmpRetOptionalBool;
17+
let tmpRetOptionalInt;
18+
let tmpRetOptionalFloat;
19+
let tmpRetOptionalDouble;
20+
let tmpRetOptionalHeapObject;
21+
let tmpRetTag;
22+
let tmpRetStrings = [];
23+
let tmpRetInts = [];
24+
let tmpRetF32s = [];
25+
let tmpRetF64s = [];
26+
let tmpParamInts = [];
27+
let tmpParamF32s = [];
28+
let tmpParamF64s = [];
29+
30+
let _exports = null;
31+
let bjs = null;
32+
33+
return {
34+
/**
35+
* @param {WebAssembly.Imports} importObject
36+
*/
37+
addImports: (importObject, importsContext) => {
38+
bjs = {};
39+
importObject["bjs"] = bjs;
40+
const imports = options.getImports(importsContext);
41+
bjs["swift_js_return_string"] = function(ptr, len) {
42+
const bytes = new Uint8Array(memory.buffer, ptr, len);
43+
tmpRetString = textDecoder.decode(bytes);
44+
}
45+
bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) {
46+
const source = swift.memory.getObject(sourceId);
47+
const bytes = new Uint8Array(memory.buffer, bytesPtr);
48+
bytes.set(source);
49+
}
50+
bjs["swift_js_make_js_string"] = function(ptr, len) {
51+
const bytes = new Uint8Array(memory.buffer, ptr, len);
52+
return swift.memory.retain(textDecoder.decode(bytes));
53+
}
54+
bjs["swift_js_init_memory_with_result"] = function(ptr, len) {
55+
const target = new Uint8Array(memory.buffer, ptr, len);
56+
target.set(tmpRetBytes);
57+
tmpRetBytes = undefined;
58+
}
59+
bjs["swift_js_throw"] = function(id) {
60+
tmpRetException = swift.memory.retainByRef(id);
61+
}
62+
bjs["swift_js_retain"] = function(id) {
63+
return swift.memory.retainByRef(id);
64+
}
65+
bjs["swift_js_release"] = function(id) {
66+
swift.memory.release(id);
67+
}
68+
bjs["swift_js_push_tag"] = function(tag) {
69+
tmpRetTag = tag;
70+
}
71+
bjs["swift_js_push_int"] = function(v) {
72+
tmpRetInts.push(v | 0);
73+
}
74+
bjs["swift_js_push_f32"] = function(v) {
75+
tmpRetF32s.push(Math.fround(v));
76+
}
77+
bjs["swift_js_push_f64"] = function(v) {
78+
tmpRetF64s.push(v);
79+
}
80+
bjs["swift_js_push_string"] = function(ptr, len) {
81+
const bytes = new Uint8Array(memory.buffer, ptr, len);
82+
const value = textDecoder.decode(bytes);
83+
tmpRetStrings.push(value);
84+
}
85+
bjs["swift_js_pop_param_int32"] = function() {
86+
return tmpParamInts.pop();
87+
}
88+
bjs["swift_js_pop_param_f32"] = function() {
89+
return tmpParamF32s.pop();
90+
}
91+
bjs["swift_js_pop_param_f64"] = function() {
92+
return tmpParamF64s.pop();
93+
}
94+
bjs["swift_js_return_optional_bool"] = function(isSome, value) {
95+
if (isSome === 0) {
96+
tmpRetOptionalBool = null;
97+
} else {
98+
tmpRetOptionalBool = value !== 0;
99+
}
100+
}
101+
bjs["swift_js_return_optional_int"] = function(isSome, value) {
102+
if (isSome === 0) {
103+
tmpRetOptionalInt = null;
104+
} else {
105+
tmpRetOptionalInt = value | 0;
106+
}
107+
}
108+
bjs["swift_js_return_optional_float"] = function(isSome, value) {
109+
if (isSome === 0) {
110+
tmpRetOptionalFloat = null;
111+
} else {
112+
tmpRetOptionalFloat = Math.fround(value);
113+
}
114+
}
115+
bjs["swift_js_return_optional_double"] = function(isSome, value) {
116+
if (isSome === 0) {
117+
tmpRetOptionalDouble = null;
118+
} else {
119+
tmpRetOptionalDouble = value;
120+
}
121+
}
122+
bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) {
123+
if (isSome === 0) {
124+
tmpRetString = null;
125+
} else {
126+
const bytes = new Uint8Array(memory.buffer, ptr, len);
127+
tmpRetString = textDecoder.decode(bytes);
128+
}
129+
}
130+
bjs["swift_js_return_optional_object"] = function(isSome, objectId) {
131+
if (isSome === 0) {
132+
tmpRetString = null;
133+
} else {
134+
tmpRetString = swift.memory.getObject(objectId);
135+
}
136+
}
137+
bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) {
138+
if (isSome === 0) {
139+
tmpRetOptionalHeapObject = null;
140+
} else {
141+
tmpRetOptionalHeapObject = pointer;
142+
}
143+
}
144+
bjs["swift_js_get_optional_int_presence"] = function() {
145+
return tmpRetOptionalInt != null ? 1 : 0;
146+
}
147+
bjs["swift_js_get_optional_int_value"] = function() {
148+
const value = tmpRetOptionalInt;
149+
tmpRetOptionalInt = undefined;
150+
return value;
151+
}
152+
bjs["swift_js_get_optional_string"] = function() {
153+
const str = tmpRetString;
154+
tmpRetString = undefined;
155+
if (str == null) {
156+
return -1;
157+
} else {
158+
const bytes = textEncoder.encode(str);
159+
tmpRetBytes = bytes;
160+
return bytes.length;
161+
}
162+
}
163+
bjs["swift_js_get_optional_float_presence"] = function() {
164+
return tmpRetOptionalFloat != null ? 1 : 0;
165+
}
166+
bjs["swift_js_get_optional_float_value"] = function() {
167+
const value = tmpRetOptionalFloat;
168+
tmpRetOptionalFloat = undefined;
169+
return value;
170+
}
171+
bjs["swift_js_get_optional_double_presence"] = function() {
172+
return tmpRetOptionalDouble != null ? 1 : 0;
173+
}
174+
bjs["swift_js_get_optional_double_value"] = function() {
175+
const value = tmpRetOptionalDouble;
176+
tmpRetOptionalDouble = undefined;
177+
return value;
178+
}
179+
bjs["swift_js_get_optional_heap_object_pointer"] = function() {
180+
const pointer = tmpRetOptionalHeapObject;
181+
tmpRetOptionalHeapObject = undefined;
182+
return pointer || 0;
183+
}
184+
// Wrapper functions for module: TestModule
185+
if (!importObject["TestModule"]) {
186+
importObject["TestModule"] = {};
187+
}
188+
importObject["TestModule"]["bjs_GlobalClass_wrap"] = function(pointer) {
189+
const obj = GlobalClass.__construct(pointer);
190+
return swift.memory.retain(obj);
191+
};
192+
},
193+
setInstance: (i) => {
194+
instance = i;
195+
memory = instance.exports.memory;
196+
197+
setException = (error) => {
198+
instance.exports._swift_js_exception.value = swift.memory.retain(error)
199+
}
200+
},
201+
/** @param {WebAssembly.Instance} instance */
202+
createExports: (instance) => {
203+
const js = swift.memory.heap;
204+
/// Represents a Swift heap object like a class instance or an actor instance.
205+
class SwiftHeapObject {
206+
static __wrap(pointer, deinit, prototype) {
207+
const obj = Object.create(prototype);
208+
obj.pointer = pointer;
209+
obj.hasReleased = false;
210+
obj.deinit = deinit;
211+
obj.registry = new FinalizationRegistry((pointer) => {
212+
deinit(pointer);
213+
});
214+
obj.registry.register(this, obj.pointer);
215+
return obj;
216+
}
217+
218+
release() {
219+
this.registry.unregister(this);
220+
this.deinit(this.pointer);
221+
}
222+
}
223+
class GlobalClass extends SwiftHeapObject {
224+
static __construct(ptr) {
225+
return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GlobalClass_deinit, GlobalClass.prototype);
226+
}
227+
228+
constructor() {
229+
const ret = instance.exports.bjs_GlobalClass_init();
230+
return GlobalClass.__construct(ret);
231+
}
232+
greet() {
233+
instance.exports.bjs_GlobalClass_greet(this.pointer);
234+
const ret = tmpRetString;
235+
tmpRetString = undefined;
236+
return ret;
237+
}
238+
}
239+
const exports = {
240+
GlobalAPI: {
241+
GlobalClass,
242+
globalFunction: function bjs_GlobalAPI_globalFunction() {
243+
instance.exports.bjs_GlobalAPI_globalFunction();
244+
const ret = tmpRetString;
245+
tmpRetString = undefined;
246+
return ret;
247+
},
248+
},
249+
};
250+
_exports = exports;
251+
return exports;
252+
},
253+
}
254+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
2+
// DO NOT EDIT.
3+
//
4+
// To update this file, just rebuild your project or run
5+
// `swift package bridge-js`.
6+
7+
export {};
8+
9+
declare global {
10+
namespace GlobalAPI {
11+
class GlobalClass {
12+
constructor();
13+
greet(): string;
14+
}
15+
globalFunction(): string;
16+
}
17+
}
18+
19+
/// Represents a Swift heap object like a class instance or an actor instance.
20+
export interface SwiftHeapObject {
21+
/// Release the heap object.
22+
///
23+
/// Note: Calling this method will release the heap object and it will no longer be accessible.
24+
release(): void;
25+
}
26+
export interface GlobalClass extends SwiftHeapObject {
27+
greet(): string;
28+
}
29+
export interface PrivateClass extends SwiftHeapObject {
30+
greet(): string;
31+
}
32+
export type Exports = {
33+
GlobalAPI: {
34+
GlobalClass: {
35+
new(): GlobalClass;
36+
}
37+
globalFunction(): string;
38+
},
39+
PrivateAPI: {
40+
PrivateClass: {
41+
new(): PrivateClass;
42+
}
43+
privateFunction(): string;
44+
},
45+
}
46+
export type Imports = {
47+
}
48+
export function createInstantiator(options: {
49+
imports: Imports;
50+
}, swift: any): Promise<{
51+
addImports: (importObject: WebAssembly.Imports) => void;
52+
setInstance: (instance: WebAssembly.Instance) => void;
53+
createExports: (instance: WebAssembly.Instance) => Exports;
54+
}>;

0 commit comments

Comments
 (0)