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