@@ -59,6 +59,8 @@ def getExtendedAttribute(self, _name):
5959parser = argparse .ArgumentParser ()
6060parser .add_argument ('--wasm64' , action = 'store_true' , default = False ,
6161 help = 'Build for wasm64' )
62+ parser .add_argument ('--thread-safe' , action = 'store_true' , default = False ,
63+ help = 'Emit temporaries as "static thread_local" to avoid race conditions' )
6264parser .add_argument ('infile' )
6365parser .add_argument ('outfile' )
6466options = parser .parse_args ()
@@ -388,7 +390,7 @@ def type_to_cdec(raw):
388390
389391def render_function (class_name , func_name , sigs , return_type , non_pointer ,
390392 copy , operator , constructor , is_static , func_scope ,
391- call_content = None , const = False , array_attribute = False ):
393+ call_content = None , const = False , array_attribute = False , thread_safe = False ):
392394 legacy_mode = CHECKS not in ['ALL' , 'FAST' ]
393395 all_checks = CHECKS == 'ALL'
394396
@@ -626,10 +628,13 @@ def make_call_args(i):
626628 basic_return = 'return ' if constructor or return_type != 'Void' else ''
627629 return_prefix = basic_return
628630 return_postfix = ''
631+ storage_attribute = ''
629632 if non_pointer :
630633 return_prefix += '&'
634+ if thread_safe :
635+ storage_attribute = 'thread_local '
631636 if copy :
632- pre += ' static %s temp;\n ' % type_to_c (return_type , non_pointing = True )
637+ pre += ' static %s%s temp;\n ' % ( storage_attribute , type_to_c (return_type , non_pointing = True ) )
633638 return_prefix += '(temp = '
634639 return_postfix += ', &temp)'
635640
@@ -767,7 +772,8 @@ def add_bounds_check_impl():
767772 constructor ,
768773 is_static = m .isStatic (),
769774 func_scope = m .parentScope .identifier .name ,
770- const = m .getExtendedAttribute ('Const' ))
775+ const = m .getExtendedAttribute ('Const' ),
776+ thread_safe = options .thread_safe )
771777 mid_js += ['\n ' ]
772778 if constructor :
773779 mid_js += build_constructor (name )
@@ -809,7 +815,8 @@ def add_bounds_check_impl():
809815 func_scope = interface ,
810816 call_content = get_call_content ,
811817 const = m .getExtendedAttribute ('Const' ),
812- array_attribute = m .type .isArray ())
818+ array_attribute = m .type .isArray (),
819+ thread_safe = options .thread_safe )
813820
814821 if m .readonly :
815822 mid_js += [r'''
@@ -831,7 +838,8 @@ def add_bounds_check_impl():
831838 func_scope = interface ,
832839 call_content = set_call_content ,
833840 const = m .getExtendedAttribute ('Const' ),
834- array_attribute = m .type .isArray ())
841+ array_attribute = m .type .isArray (),
842+ thread_safe = options .thread_safe )
835843 mid_js += [r'''
836844/** @suppress {checkTypes} */
837845Object.defineProperty(%s.prototype, '%s', { get: %s.prototype.%s, set: %s.prototype.%s });
@@ -849,7 +857,8 @@ def add_bounds_check_impl():
849857 False ,
850858 False ,
851859 func_scope = interface ,
852- call_content = 'delete self' )
860+ call_content = 'delete self' ,
861+ thread_safe = options .thread_safe )
853862
854863 # Emit C++ class implementation that calls into JS implementation
855864
0 commit comments