diff --git a/platforms/app/main.c b/platforms/app/main.c index 985bf09..f698816 100644 --- a/platforms/app/main.c +++ b/platforms/app/main.c @@ -11,11 +11,15 @@ #include #include "wasm3.h" +#include "m3_api_defs.h" #include "m3_api_wasi.h" #include "m3_api_libc.h" #include "m3_api_tracer.h" -#define FATAL(msg, ...) { printf("Error: [Fatal] " msg "\n", ##__VA_ARGS__); goto _onfatal; } +// Gas metering/limit only applies to pre-instrumented modules +#define GAS_LIMIT 2000000000000 + +#define FATAL(msg, ...) { fprintf(stderr, "Error: [Fatal] " msg "\n", ##__VA_ARGS__); goto _onfatal; } #if defined(d_m3HasWASI) || defined(d_m3HasMetaWASI) || defined(d_m3HasUVWASI) #define LINK_WASI @@ -24,6 +28,26 @@ IM3Environment env; IM3Runtime runtime; +#if defined(GAS_LIMIT) + +static int64_t current_gas = GAS_LIMIT; +static bool is_gas_metered = false; + +m3ApiRawFunction(metering_usegas) +{ + m3ApiGetArg (int32_t, gas) + + current_gas -= gas; + + if (UNLIKELY(current_gas < 0)) { + m3ApiTrap("[trap] Out of gas"); + } + m3ApiSuccess(); +} + +#endif // GAS_LIMIT + + M3Result link_all (IM3Module module) { M3Result res; @@ -43,6 +67,15 @@ M3Result link_all (IM3Module module) if (res) return res; #endif +#if defined(GAS_LIMIT) + res = m3_LinkRawFunction (module, "metering", "usegas", "v(i)", &metering_usegas); + if (!res) { + fprintf(stderr, "Warning: Gas is limited to %0.4f\n", (double)(current_gas)/10000); + is_gas_metered = true; + } + if (res == m3Err_functionLookupFailed) { res = NULL; } +#endif + return res; } @@ -199,6 +232,13 @@ M3Result repl_call (const char* name, int argc, const char* argv[]) } result = m3_CallArgv (func, argc, argv); + +#if defined(GAS_LIMIT) + if (is_gas_metered) { + fprintf(stderr, "Gas used: %0.4f\n", (double)(GAS_LIMIT - current_gas)/10000); + } +#endif + if (result) return result; static uint64_t valbuff[128];