8
8
https://emscripten.org/docs/porting/connecting_cpp_and_javascript/WebIDL-Binder.html
9
9
"""
10
10
11
+ import argparse
11
12
import os
12
13
import sys
13
14
from typing import List
32
33
# DEBUG=1 will print debug info in render_function
33
34
DEBUG = os .environ .get ('IDL_VERBOSE' ) == '1'
34
35
35
- if DEBUG :
36
- print (f'Debug print ON, CHECKS=${ CHECKS } ' )
36
+ def dbg (* args ):
37
+ if DEBUG :
38
+ print (* args , file = sys .stderr )
39
+
40
+ dbg (f'Debug print ON, CHECKS=${ CHECKS } ' )
37
41
38
42
# We need to avoid some closure errors on the constructors we define here.
39
43
CONSTRUCTOR_CLOSURE_SUPPRESSIONS = '/** @suppress {undefinedVars, duplicate} @this{Object} */'
@@ -48,8 +52,15 @@ def getExtendedAttribute(self, _name):
48
52
return None
49
53
50
54
51
- input_file = sys .argv [1 ]
52
- output_base = sys .argv [2 ]
55
+ parser = argparse .ArgumentParser ()
56
+ parser .add_argument ('--wasm64' , action = 'store_true' , default = False ,
57
+ help = 'Build for wasm64' )
58
+ parser .add_argument ('infile' )
59
+ parser .add_argument ('outfile' )
60
+ options = parser .parse_args ()
61
+
62
+ input_file = options .infile
63
+ output_base = options .outfile
53
64
cpp_output = output_base + '.cpp'
54
65
js_output = output_base + '.js'
55
66
@@ -392,13 +403,13 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
392
403
all_args = sigs .get (max_args )
393
404
394
405
if DEBUG :
395
- print ('renderfunc' , class_name , func_name , list (sigs .keys ()), return_type , constructor )
396
- for i in range ( max_args ):
397
- a = all_args [ i ]
406
+ dbg ('renderfunc' , class_name , func_name , list (sigs .keys ()), return_type , constructor )
407
+ for i , a in enumerate ( all_args ):
408
+ dbg ( type ( a ))
398
409
if isinstance (a , WebIDL .IDLArgument ):
399
- print ( ' ' , a .identifier .name , a .identifier , a .type , a .optional )
410
+ dbg ( ' ' , a .identifier .name , a .identifier , a .type , a .optional )
400
411
else :
401
- print (' arg%d' % i )
412
+ dbg (' arg%d' % i )
402
413
403
414
# JS
404
415
@@ -410,6 +421,9 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
410
421
if return_type != 'Void' and not constructor :
411
422
call_prefix = 'return '
412
423
if not constructor :
424
+ if options .wasm64 and (return_type in interfaces or return_type == 'String' ):
425
+ call_postfix += ')'
426
+
413
427
if return_type in interfaces :
414
428
call_prefix += 'wrapPointer('
415
429
call_postfix += ', ' + return_type + ')'
@@ -420,17 +434,30 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
420
434
call_prefix += '!!('
421
435
call_postfix += ')'
422
436
437
+ if options .wasm64 and (return_type in interfaces or return_type == 'String' ):
438
+ call_prefix += 'Number('
439
+
440
+
423
441
args = [(all_args [i ].identifier .name if isinstance (all_args [i ], WebIDL .IDLArgument ) else ('arg%d' % i )) for i in range (max_args )]
424
442
if not constructor and not is_static :
425
443
body = ' var self = this.ptr;\n '
426
- pre_arg = ['self' ]
444
+ if options .wasm64 :
445
+ pre_arg = ['BigInt(self)' ]
446
+ else :
447
+ pre_arg = ['self' ]
427
448
else :
428
449
body = ''
429
450
pre_arg = []
430
451
431
452
if any (arg .type .isString () or arg .type .isArray () for arg in all_args ):
432
453
body += ' ensureCache.prepare();\n '
433
454
455
+ def is_ptr_arg (i ):
456
+ if not isinstance (all_args [i ], WebIDL .IDLArgument ):
457
+ return False
458
+ t = all_args [i ].type
459
+ return (t .isArray () or t .isAny () or t .isString () or t .isObject () or t .isInterface ())
460
+
434
461
for i , (js_arg , arg ) in enumerate (zip (args , all_args )):
435
462
if i >= min_args :
436
463
optional = True
@@ -494,9 +521,11 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
494
521
495
522
if do_default :
496
523
if not (arg .type .isArray () and not array_attribute ):
497
- body += " if ({0 } && typeof {0 } === 'object') {0 } = {0 }.ptr;\n " . format ( js_arg )
524
+ body += f " if ({ js_arg } && typeof { js_arg } === 'object') { js_arg } = { js_arg } .ptr;\n "
498
525
if arg .type .isString ():
499
526
body += " else {0} = ensureString({0});\n " .format (js_arg )
527
+ if options .wasm64 and is_ptr_arg (i ):
528
+ body += f' if ({ args [i ]} === null) { args [i ]} = 0;\n '
500
529
else :
501
530
# an array can be received here
502
531
arg_type = arg .type .name
@@ -511,18 +540,44 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
511
540
elif arg_type == 'Double' :
512
541
body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}); }}\n " .format (js_arg )
513
542
543
+ call_args = pre_arg
544
+
545
+ for i , arg in enumerate (args ):
546
+ if options .wasm64 and is_ptr_arg (i ):
547
+ arg = f'BigInt({ arg } )'
548
+ call_args .append (arg )
549
+
514
550
c_names = {}
551
+
552
+ def make_call_args (i ):
553
+ if pre_arg :
554
+ i += 1
555
+ return ', ' .join (call_args [:i ])
556
+
515
557
for i in range (min_args , max_args ):
516
- c_names [i ] = 'emscripten_bind_%s_%d' % (bindings_name , i )
517
- body += ' if (%s === undefined) { %s%s(%s)%s%s }\n ' % (args [i ], call_prefix , '_' + c_names [i ], ', ' .join (pre_arg + args [:i ]), call_postfix , '' if 'return ' in call_prefix else '; ' + (cache or ' ' ) + 'return' )
518
- c_names [max_args ] = 'emscripten_bind_%s_%d' % (bindings_name , max_args )
519
- body += ' %s%s(%s)%s;\n ' % (call_prefix , '_' + c_names [max_args ], ', ' .join (pre_arg + args ), call_postfix )
558
+ c_names [i ] = f'emscripten_bind_{ bindings_name } _{ i } '
559
+ if 'return ' in call_prefix :
560
+ after_call = ''
561
+ else :
562
+ after_call = '; ' + cache + 'return'
563
+ args_for_call = make_call_args (i )
564
+ body += ' if (%s === undefined) { %s_%s(%s)%s%s }\n ' % (args [i ], call_prefix , c_names [i ],
565
+ args_for_call ,
566
+ call_postfix , after_call )
567
+ c_names [max_args ] = f'emscripten_bind_{ bindings_name } _{ max_args } '
568
+ args_for_call = make_call_args (len (args ))
569
+ body += ' %s_%s(%s)%s;\n ' % (call_prefix , c_names [max_args ], args_for_call , call_postfix )
520
570
if cache :
521
- body += ' ' + cache + '\n '
571
+ body += f' { cache } \n '
572
+
573
+ if constructor :
574
+ declare_name = ' ' + func_name
575
+ else :
576
+ declare_name = ''
522
577
mid_js .append (r'''function%s(%s) {
523
578
%s
524
579
};
525
- ''' % (( ' ' + func_name ) if constructor else '' , ', ' .join (args ), body [:- 1 ]))
580
+ ''' % (declare_name , ', ' .join (args ), body [:- 1 ]))
526
581
527
582
# C
528
583
@@ -532,7 +587,8 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
532
587
continue
533
588
sig = list (map (full_typename , raw ))
534
589
if array_attribute :
535
- sig = [x .replace ('[]' , '' ) for x in sig ] # for arrays, ignore that this is an array - our get/set methods operate on the elements
590
+ # for arrays, ignore that this is an array - our get/set methods operate on the elements
591
+ sig = [x .replace ('[]' , '' ) for x in sig ]
536
592
537
593
c_arg_types = list (map (type_to_c , sig ))
538
594
c_class_name = type_to_c (class_name , non_pointing = True )
0 commit comments