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
@@ -55,8 +56,15 @@ def getExtendedAttribute(self, _name):
55
56
return None
56
57
57
58
58
- input_file = sys .argv [1 ]
59
- output_base = sys .argv [2 ]
59
+ parser = argparse .ArgumentParser ()
60
+ parser .add_argument ('--wasm64' , action = 'store_true' , default = False ,
61
+ help = 'Build for wasm64' )
62
+ parser .add_argument ('infile' )
63
+ parser .add_argument ('outfile' )
64
+ options = parser .parse_args ()
65
+
66
+ input_file = options .infile
67
+ output_base = options .outfile
60
68
cpp_output = output_base + '.cpp'
61
69
js_output = output_base + '.js'
62
70
@@ -415,6 +423,10 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
415
423
call_postfix = ''
416
424
if return_type != 'Void' and not constructor :
417
425
call_prefix = 'return '
426
+
427
+ if options .wasm64 and (constructor or return_type in interfaces or return_type == 'String' ):
428
+ call_postfix += ')'
429
+
418
430
if not constructor :
419
431
if return_type in interfaces :
420
432
call_prefix += 'wrapPointer('
@@ -426,17 +438,28 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
426
438
call_prefix += '!!('
427
439
call_postfix += ')'
428
440
441
+ if options .wasm64 and (constructor or return_type in interfaces or return_type == 'String' ):
442
+ call_prefix += 'Number('
443
+
444
+
429
445
args = [(all_args [i ].identifier .name if isinstance (all_args [i ], WebIDL .IDLArgument ) else ('arg%d' % i )) for i in range (max_args )]
430
446
if not constructor and not is_static :
431
447
body = ' var self = this.ptr;\n '
432
- pre_arg = ['self' ]
448
+ if options .wasm64 :
449
+ pre_arg = ['BigInt(self)' ]
450
+ else :
451
+ pre_arg = ['self' ]
433
452
else :
434
453
body = ''
435
454
pre_arg = []
436
455
437
456
if any (arg .type .isString () or arg .type .isArray () for arg in all_args ):
438
457
body += ' ensureCache.prepare();\n '
439
458
459
+ def is_ptr_arg (i ):
460
+ t = all_args [i ].type
461
+ return (t .isArray () or t .isAny () or t .isString () or t .isObject () or t .isInterface ())
462
+
440
463
for i , (js_arg , arg ) in enumerate (zip (args , all_args )):
441
464
if i >= min_args :
442
465
optional = True
@@ -500,9 +523,11 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
500
523
501
524
if do_default :
502
525
if not (arg .type .isArray () and not array_attribute ):
503
- body += " if ({0 } && typeof {0 } === 'object') {0 } = {0 }.ptr;\n " . format ( js_arg )
526
+ body += f " if ({ js_arg } && typeof { js_arg } === 'object') { js_arg } = { js_arg } .ptr;\n "
504
527
if arg .type .isString ():
505
528
body += " else {0} = ensureString({0});\n " .format (js_arg )
529
+ if options .wasm64 and is_ptr_arg (i ):
530
+ body += f' if ({ args [i ]} === null) { args [i ]} = 0;\n '
506
531
else :
507
532
# an array can be received here
508
533
arg_type = arg .type .name
@@ -517,18 +542,45 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
517
542
elif arg_type == 'Double' :
518
543
body += " if (typeof {0} == 'object') {{ {0} = ensureFloat64({0}); }}\n " .format (js_arg )
519
544
545
+ call_args = pre_arg
546
+
547
+ for i , arg in enumerate (args ):
548
+ if options .wasm64 and is_ptr_arg (i ):
549
+ arg = f'BigInt({ arg } )'
550
+ call_args .append (arg )
551
+
520
552
c_names = {}
553
+
554
+ def make_call_args (i ):
555
+ if pre_arg :
556
+ i += 1
557
+ return ', ' .join (call_args [:i ])
558
+
521
559
for i in range (min_args , max_args ):
522
- c_names [i ] = 'emscripten_bind_%s_%d' % (bindings_name , i )
523
- 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' )
524
- c_names [max_args ] = 'emscripten_bind_%s_%d' % (bindings_name , max_args )
525
- body += ' %s%s(%s)%s;\n ' % (call_prefix , '_' + c_names [max_args ], ', ' .join (pre_arg + args ), call_postfix )
560
+ c_names [i ] = f'emscripten_bind_{ bindings_name } _{ i } '
561
+ if 'return ' in call_prefix :
562
+ after_call = ''
563
+ else :
564
+ after_call = '; ' + cache + 'return'
565
+ args_for_call = make_call_args (i )
566
+ body += ' if (%s === undefined) { %s_%s(%s)%s%s }\n ' % (args [i ], call_prefix , c_names [i ],
567
+ args_for_call ,
568
+ call_postfix , after_call )
569
+ dbg (call_prefix )
570
+ c_names [max_args ] = f'emscripten_bind_{ bindings_name } _{ max_args } '
571
+ args_for_call = make_call_args (len (args ))
572
+ body += ' %s_%s(%s)%s;\n ' % (call_prefix , c_names [max_args ], args_for_call , call_postfix )
526
573
if cache :
527
- body += ' ' + cache + '\n '
574
+ body += f' { cache } \n '
575
+
576
+ if constructor :
577
+ declare_name = ' ' + func_name
578
+ else :
579
+ declare_name = ''
528
580
mid_js .append (r'''function%s(%s) {
529
581
%s
530
582
};
531
- ''' % (( ' ' + func_name ) if constructor else '' , ', ' .join (args ), body [:- 1 ]))
583
+ ''' % (declare_name , ', ' .join (args ), body [:- 1 ]))
532
584
533
585
# C
534
586
@@ -538,7 +590,8 @@ def render_function(class_name, func_name, sigs, return_type, non_pointer,
538
590
continue
539
591
sig = list (map (full_typename , raw ))
540
592
if array_attribute :
541
- sig = [x .replace ('[]' , '' ) for x in sig ] # for arrays, ignore that this is an array - our get/set methods operate on the elements
593
+ # for arrays, ignore that this is an array - our get/set methods operate on the elements
594
+ sig = [x .replace ('[]' , '' ) for x in sig ]
542
595
543
596
c_arg_types = list (map (type_to_c , sig ))
544
597
c_class_name = type_to_c (class_name , non_pointing = True )
0 commit comments