Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/src/lib/libembind_gen.js
6162 views
1
// Copyright 2023 The Emscripten Authors. All rights reserved.
2
// Emscripten is available under two separate licenses, the MIT license and the
3
// University of Illinois/NCSA Open Source License. Both these licenses can be
4
// found in the LICENSE file.
5
#include "libembind_shared.js"
6
7
var LibraryEmbind = {
8
9
$moduleDefinitions: [],
10
// Function signatures that have already been generated for JS generation.
11
$emittedFunctions: 'new Set()',
12
13
$PrimitiveType: class {
14
constructor(typeId, name, destructorType) {
15
this.typeId = typeId;
16
this.name = name;
17
this.destructorType = destructorType;
18
}
19
},
20
$IntegerType: class {
21
constructor(typeId) {
22
this.typeId = typeId;
23
this.destructorType = 'none';
24
}
25
},
26
$Argument: class {
27
constructor(name, type) {
28
this.name = name;
29
this.type = type;
30
}
31
},
32
$UserType: class {
33
constructor(typeId, name) {
34
this.typeId = typeId;
35
this.name = name;
36
this.destructorType = 'none'; // Same as emval.
37
}
38
},
39
$UserTypeDefinition: class {
40
constructor(typeId, name, definition) {
41
this.typeId = typeId;
42
this.name = name;
43
this.definition = definition;
44
this.destructorType = 'none'; // Same as emval.
45
}
46
47
print(nameMap, out) {
48
out.push(`export type ${this.name} = ${this.definition};\n\n`);
49
}
50
},
51
$OptionalType: class {
52
constructor(type) {
53
this.type = type;
54
this.destructorType = 'none'; // Same as emval.
55
}
56
},
57
$FunctionDefinition__deps: ['$createJsInvoker', '$createJsInvokerSignature', '$emittedFunctions'],
58
$FunctionDefinition: class {
59
hasPublicSymbol = true;
60
constructor(name, returnType, argumentTypes, functionIndex, thisType = null, isNonnullReturn = false, isAsync = false) {
61
this.name = name;
62
this.returnType = returnType;
63
this.argumentTypes = argumentTypes;
64
this.functionIndex = functionIndex;
65
this.thisType = thisType;
66
this.isNonnullReturn = isNonnullReturn;
67
this.isAsync = isAsync;
68
}
69
70
printSignature(nameMap, out) {
71
out.push('(');
72
const argOut = [];
73
// Work backwards on the arguments, so optional types can be replaced
74
// with TS optional params until we see the first non-optional argument.
75
let seenNonOptional = false;
76
for (let i = this.argumentTypes.length - 1; i >= 0; i--) {
77
const arg = this.argumentTypes[i];
78
let argType;
79
let argName;
80
if (arg.type instanceof OptionalType && !seenNonOptional) {
81
argType = nameMap(arg.type.type);
82
argName = arg.name + '?';
83
} else {
84
seenNonOptional = true;
85
argType = nameMap(arg.type);
86
argName = arg.name;
87
}
88
argOut.unshift(`${argName}: ${argType}`);
89
}
90
91
out.push(argOut.join(', '));
92
let returnType = this.returnType;
93
// Constructors can return a pointer, but it will be a non-null pointer.
94
// Change the return type to the class type so the TS output doesn't
95
// have `| null`.
96
if (this.isNonnullReturn && this.returnType instanceof PointerDefinition) {
97
returnType = this.returnType.classType;
98
}
99
returnType = nameMap(returnType, true);
100
if (this.isAsync) {
101
returnType = `Promise<${returnType}>`;
102
}
103
out.push(`): ${returnType}`);
104
}
105
106
printFunction(nameMap, out) {
107
out.push(`${this.name}`);
108
this.printSignature(nameMap, out);
109
}
110
111
printModuleEntry(nameMap, out) {
112
out.push(' ');
113
this.printFunction(nameMap, out);
114
out.push(';\n');
115
}
116
117
// Convert a type definition in this file to something that matches the type
118
// object in embind.js `registerType()`.
119
convertToEmbindType(type) {
120
const ret = {
121
name: type.name,
122
};
123
switch (type.destructorType) {
124
case 'none':
125
ret.destructorFunction = null;
126
break;
127
case 'function':
128
ret.destructorFunction = true;
129
break;
130
case 'stack':
131
// Intentionally empty since embind uses `undefined` for this type.
132
break;
133
default:
134
throw new Error(`Bad destructor type '${type.destructorType}'`);
135
}
136
return ret;
137
}
138
139
printJs(out) {
140
const argTypes = [this.convertToEmbindType(this.returnType)];
141
if (this.thisType) {
142
argTypes.push(this.convertToEmbindType(this.thisType));
143
} else {
144
argTypes.push(null);
145
}
146
for (const argType of this.argumentTypes) {
147
argTypes.push(this.convertToEmbindType(argType.type));
148
}
149
const signature = createJsInvokerSignature(argTypes, !!this.thisType, !this.returnType.isVoid, this.isAsync)
150
if (emittedFunctions.has(signature)) {
151
return;
152
}
153
emittedFunctions.add(signature);
154
let invokerFactory = createJsInvoker(argTypes, !!this.thisType, !this.returnType.isVoid, this.isAsync);
155
out.push(`'${signature}': ${invokerFactory},`);
156
}
157
},
158
$PointerDefinition: class {
159
constructor(classType, isConst, isSmartPointer) {
160
this.classType = classType;
161
this.isConst = isConst;
162
this.isSmartPointer = isSmartPointer;
163
this.destructorType = 'none';
164
if (isSmartPointer || classType.base) {
165
this.destructorType = 'stack';
166
}
167
}
168
},
169
$ClassDefinition: class {
170
hasPublicSymbol = true;
171
constructor(typeId, name, base = null) {
172
this.typeId = typeId;
173
this.name = name;
174
this.methods = [];
175
this.staticMethods = [];
176
this.staticProperties = [];
177
this.constructors = [];
178
this.base = base;
179
this.properties = [];
180
this.iterableElementType = null;
181
this.destructorType = 'none';
182
if (base) {
183
this.destructorType = 'stack';
184
}
185
}
186
187
print(nameMap, out) {
188
out.push(`export interface ${this.name}`);
189
const extendsParts = [];
190
if (this.base) {
191
extendsParts.push(this.base.name);
192
} else {
193
extendsParts.push('ClassHandle');
194
}
195
if (this.iterableElementType) {
196
extendsParts.push(`Iterable<${nameMap(this.iterableElementType, true)}>`);
197
}
198
out.push(` extends ${extendsParts.join(', ')}`);
199
out.push(' {\n');
200
for (const property of this.properties) {
201
const props = [];
202
property.print(nameMap, props);
203
for (const formattedProp of props) {
204
out.push(` ${formattedProp};\n`);
205
}
206
}
207
for (const method of this.methods) {
208
out.push(' ');
209
method.printFunction(nameMap, out);
210
out.push(';\n');
211
}
212
out.push('}\n\n');
213
}
214
215
printModuleEntry(nameMap, out) {
216
out.push(` ${this.name}: {`);
217
const entries = [];
218
for (const construct of this.constructors) {
219
const entry = [];
220
entry.push('new');
221
construct.printSignature(nameMap, entry);
222
entries.push(entry.join(''));
223
}
224
for (const method of this.staticMethods) {
225
const entry = [];
226
method.printFunction(nameMap, entry);
227
entries.push(entry.join(''));
228
}
229
for (const prop of this.staticProperties) {
230
const entry = [];
231
prop.print(nameMap, entry);
232
entries.push(...entry);
233
}
234
if (entries.length) {
235
out.push('\n');
236
for (const entry of entries) {
237
out.push(` ${entry};\n`);
238
}
239
out.push(' ');
240
}
241
out.push('};\n');
242
}
243
244
printJs(out) {
245
out.push(`// class ${this.name}\n`);
246
if (this.constructors.length) {
247
out.push(`// constructors\n`);
248
for (const construct of this.constructors) {
249
construct.printJs(out);
250
}
251
}
252
if (this.staticMethods.length) {
253
out.push(`// static methods\n`);
254
for (const method of this.staticMethods) {
255
method.printJs(out);
256
}
257
}
258
if (this.methods.length) {
259
out.push(`// methods\n`);
260
for (const method of this.methods) {
261
method.printJs(out);
262
}
263
}
264
out.push('\n');
265
}
266
267
},
268
$ClassProperty: class {
269
constructor(type, name, readonly) {
270
this.type = type;
271
this.name = name;
272
this.readonly = readonly;
273
}
274
275
print(nameMap, out) {
276
const setType = nameMap(this.type, false);
277
const getType = nameMap(this.type, true);
278
if (this.readonly || setType === getType) {
279
out.push(`${this.readonly ? 'readonly ' : ''}${this.name}: ${getType}`);
280
return;
281
}
282
// The getter/setter types don't match, so generate each get/set definition.
283
out.push(`get ${this.name}(): ${getType}`);
284
out.push(`set ${this.name}(value: ${setType})`);
285
}
286
},
287
$ConstantDefinition: class {
288
hasPublicSymbol = true;
289
constructor(type, name) {
290
this.type = type;
291
this.name = name;
292
}
293
294
printModuleEntry(nameMap, out) {
295
out.push(` ${this.name}: ${nameMap(this.type)};\n`);
296
}
297
},
298
$EnumDefinition: class {
299
hasPublicSymbol = true;
300
constructor(typeId, name, valueType) {
301
this.typeId = typeId;
302
this.name = name;
303
this.items = [];
304
this.destructorType = 'none';
305
this.valueType = valueType;
306
}
307
308
print(nameMap, out) {
309
if (this.valueType === 'object') {
310
out.push(`export interface ${this.name}Value<T extends number> {\n`);
311
out.push(' value: T;\n}\n');
312
}
313
out.push(`export type ${this.name} = `);
314
if (this.items.length === 0) {
315
out.push('never/* Empty Enumerator */');
316
} else {
317
const outItems = [];
318
for (const [name, value] of this.items) {
319
switch (this.valueType) {
320
case 'object':
321
outItems.push(`${this.name}Value<${value}>`);
322
break;
323
case 'number':
324
outItems.push(`${value}`);
325
break;
326
case 'string':
327
outItems.push(`'${name}'`);
328
break;
329
}
330
}
331
out.push(outItems.join('|'));
332
}
333
out.push(';\n\n');
334
}
335
336
printModuleEntry(nameMap, out) {
337
out.push(` ${this.name}: {`);
338
const outItems = [];
339
for (const [name, value] of this.items) {
340
switch (this.valueType) {
341
case 'object':
342
outItems.push(`${name}: ${this.name}Value<${value}>`);
343
break;
344
case 'number':
345
outItems.push(`${name}: ${value}`);
346
break;
347
case 'string':
348
outItems.push(`${name}: '${name}'`);
349
break;
350
}
351
}
352
out.push(outItems.join(', '));
353
out.push('};\n');
354
}
355
},
356
$ValueArrayDefinition: class {
357
constructor(typeId, name) {
358
this.typeId = typeId;
359
this.name = name;
360
this.elementTypeIds = [];
361
this.elements = [];
362
this.destructorType = 'function';
363
}
364
365
print(nameMap, out) {
366
out.push(`export type ${this.name} = [ `);
367
const outElements = [];
368
for (const type of this.elements) {
369
outElements.push(nameMap(type));
370
}
371
out.push(outElements.join(', '))
372
out.push(' ];\n\n');
373
}
374
},
375
$ValueObjectDefinition: class {
376
constructor(typeId, name) {
377
this.typeId = typeId;
378
this.name = name;
379
this.fieldTypeIds = [];
380
this.fieldNames = [];
381
this.fields = [];
382
this.destructorType = 'function';
383
}
384
385
print(nameMap, out) {
386
out.push(`export type ${this.name} = {\n`);
387
const outFields = [];
388
for (const {name, type} of this.fields) {
389
outFields.push(` ${name}${type instanceof OptionalType ? '?' : ''}: ${nameMap(type)}`);
390
}
391
out.push(outFields.join(',\n'))
392
out.push('\n};\n\n');
393
}
394
},
395
$TsPrinter__deps: ['$OptionalType', '$ClassDefinition'],
396
$TsPrinter: class {
397
constructor(definitions) {
398
this.definitions = definitions;
399
const jsString = 'EmbindString'; // Type alias for multiple types.
400
// The mapping is in the format of '<c++ name>' => ['toWireType', 'fromWireType']
401
// or if the to/from wire types are the same use a single element.
402
this.builtInToJsName = new Map([
403
['bool', ['boolean']],
404
['float', ['number']],
405
['double', ['number']],
406
#if MEMORY64
407
['long', ['bigint']],
408
['unsigned long', ['bigint']],
409
#endif
410
#if WASM_BIGINT
411
['long long', ['bigint']],
412
['unsigned long long', ['bigint']],
413
#endif
414
['void', ['void']],
415
['std::string', [jsString, 'string']],
416
['std::basic_string<unsigned char>', [jsString, 'string']],
417
['std::wstring', ['string']],
418
['std::u16string', ['string']],
419
['std::u32string', ['string']],
420
['emscripten::val', ['any']],
421
]);
422
// Signal that the type alias for EmbindString is needed.
423
this.usedEmbindString = false;
424
}
425
426
typeToJsName(type, isFromWireType = false) {
427
if (type instanceof IntegerType) {
428
return 'number';
429
}
430
if (type instanceof PrimitiveType) {
431
if (!this.builtInToJsName.has(type.name)) {
432
throw new Error(`Missing primitive type to TS type for '${type.name}'`);
433
}
434
const [toWireType, fromWireType = toWireType] = this.builtInToJsName.get(type.name);
435
const tsName = isFromWireType ? fromWireType : toWireType;
436
if (tsName === 'EmbindString') {
437
this.usedEmbindString = true;
438
}
439
return tsName;
440
}
441
if (type instanceof PointerDefinition) {
442
return `${this.typeToJsName(type.classType, isFromWireType)} | null`;
443
}
444
if (type instanceof OptionalType) {
445
return `${this.typeToJsName(type.type, isFromWireType)} | undefined`;
446
}
447
return type.name;
448
}
449
450
print() {
451
const out = [];
452
let hadClass = false;
453
for (const def of this.definitions) {
454
if (def instanceof ClassDefinition) {
455
hadClass = true;
456
break;
457
}
458
}
459
if (hadClass) {
460
out.push(
461
'export interface ClassHandle {\n',
462
' isAliasOf(other: ClassHandle): boolean;\n',
463
' delete(): void;\n',
464
' deleteLater(): this;\n',
465
' isDeleted(): boolean;\n',
466
' // @ts-ignore - If targeting lower than ESNext, this symbol might not exist.\n',
467
' [Symbol.dispose](): void;\n',
468
' clone(): this;\n',
469
'}\n',
470
);
471
}
472
for (const def of this.definitions) {
473
if (!def.print) {
474
continue;
475
}
476
def.print(this.typeToJsName.bind(this), out);
477
}
478
// Print module definitions
479
out.push('interface EmbindModule {\n');
480
for (const def of this.definitions) {
481
if (!def.printModuleEntry) {
482
continue;
483
}
484
def.printModuleEntry(this.typeToJsName.bind(this), out);
485
}
486
out.push('}\n');
487
if (this.usedEmbindString) {
488
out.unshift('type EmbindString = ArrayBuffer|Uint8Array|Uint8ClampedArray|Int8Array|string;\n');
489
}
490
return out.join('');
491
}
492
},
493
494
$JsPrinter: class {
495
constructor(definitions) {
496
this.definitions = definitions;
497
}
498
499
print() {
500
const out = ['{\n'];
501
const publicSymbols = [];
502
for (const def of this.definitions) {
503
if (def.hasPublicSymbol) {
504
publicSymbols.push(def.name);
505
}
506
if (!def.printJs) {
507
continue;
508
}
509
def.printJs(out);
510
}
511
out.push('}\n');
512
return JSON.stringify({
513
'invokers': out.join(''),
514
publicSymbols,
515
});
516
}
517
},
518
519
$registerType__deps: ['$sharedRegisterType'],
520
$registerType: function(rawType, registeredInstance, options = {}) {
521
return sharedRegisterType(rawType, registeredInstance, options);
522
},
523
$registerPrimitiveType__deps: ['$registerType', '$PrimitiveType'],
524
$registerPrimitiveType: (id, name, destructorType) => {
525
name = AsciiToString(name);
526
registerType(id, new PrimitiveType(id, name, destructorType));
527
},
528
$registerIntegerType__deps: ['$registerType', '$IntegerType'],
529
$registerIntegerType: (id) => {
530
registerType(id, new IntegerType(id));
531
},
532
$createFunctionDefinition__deps: ['$FunctionDefinition', '$heap32VectorToArray', '$AsciiToString', '$Argument', '$whenDependentTypesAreResolved', '$getFunctionName', '$getFunctionArgsName', '$PointerDefinition', '$ClassDefinition'],
533
$createFunctionDefinition: (name, argCount, rawArgTypesAddr, functionIndex, hasThis, isNonnullReturn, isAsync, cb) => {
534
const argTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
535
name = typeof name === 'string' ? name : AsciiToString(name);
536
537
whenDependentTypesAreResolved([], argTypes, function (argTypes) {
538
const argsName = getFunctionArgsName(name);
539
name = getFunctionName(name);
540
const returnType = argTypes[0];
541
let thisType = null;
542
let argStart = 1;
543
if (hasThis) {
544
thisType = argTypes[1];
545
if (thisType instanceof PointerDefinition) {
546
thisType = argTypes[1].classType;
547
}
548
if (!(thisType instanceof ClassDefinition)) {
549
throw new Error('This type must be class definition for: ' + name);
550
}
551
argStart = 2;
552
}
553
if (argsName && argsName.length != (argTypes.length - hasThis - 1)) {
554
throw new Error('Argument names should match number of parameters.');
555
}
556
557
const args = [];
558
for (let i = argStart, x = 0; i < argTypes.length; i++) {
559
if (argsName) {
560
args.push(new Argument(argsName[x++], argTypes[i]));
561
} else {
562
args.push(new Argument(`_${i - argStart}`, argTypes[i]));
563
}
564
}
565
const funcDef = new FunctionDefinition(name, returnType, args, functionIndex, thisType, isNonnullReturn, isAsync);
566
cb(funcDef);
567
return [];
568
});
569
},
570
_embind_register_void__deps: ['$registerPrimitiveType'],
571
_embind_register_void: (rawType, name) => {
572
const voidType = new PrimitiveType(rawType, 'void', 'none');
573
voidType.isVoid = true; // Match the marker property from the non-AOT mode.
574
registerType(rawType, voidType);
575
},
576
_embind_register_bool__deps: ['$registerPrimitiveType'],
577
_embind_register_bool: (rawType, name, trueValue, falseValue) => {
578
registerPrimitiveType(rawType, name, 'none');
579
},
580
_embind_register_integer__deps: ['$registerIntegerType'],
581
_embind_register_integer: (primitiveType, name, size, minRange, maxRange) => {
582
registerIntegerType(primitiveType, name);
583
},
584
_embind_register_bigint: (primitiveType, name, size, minRange, maxRange) => {
585
registerPrimitiveType(primitiveType, name, 'none');
586
},
587
_embind_register_float__deps: ['$registerPrimitiveType'],
588
_embind_register_float: (rawType, name, size) => {
589
registerPrimitiveType(rawType, name, 'none');
590
},
591
_embind_register_std_string__deps: ['$registerPrimitiveType'],
592
_embind_register_std_string: (rawType, name) => {
593
registerPrimitiveType(rawType, name, 'function');
594
},
595
_embind_register_std_wstring: (rawType, charSize, name) => {
596
registerPrimitiveType(rawType, name, 'function');
597
},
598
_embind_register_emval__deps: ['$registerType', '$PrimitiveType'],
599
_embind_register_emval: (rawType) => {
600
registerType(rawType, new PrimitiveType(rawType, 'emscripten::val', 'none'));
601
},
602
_embind_register_user_type__deps: ['$registerType', '$AsciiToString', '$UserType'],
603
_embind_register_user_type: (rawType, name) => {
604
name = AsciiToString(name);
605
registerType(rawType, new UserType(rawType, name));
606
},
607
_embind_register_user_type_definition__deps: ['$registerType', '$AsciiToString', '$UserTypeDefinition'],
608
_embind_register_user_type_definition: (rawType, name, definition) => {
609
name = AsciiToString(name);
610
definition = AsciiToString(definition);
611
const userTypeDef = new UserTypeDefinition(rawType, name, definition);
612
registerType(rawType, userTypeDef);
613
moduleDefinitions.push(userTypeDef);
614
},
615
_embind_register_optional__deps: ['$OptionalType'],
616
_embind_register_optional: (rawOptionalType, rawType) => {
617
whenDependentTypesAreResolved([rawOptionalType], [rawType], function(type) {
618
type = type[0];
619
return [new OptionalType(type)];
620
});
621
},
622
_embind_register_memory_view: (rawType, dataTypeIndex, name) => {
623
// TODO
624
},
625
_embind_register_function__deps: ['$moduleDefinitions', '$createFunctionDefinition'],
626
_embind_register_function: (name, argCount, rawArgTypesAddr, signature, rawInvoker, fn, isAsync, isNonnullReturn) => {
627
createFunctionDefinition(name, argCount, rawArgTypesAddr, fn, false, isNonnullReturn, isAsync, (funcDef) => {
628
moduleDefinitions.push(funcDef);
629
});
630
},
631
_embind_register_class__deps: ['$AsciiToString', '$ClassDefinition', '$whenDependentTypesAreResolved', '$moduleDefinitions', '$PointerDefinition'],
632
_embind_register_class: function(rawType,
633
rawPointerType,
634
rawConstPointerType,
635
baseClassRawType,
636
getActualTypeSignature,
637
getActualType,
638
upcastSignature,
639
upcast,
640
downcastSignature,
641
downcast,
642
name,
643
destructorSignature,
644
rawDestructor) {
645
name = AsciiToString(name);
646
whenDependentTypesAreResolved(
647
[rawType, rawPointerType, rawConstPointerType],
648
baseClassRawType ? [baseClassRawType] : [],
649
function(base) {
650
const hasBase = base.length;
651
const classDef = new ClassDefinition(rawType, name, hasBase ? base[0] : null);
652
moduleDefinitions.push(classDef);
653
654
const pointer = new PointerDefinition(classDef, false, false);
655
const constPointer = new PointerDefinition(classDef, true, false);
656
return [classDef, pointer, constPointer];
657
}
658
);
659
660
},
661
_embind_register_iterable__deps: ['$whenDependentTypesAreResolved'],
662
_embind_register_iterable: (rawClassType, rawElementType, sizeMethodName, getMethodName) => {
663
whenDependentTypesAreResolved([], [rawClassType, rawElementType], (types) => {
664
const classType = types[0];
665
const elementType = types[1];
666
classType.iterableElementType = elementType;
667
return [];
668
});
669
},
670
_embind_register_class_constructor__deps: ['$whenDependentTypesAreResolved', '$createFunctionDefinition'],
671
_embind_register_class_constructor: function(
672
rawClassType,
673
argCount,
674
rawArgTypesAddr,
675
invokerSignature,
676
invoker,
677
rawConstructor
678
) {
679
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
680
classType = classType[0];
681
createFunctionDefinition(`constructor ${classType.name}`, argCount, rawArgTypesAddr, rawConstructor, false, true, false, (funcDef) => {
682
classType.constructors.push(funcDef);
683
});
684
return [];
685
});
686
},
687
_embind_register_class_function__deps: ['$createFunctionDefinition'],
688
_embind_register_class_function: function(rawClassType,
689
methodName,
690
argCount,
691
rawArgTypesAddr, // [ReturnType, ThisType, Args...]
692
invokerSignature,
693
rawInvoker,
694
context,
695
isPureVirtual,
696
isAsync,
697
isNonnullReturn) {
698
createFunctionDefinition(methodName, argCount, rawArgTypesAddr, context, true, isNonnullReturn, isAsync, (funcDef) => {
699
const classDef = funcDef.thisType;
700
classDef.methods.push(funcDef);
701
});
702
},
703
_embind_register_class_property__deps: [
704
'$AsciiToString', '$whenDependentTypesAreResolved', '$ClassProperty'],
705
_embind_register_class_property: function(classType,
706
fieldName,
707
getterReturnType,
708
getterSignature,
709
getter,
710
getterContext,
711
setterArgumentType,
712
setterSignature,
713
setter,
714
setterContext) {
715
fieldName = AsciiToString(fieldName);
716
const readonly = setter === 0;
717
if (!(readonly || getterReturnType === setterArgumentType)) {
718
throw new error('Mismatched getter and setter types are not supported.');
719
}
720
721
whenDependentTypesAreResolved([], [classType], function(classType) {
722
classType = classType[0];
723
whenDependentTypesAreResolved([], [getterReturnType], function(types) {
724
const prop = new ClassProperty(types[0], fieldName, readonly);
725
classType.properties.push(prop);
726
return [];
727
});
728
return [];
729
});
730
},
731
_embind_register_class_class_function__deps: ['$createFunctionDefinition'],
732
_embind_register_class_class_function: function(rawClassType,
733
methodName,
734
argCount,
735
rawArgTypesAddr,
736
invokerSignature,
737
rawInvoker,
738
fn,
739
isAsync,
740
isNonnullReturn) {
741
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
742
classType = classType[0];
743
createFunctionDefinition(methodName, argCount, rawArgTypesAddr, fn, false, isNonnullReturn, isAsync, (funcDef) => {
744
classType.staticMethods.push(funcDef);
745
});
746
return [];
747
});
748
},
749
_embind_register_class_class_property__deps: [
750
'$AsciiToString', '$whenDependentTypesAreResolved', '$ClassProperty'],
751
_embind_register_class_class_property: (rawClassType,
752
fieldName,
753
rawFieldType,
754
rawFieldPtr,
755
getterSignature,
756
getter,
757
setterSignature,
758
setter) => {
759
fieldName = AsciiToString(fieldName);
760
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
761
classType = classType[0];
762
whenDependentTypesAreResolved([], [rawFieldType], function(types) {
763
const prop = new ClassProperty(types[0], fieldName);
764
classType.staticProperties.push(prop);
765
return [];
766
});
767
return [];
768
});
769
},
770
// Stub function. This is called when extending an object and not needed for TS generation.
771
_embind_create_inheriting_constructor: (constructorName, wrapperType, properties) => {},
772
_embind_register_enum__deps: ['$AsciiToString', '$EnumDefinition', '$moduleDefinitions', '$getEnumValueType'],
773
_embind_register_enum: function(rawType, name, size, isSigned, rawValueType) {
774
name = AsciiToString(name);
775
const valueType = getEnumValueType(rawValueType);
776
const enumDef = new EnumDefinition(rawType, name, valueType);
777
registerType(rawType, enumDef);
778
moduleDefinitions.push(enumDef);
779
},
780
_embind_register_enum_value__deps: ['$AsciiToString', '$requireRegisteredType'],
781
_embind_register_enum_value: function(rawEnumType, name, enumValue) {
782
name = AsciiToString(name);
783
const enumDef = requireRegisteredType(rawEnumType, name);
784
enumDef.items.push([name, enumValue]);
785
},
786
_embind_register_constant__deps: ['$AsciiToString', '$ConstantDefinition', '$whenDependentTypesAreResolved', '$moduleDefinitions'],
787
_embind_register_constant: function(name, typeId, value) {
788
name = AsciiToString(name);
789
whenDependentTypesAreResolved([], [typeId], function(types) {
790
const def = new ConstantDefinition(types[0], name);
791
moduleDefinitions.push(def);
792
return [];
793
});
794
},
795
_embind_register_value_array__deps: [
796
'$AsciiToString', '$ValueArrayDefinition', '$tupleRegistrations'],
797
_embind_register_value_array: function(
798
rawType,
799
name,
800
constructorSignature,
801
rawConstructor,
802
destructorSignature,
803
rawDestructor
804
) {
805
name = AsciiToString(name);
806
const valueArray = new ValueArrayDefinition(rawType, name);
807
tupleRegistrations[rawType] = valueArray;
808
},
809
_embind_register_value_array_element__deps: ['$tupleRegistrations'],
810
_embind_register_value_array_element: function(
811
rawTupleType,
812
getterReturnType,
813
getterSignature,
814
getter,
815
getterContext,
816
setterArgumentType,
817
setterSignature,
818
setter,
819
setterContext
820
) {
821
const valueArray = tupleRegistrations[rawTupleType];
822
if (getterReturnType !== setterArgumentType) {
823
throw new Error('Mismatched getter and setter types are not supported.');
824
}
825
826
valueArray.elementTypeIds.push(getterReturnType);
827
},
828
_embind_finalize_value_array__deps: ['$whenDependentTypesAreResolved', '$moduleDefinitions', '$tupleRegistrations'],
829
_embind_finalize_value_array: function(rawTupleType) {
830
const valueArray = tupleRegistrations[rawTupleType];
831
delete tupleRegistrations[rawTupleType];
832
whenDependentTypesAreResolved([rawTupleType], valueArray.elementTypeIds, function(types) {
833
moduleDefinitions.push(valueArray);
834
valueArray.elements = types;
835
return [valueArray];
836
});
837
},
838
_embind_register_value_object__deps: ['$AsciiToString', '$ValueObjectDefinition', '$structRegistrations'],
839
_embind_register_value_object: function(
840
rawType,
841
name,
842
constructorSignature,
843
rawConstructor,
844
destructorSignature,
845
rawDestructor
846
) {
847
name = AsciiToString(name);
848
const valueObject = new ValueObjectDefinition(rawType, name);
849
structRegistrations[rawType] = valueObject;
850
},
851
_embind_register_value_object_field__deps: [
852
'$AsciiToString', '$structRegistrations'],
853
_embind_register_value_object_field: function(
854
structType,
855
fieldName,
856
getterReturnType,
857
getterSignature,
858
getter,
859
getterContext,
860
setterArgumentType,
861
setterSignature,
862
setter,
863
setterContext
864
) {
865
const valueObject = structRegistrations[structType];
866
if (getterReturnType !== setterArgumentType) {
867
throw new Error('Mismatched getter and setter types are not supported.');
868
}
869
870
valueObject.fieldTypeIds.push(getterReturnType);
871
valueObject.fieldNames.push(AsciiToString(fieldName));
872
},
873
_embind_finalize_value_object__deps: ['$moduleDefinitions', '$whenDependentTypesAreResolved', '$structRegistrations'],
874
_embind_finalize_value_object: function(structType) {
875
const valueObject = structRegistrations[structType];
876
delete structRegistrations[structType];
877
whenDependentTypesAreResolved([structType], valueObject.fieldTypeIds, function(types) {
878
moduleDefinitions.push(valueObject);
879
for (let i = 0; i < types.length; i++) {
880
valueObject.fields.push({
881
name: valueObject.fieldNames[i],
882
type: types[i],
883
});
884
}
885
return [valueObject];
886
});
887
},
888
_embind_register_smart_ptr__deps: ['$whenDependentTypesAreResolved'],
889
_embind_register_smart_ptr: function(rawType,
890
rawPointeeType,
891
name,
892
sharingPolicy,
893
getPointeeSignature,
894
rawGetPointee,
895
constructorSignature,
896
rawConstructor,
897
shareSignature,
898
rawShare,
899
destructorSignature,
900
rawDestructor) {
901
whenDependentTypesAreResolved([rawType], [rawPointeeType], function(pointeeType) {
902
const smartPointer = new PointerDefinition(pointeeType[0], false, true);
903
return [smartPointer];
904
});
905
},
906
907
$emitOutput__deps: ['$awaitingDependencies', '$throwBindingError', '$getTypeName', '$moduleDefinitions',
908
#if EMBIND_AOT
909
'$JsPrinter',
910
#else
911
'$TsPrinter',
912
#endif
913
],
914
$emitOutput__postset: () => { addAtPostCtor('emitOutput()'); },
915
$emitOutput: () => {
916
for (const typeId in awaitingDependencies) {
917
throwBindingError(`Missing binding for type: '${getTypeName(typeId)}' typeId: ${typeId}`);
918
}
919
#if EMBIND_AOT
920
const printer = new JsPrinter(moduleDefinitions);
921
#else
922
const printer = new TsPrinter(moduleDefinitions);
923
#endif
924
const output = printer.print();
925
var fs = require('node:fs');
926
fs.writeFileSync(process.argv[2], output + '\n');
927
},
928
929
// Stub functions used by eval, but not needed for TS generation:
930
$makeLegalFunctionName: () => { throw new Error('stub function should not be called'); },
931
$runDestructors: () => { throw new Error('stub function should not be called'); },
932
$flushPendingDeletes: () => { throw new Error('stub function should not be called'); },
933
$setDelayFunction: () => { throw new Error('stub function should not be called'); },
934
$PureVirtualError: () => { throw new Error('stub function should not be called'); },
935
};
936
937
extraLibraryFuncs.push('$emitOutput');
938
939
addToLibrary(LibraryEmbind);
940
941