@@ -282,6 +282,40 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
282
282
for (auto wasi_func:wasi_imports_funcs) {
283
283
import_function (wasi_func, " wasi_snapshot_preview1" );
284
284
}
285
+
286
+ // In WASM: The indices of the imports precede the indices of other
287
+ // definitions in the same index space. Therefore, declare the import
288
+ // functions before defined functions
289
+ for (auto &item : global_scope->get_scope ()) {
290
+ if (ASR::is_a<ASR::Program_t>(*item.second )) {
291
+ ASR::Program_t *p = ASR::down_cast<ASR::Program_t>(item.second );
292
+ for (auto &item : p->m_symtab ->get_scope ()) {
293
+ if (ASR::is_a<ASR::Function_t>(*item.second )) {
294
+ ASR::Function_t *fn =
295
+ ASR::down_cast<ASR::Function_t>(item.second );
296
+ if (ASRUtils::get_FunctionType (fn)->m_abi == ASR::abiType::BindC &&
297
+ ASRUtils::get_FunctionType (fn)->m_deftype == ASR::deftypeType::Interface &&
298
+ !ASRUtils::is_intrinsic_function2 (fn)) {
299
+ wasm::emit_import_fn (m_import_section, m_al, " js" ,
300
+ fn->m_name , no_of_types);
301
+ no_of_imports++;
302
+ emit_function_prototype (*fn);
303
+ }
304
+ }
305
+ }
306
+ } else if (ASR::is_a<ASR::Function_t>(*item.second )) {
307
+ ASR::Function_t *fn =
308
+ ASR::down_cast<ASR::Function_t>(item.second );
309
+ if (ASRUtils::get_FunctionType (fn)->m_abi == ASR::abiType::BindC &&
310
+ ASRUtils::get_FunctionType (fn)->m_deftype == ASR::deftypeType::Interface &&
311
+ !ASRUtils::is_intrinsic_function2 (fn)) {
312
+ wasm::emit_import_fn (m_import_section, m_al, " js" ,
313
+ fn->m_name , no_of_types);
314
+ no_of_imports++;
315
+ emit_function_prototype (*fn);
316
+ }
317
+ }
318
+ }
285
319
}
286
320
287
321
void emit_if_else (std::function<void ()> test_cond, std::function<void()> if_block, std::function<void()> else_block) {
@@ -490,7 +524,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
490
524
491
525
wasm::emit_get_local (m_code_section, m_al, 0 );
492
526
wasm::emit_i64_trunc_f64_s (m_code_section, m_al);
493
- wasm::emit_call (m_code_section, m_al, 2 /* print_i64 */ );
527
+ wasm::emit_call (m_code_section, m_al, no_of_imports /* print_i64 */ );
494
528
emit_call_fd_write (1 , " ." , 1 , 0 );
495
529
496
530
wasm::emit_get_local (m_code_section, m_al, 0 );
@@ -541,7 +575,7 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
541
575
});
542
576
543
577
wasm::emit_get_local (m_code_section, m_al, 3 );
544
- wasm::emit_call (m_code_section, m_al, 2 /* print_i64 */ );
578
+ wasm::emit_call (m_code_section, m_al, no_of_imports /* print_i64 */ );
545
579
546
580
wasm::emit_b8 (m_code_section, m_al, 0x0F ); // emit wasm return instruction
547
581
wasm::emit_expr_end (m_code_section, m_al);
@@ -2334,11 +2368,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2334
2368
switch (a_kind) {
2335
2369
case 4 : {
2336
2370
wasm::emit_i64_extend_i32_s (m_code_section, m_al);
2337
- wasm::emit_call (m_code_section, m_al, 2 /* print_i64 */ );
2371
+ wasm::emit_call (m_code_section, m_al, no_of_imports /* print_i64 */ );
2338
2372
break ;
2339
2373
}
2340
2374
case 8 : {
2341
- wasm::emit_call (m_code_section, m_al, 2 /* print_i64 */ );
2375
+ wasm::emit_call (m_code_section, m_al, no_of_imports /* print_i64 */ );
2342
2376
break ;
2343
2377
}
2344
2378
default : {
@@ -2352,11 +2386,11 @@ class ASRToWASMVisitor : public ASR::BaseVisitor<ASRToWASMVisitor> {
2352
2386
switch (a_kind) {
2353
2387
case 4 : {
2354
2388
wasm::emit_f64_promote_f32 (m_code_section, m_al);
2355
- wasm::emit_call (m_code_section, m_al, 3 /* print_f64 */ );
2389
+ wasm::emit_call (m_code_section, m_al, no_of_imports + 1 /* print_f64 */ );
2356
2390
break ;
2357
2391
}
2358
2392
case 8 : {
2359
- wasm::emit_call (m_code_section, m_al, 3 /* print_f64 */ );
2393
+ wasm::emit_call (m_code_section, m_al, no_of_imports + 1 /* print_f64 */ );
2360
2394
break ;
2361
2395
}
2362
2396
default : {
0 commit comments