def dylink_test(self, main, side, expected=None, header=None, main_emcc_args=[], force_c=False, need_reverse=True, auto_load=True, **kwargs):
    if header:
        create_test_file('header.h', header)
    old_args = self.emcc_args[:]
    self.clear_setting('MAIN_MODULE')
    self.set_setting('SIDE_MODULE')
    side_suffix = ('wasm' if self.is_wasm() else 'js')
    if isinstance(side, list):
        try_delete(('liblib.cpp.o.' + side_suffix))
        run_process(((([EMCC] + side) + self.get_emcc_args()) + ['-o', os.path.join(self.get_dir(), ('liblib.cpp.o.' + side_suffix))]))
    else:
        base = ('liblib.cpp' if (not force_c) else 'liblib.c')
        try_delete(((base + '.o.') + side_suffix))
        self.build(side, self.get_dir(), base, js_outfile=(side_suffix == 'js'))
        if force_c:
            shutil.move(((base + '.o.') + side_suffix), ('liblib.cpp.o.' + side_suffix))
    if (SPIDERMONKEY_ENGINE and os.path.exists(SPIDERMONKEY_ENGINE[0]) and (not self.is_wasm())):
        out = run_js('liblib.cpp.o.js', engine=SPIDERMONKEY_ENGINE, full_output=True, stderr=STDOUT)
        if ('asm' in out):
            self.validate_asmjs(out)
    shutil.move(('liblib.cpp.o.' + side_suffix), 'liblib.so')
    self.set_setting('MAIN_MODULE')
    self.clear_setting('SIDE_MODULE')
    if auto_load:
        self.set_setting('RUNTIME_LINKED_LIBS', ['liblib.so'])
        self.emcc_args += main_emcc_args
    if isinstance(main, list):
        try_delete('src.cpp.o.js')
        run_process((((([EMCC] + main) + self.emcc_args) + self.serialize_settings()) + ['-o', 'src.cpp.o.js']))
        self.do_run(None, expected, no_build=True, **kwargs)
    else:
        self.do_run(main, expected, force_c=force_c, **kwargs)
    self.emcc_args = old_args
    if need_reverse:
        print('flip')
        self.dylink_test(side, main, expected, header, (main_emcc_args + ['--no-entry']), force_c, need_reverse=False, **kwargs)
def dylink_test(self, main, side, expected=None, header=None, main_emcc_args=[], force_c=False, need_reverse=True, auto_load=True, **kwargs):
    if header:
        create_test_file('header.h', header)
    old_args = self.emcc_args[:]
    self.clear_setting('MAIN_MODULE')
    self.set_setting('SIDE_MODULE')
    side_suffix = ('wasm' if self.is_wasm() else 'js')
    if isinstance(side, list):
        try_delete(('liblib.cpp.o.' + side_suffix))
        run_process(((([EMCC] + side) + self.get_emcc_args()) + ['-o', os.path.join(self.get_dir(), ('liblib.cpp.o.' + side_suffix))]))
    else:
        base = ('liblib.cpp' if (not force_c) else 'liblib.c')
        try_delete(((base + '.o.') + side_suffix))
        self.build(side, self.get_dir(), base, js_outfile=(side_suffix == 'js'))
        if force_c:
            shutil.move(((base + '.o.') + side_suffix), ('liblib.cpp.o.' + side_suffix))
    if (SPIDERMONKEY_ENGINE and os.path.exists(SPIDERMONKEY_ENGINE[0]) and (not self.is_wasm())):
        out = run_js('liblib.cpp.o.js', engine=SPIDERMONKEY_ENGINE, full_output=True, stderr=STDOUT)
        if ('asm' in out):
            self.validate_asmjs(out)
    shutil.move(('liblib.cpp.o.' + side_suffix), 'liblib.so')
    self.set_setting('MAIN_MODULE')
    self.clear_setting('SIDE_MODULE')
    if auto_load:
        self.set_setting('RUNTIME_LINKED_LIBS', ['liblib.so'])
        self.emcc_args += main_emcc_args
    if isinstance(main, list):
        try_delete('src.cpp.o.js')
        run_process((((([EMCC] + main) + self.emcc_args) + self.serialize_settings()) + ['-o', 'src.cpp.o.js']))
        self.do_run(None, expected, no_build=True, **kwargs)
    else:
        self.do_run(main, expected, force_c=force_c, **kwargs)
    self.emcc_args = old_args
    if need_reverse:
        print('flip')
        self.dylink_test(side, main, expected, header, (main_emcc_args + ['--no-entry']), force_c, need_reverse=False, **kwargs)