linking.pp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. program linking;
  2. uses classes,ctypes, wasmtime;
  3. procedure exit_with_error(message : string; error : Pwasmtime_error_t; trap: Pwasm_trap_t); cdecl;
  4. var
  5. error_message : Twasm_byte_vec_t ;
  6. S : AnsiString;
  7. begin
  8. Writeln(stderr, 'error: ', message);
  9. S:='';
  10. if (error <> Nil) then
  11. begin
  12. write('Error: ');
  13. wasmtime_error_message(error, @error_message);
  14. wasmtime_error_delete(error)
  15. end
  16. else
  17. begin
  18. write('Trap: ');
  19. wasm_trap_message(trap, @error_message);
  20. wasm_trap_delete(trap);
  21. end;
  22. SetLength(S,error_message.size);
  23. Move(error_message.data^,S[1],error_message.size);
  24. Writeln(stderr, '>>',S,'<<');
  25. wasm_byte_vec_delete(@error_message);
  26. halt(1);
  27. end;
  28. procedure checkerror(error : Pwasmtime_error_t; Message : string);
  29. begin
  30. if Assigned(error) then
  31. exit_with_error(message,error,Nil);
  32. end;
  33. procedure checkerror(error : Pwasmtime_error_t; var trap : Pwasm_trap_t; Message : string);
  34. begin
  35. if Assigned(error) or assigned(Trap) then
  36. exit_with_error(message,error,trap);
  37. end;
  38. Procedure read_wat_file(engine : Pwasm_engine_t; out bytes : twasm_byte_vec_t; aFile : String);
  39. var
  40. wat : twasm_byte_vec_t;
  41. F : TMemoryStream;
  42. begin
  43. F:=TMemoryStream.Create;
  44. try
  45. F.LoadFromFile(aFile);
  46. wasm_byte_vec_new_uninitialized(@wat, F.Size);
  47. Move(F.Memory^,wat.data^,F.Size);
  48. finally
  49. F.Free;
  50. end;
  51. CheckError(wasmtime_wat2wasm(PAnsiChar(wat.data), wat.size, @bytes),
  52. 'failed to parse wat file '+aFile);
  53. wasm_byte_vec_delete(@wat);
  54. end;
  55. Var
  56. engine : Pwasm_engine_t = Nil;
  57. store : Pwasmtime_store_t = Nil;
  58. context : Pwasmtime_context_t = Nil;
  59. linking1_wasm, linking2_wasm : twasm_byte_vec_t;
  60. linking1_module,linking2_module : Pwasmtime_module_t;
  61. error : Pwasmtime_error_t = Nil;
  62. run : twasmtime_extern_t;
  63. trap : Pwasm_trap_t = Nil;
  64. linker : Pwasmtime_linker_t;
  65. wasi_config : Pwasi_config_t;
  66. status : cint;
  67. linking1, linking2 : twasmtime_instance_t;
  68. ok : Byte;
  69. begin
  70. linking1_module:=nil;
  71. linking2_module:=Nil;
  72. Writeln('Loading wasm library');
  73. Loadwasmtime('./'+libwasmtime);
  74. Writeln('Initializing...');
  75. engine := wasm_engine_new();
  76. store:=wasmtime_store_new(engine, nil,nil);
  77. context:=wasmtime_store_context(store);
  78. read_wat_file(engine, linking1_wasm, 'linking1.wat');
  79. read_wat_file(engine, linking2_wasm, 'linking2.wat');
  80. // Now that we've got our binary webassembly we can compile our module.
  81. Writeln('Compiling module...');
  82. error:=wasmtime_module_new(engine, Puint8_t(linking1_wasm.data), linking1_wasm.size, @linking1_module);
  83. wasm_byte_vec_delete(@linking1_wasm);
  84. if (error <> nil) then
  85. exit_with_error('failed to compile module linking1', error, nil);
  86. error:=wasmtime_module_new(engine, Puint8_t(linking2_wasm.data), linking2_wasm.size, @linking2_module);
  87. wasm_byte_vec_delete(@linking2_wasm);
  88. if (error <> nil) then
  89. exit_with_error('failed to compile module linking2', error, nil);
  90. Writeln('Configuring WASI...');
  91. wasi_config:=wasi_config_new();
  92. if (wasi_config=nil) then
  93. exit_with_error('failed to create wasi config', Nil, nil);
  94. wasi_config_inherit_argv(wasi_config);
  95. wasi_config_inherit_env(wasi_config);
  96. wasi_config_inherit_stdin(wasi_config);
  97. wasi_config_inherit_stdout(wasi_config);
  98. wasi_config_inherit_stderr(wasi_config);
  99. wasi_config_preopen_dir(wasi_config,PAnsiChar('.'),PAnsiChar('.'));
  100. CheckError(wasmtime_context_set_wasi(context, wasi_config),
  101. 'failed to instantiate WASI');
  102. Writeln('Creating linker...');
  103. linker:= wasmtime_linker_new(engine);
  104. CheckError(wasmtime_linker_define_wasi(linker),'failed to define link wasi');
  105. // Instantiate `linking2` with our linker.
  106. CheckError(wasmtime_linker_instantiate(linker, context, linking2_module, @linking2, @trap),Trap,
  107. 'failed to instantiate linking2');
  108. // Register our new `linking2` instance with the linker
  109. CheckError(wasmtime_linker_define_instance(linker, context, PAnsiChar('linking2'), Length('linking2'), @linking2),
  110. 'failed to link linking2');
  111. // Instantiate `linking1` with the linker now that `linking2` is defined
  112. CheckError(wasmtime_linker_instantiate(linker, context, linking1_module, @linking1, @trap),trap,
  113. 'failed to instantiate linking1');
  114. Writeln('Extracting export...');
  115. ok:=wasmtime_instance_export_get(context, @linking1, PAnsiChar('run'), 3, @run) ;
  116. if OK=0 then
  117. exit_with_error('failed to get run export', nil, nil);
  118. if run.kind<>WASMTIME_EXTERN_FUNC then
  119. exit_with_error('run is not a function', nil, nil);
  120. // And call it!
  121. Writeln('Calling export...');
  122. error:=wasmtime_func_call(context, @run.of_.func, nil, 0, nil, 0, @trap);
  123. if (Trap<>Nil) then
  124. begin
  125. // exit_proc is reported as trap.
  126. if wasmtime_trap_exit_status(trap,@status)<>0 then
  127. Writeln('Wasm program exited with status: ',Status)
  128. else
  129. exit_with_error('failed to run default export for module', error, trap);
  130. end
  131. else if (error<>nil) then
  132. exit_with_error('failed to run default export for module', error, trap);
  133. // Clean up after ourselves at this point
  134. Writeln('All finished!');
  135. wasmtime_linker_delete(linker);
  136. wasmtime_module_delete(linking1_module);
  137. wasmtime_module_delete(linking2_module);
  138. wasmtime_store_delete(store);
  139. wasm_engine_delete(engine);
  140. end.