@no_asan('asan is not compatible with asyncify stack operations; may also need to not instrument asan_c_load_4, TODO')
def test_async(self):
    self.set_setting('EXIT_RUNTIME', 1)
    self.banned_js_engines = [SPIDERMONKEY_ENGINE, V8_ENGINE]
    if self.is_wasm_backend():
        self.set_setting('ASYNCIFY', 1)
    else:
        self.skipTest('fastcomp Asyncify was removed')
    src = '\n#include <stdio.h>\n#include <emscripten.h>\nvoid f(void *p) {\n  *(int*)p = 99;\n  printf("!");\n}\nint main() {\n  int i = 0;\n  printf("Hello");\n  emscripten_async_call(f, &i, 1);\n  printf("World");\n  emscripten_sleep(100);\n  printf("%d\\n", i);\n}\n'
    self.do_run(src, 'HelloWorld!99')
    if self.is_wasm_backend():
        print('check bad ccall use')
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nint main() {\n  printf("Hello");\n  emscripten_sleep(100);\n  printf("World\\n");\n}\n'
        self.set_setting('ASSERTIONS', 1)
        self.set_setting('INVOKE_RUN', 0)
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  try {\n    ccall('main', 'number', ['number', 'string'], [2, 'waka']);\n    var never = true;\n  } catch(e) {\n    out(e);\n    assert(!never);\n  }\n};\n")
        self.emcc_args += ['--pre-js', 'pre.js']
        self.do_run(src, 'The call to main is running asynchronously.')
        print('check reasonable ccall use')
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nint main() {\n  printf("Hello");\n  emscripten_sleep(100);\n  printf("World\\n");\n}\n'
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  ccall('main', null, ['number', 'string'], [2, 'waka'], { async: true });\n};\n")
        self.do_run(src, 'HelloWorld')
        print('check ccall promise')
        self.set_setting('EXPORTED_FUNCTIONS', ['_stringf', '_floatf'])
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nextern "C" {\n  const char* stringf(char* param) {\n    emscripten_sleep(20);\n    printf(param);\n    return "second";\n  }\n  double floatf() {\n    emscripten_sleep(20);\n    emscripten_sleep(20);\n    return 6.4;\n  }\n}\n'
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  ccall('stringf', 'string', ['string'], ['first\\n'], { async: true })\n    .then(function(val) {\n      console.log(val);\n      ccall('floatf', 'number', null, null, { async: true }).then(console.log);\n    });\n};\n")
        self.do_run(src, 'first\nsecond\n6.4')
@no_asan('asan is not compatible with asyncify stack operations; may also need to not instrument asan_c_load_4, TODO')
def test_async(self):
    self.set_setting('EXIT_RUNTIME', 1)
    self.banned_js_engines = [SPIDERMONKEY_ENGINE, V8_ENGINE]
    if self.is_wasm_backend():
        self.set_setting('ASYNCIFY', 1)
    else:
        self.skipTest('fastcomp Asyncify was removed')
    src = '\n#include <stdio.h>\n#include <emscripten.h>\nvoid f(void *p) {\n  *(int*)p = 99;\n  printf("!");\n}\nint main() {\n  int i = 0;\n  printf("Hello");\n  emscripten_async_call(f, &i, 1);\n  printf("World");\n  emscripten_sleep(100);\n  printf("%d\\n", i);\n}\n'
    self.do_run(src, 'HelloWorld!99')
    if self.is_wasm_backend():
        print('check bad ccall use')
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nint main() {\n  printf("Hello");\n  emscripten_sleep(100);\n  printf("World\\n");\n}\n'
        self.set_setting('ASSERTIONS', 1)
        self.set_setting('INVOKE_RUN', 0)
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  try {\n    ccall('main', 'number', ['number', 'string'], [2, 'waka']);\n    var never = true;\n  } catch(e) {\n    out(e);\n    assert(!never);\n  }\n};\n")
        self.emcc_args += ['--pre-js', 'pre.js']
        self.do_run(src, 'The call to main is running asynchronously.')
        print('check reasonable ccall use')
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nint main() {\n  printf("Hello");\n  emscripten_sleep(100);\n  printf("World\\n");\n}\n'
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  ccall('main', null, ['number', 'string'], [2, 'waka'], { async: true });\n};\n")
        self.do_run(src, 'HelloWorld')
        print('check ccall promise')
        self.set_setting('EXPORTED_FUNCTIONS', ['_stringf', '_floatf'])
        src = '\n#include <stdio.h>\n#include <emscripten.h>\nextern "C" {\n  const char* stringf(char* param) {\n    emscripten_sleep(20);\n    printf(param);\n    return "second";\n  }\n  double floatf() {\n    emscripten_sleep(20);\n    emscripten_sleep(20);\n    return 6.4;\n  }\n}\n'
        create_test_file('pre.js', "\nModule['onRuntimeInitialized'] = function() {\n  ccall('stringf', 'string', ['string'], ['first\\n'], { async: true })\n    .then(function(val) {\n      console.log(val);\n      ccall('floatf', 'number', null, null, { async: true }).then(console.log);\n    });\n};\n")
        self.do_run(src, 'first\nsecond\n6.4')