extensions
Steven Massey 5 years ago
parent 859766d87c
commit afa8478e00

@ -64,8 +64,9 @@ enum // EWaTypes
c_m3Type_f32 = 3,
c_m3Type_f64 = 4,
c_m3Type_void = 5,
c_m3Type_ptr = 6,
c_m3Type_void,
c_m3Type_ptr,
c_m3Type_trap,
c_m3Type_module
};
@ -137,6 +138,7 @@ d_m3ErrorConst (trapOutOfBoundsMemoryAccess, "[trap] out of bounds memory access
d_m3ErrorConst (trapDivisionByZero, "[trap] division by zero")
d_m3ErrorConst (trapRemainderByZero, "[trap] remainder by zero")
d_m3ErrorConst (trapTableIndexOutOfRange, "[trap] table index is out of range")
d_m3ErrorConst (trapExit, "[trap] program called exit")
d_m3ErrorConst (runtimeTrap, "[trap] unspecified runtime trap")

@ -10,6 +10,7 @@
#include "m3_exec.h"
#include "m3_env.h"
#include "m3_exception.h"
typedef struct M3State
@ -41,13 +42,13 @@ m3ret_t PushArg_module (d_m3BindingArgList, M3State * _state)
}
//printf ("push ptr: r%d off: %d\n", INDEX, offset);
#define d_argPusherPointer(INDEX) \
m3ret_t PushArg_p##INDEX (d_m3BindingArgList, M3State * _state) \
{ \
i32 offset = (u32) * (_state->sp++); \
_i##INDEX = (i64) (_state->mem + offset); \
M3ArgPusher pusher = (* _state->pc++); \
printf ("push ptr: r%d off: %d\n", INDEX, offset);\
return pusher (d_m3BindingArgs, _state); \
}
@ -85,6 +86,18 @@ M3ArgPusher c_m3Float32Pushers [] = { PushArg_f32_0, PushArg_f32_1, PushArg_f32
M3ArgPusher c_m3Float64Pushers [] = { PushArg_f64_0, PushArg_f64_1, PushArg_f64_2, PushArg_f64_3, NULL };
d_m3RetSig CallTrappingCFunction_void (d_m3OpSig)
{
M3ArgPusher pusher = (M3ArgPusher) (* _pc++);
M3State state = { _pc, _sp, _mem };
m3ret_t r = (m3ret_t) pusher (0, 0, 0, 0, 0., 0., 0., 0., & state);
return r;
}
d_m3RetSig CallCFunction_i64 (d_m3OpSig)
{
M3ArgPusher pusher = (M3ArgPusher) (* _pc++);
@ -144,10 +157,11 @@ u8 ConvertTypeCharToTypeId (char i_code)
{
u8 type = 0;
if (i_code > c_m3Type_ptr)
// if (i_code > c_m3Type_ptr)
{
if (i_code == 'v') type = c_m3Type_void;
else if (i_code == '*') type = c_m3Type_ptr;
else if (i_code == 'T') type = c_m3Type_trap;
else if (i_code == '8') type = c_m3Type_i32;
else if (i_code == 'f') type = c_m3Type_f32;
else if (i_code == 'F') type = c_m3Type_f64;
@ -160,70 +174,75 @@ u8 ConvertTypeCharToTypeId (char i_code)
}
M3Result ValidateSignature (IM3Function i_function, u8 * o_normalizedSignature, ccstr_t i_linkingSignature)
M3Result ValidateSignature (IM3Function i_function, bool * o_traps, u8 * o_normalizedSignature, ccstr_t i_linkingSignature)
{
M3Result result = c_m3Err_none;
cstr_t sig = i_linkingSignature;
* o_traps = false;
char returnTypeChar = * sig++;
cstr_t sig = i_linkingSignature;
if (returnTypeChar)
bool hasReturn = false;
u32 numArgs = 0;
// check for trap flag
u8 type = ConvertTypeCharToTypeId (* sig);
if (type == c_m3Type_trap)
{
u8 returnType = ConvertTypeCharToTypeId (returnTypeChar);
* o_traps = true;
++sig;
}
bool parsingArgs = false;
while (* sig)
{
if (numArgs >= c_m3MaxNumFunctionArgs)
throw ("arg count overflow");
char typeChar = * sig++;
if (returnType)
if (typeChar == '(')
{
o_normalizedSignature [0] = returnType;
if (not hasReturn)
throw ("malformed function signature; missing return type");
parsingArgs = true;
continue;
}
else if ( typeChar == ' ')
continue;
else if (typeChar == ')')
break;
type = ConvertTypeCharToTypeId (typeChar);
if (type)
{
* o_normalizedSignature++ = type;
if (type == c_m3Type_trap)
throw ("malformed function signature");
u32 hasModuleArgument = 0;
u32 i = 0;
while (i < c_m3MaxNumFunctionArgs)
if (not parsingArgs)
{
char typeChar = * sig++;
if (hasReturn)
throw ("malformed function signature; too many return types");
if (typeChar)
{
if (typeChar == '(' or typeChar == ' ') // allow some decoration
continue;
else if (typeChar == ')')
break;
u8 type = ConvertTypeCharToTypeId (typeChar);
if (type)
{
if (type == c_m3Type_module)
hasModuleArgument = 1;
// FIX: compare to fun; need to ignore module argument
o_normalizedSignature [++i] = type;
}
else
{
result = "unknown type char";
break;
}
}
else break;
hasReturn = true;
}
if (* sig == 0)
else
{
if (i == GetFunctionNumArgs (i_function) + hasModuleArgument)
{
}
else result = "function arg count mismatch";
if (type != c_m3Type_module)
++numArgs;
}
else result = "arg count overflow";
}
else result = "invalid return type char code";
else throw ("unknown argument type char");
}
else result = "missing return type";
return result;
if (GetFunctionNumArgs (i_function) != numArgs)
throw ("function arg count mismatch");
catch: return result;
}
@ -246,15 +265,18 @@ M3Result m3_LinkFunction (IM3Module io_module, ccstr_t i_functionName, ccstr
IM3Function func = (IM3Function) v_FindFunction (io_module, i_functionName);
if (func)
{
result = ValidateSignature (func, signature, i_signature);
bool trappingFunction = false;
result = ValidateSignature (func, & trappingFunction, signature, i_signature);
if (not result)
{
u8 returnType = signature [0];
u8 * sig = & signature [1];
u32 intIndex = 0;
u32 floatIndex = 0;
u8 * sig = & signature [1];
u32 i = 0;
while (* sig)
{
@ -287,16 +309,26 @@ M3Result m3_LinkFunction (IM3Module io_module, ccstr_t i_functionName, ccstr
func->compiled = GetPagePC (page);
func->module = io_module;
IM3Operation callerOp = CallCFunction_i64;
IM3Operation callerOp;
u8 returnType = signature [0];
if (returnType == c_m3Type_f64)
callerOp = CallCFunction_f64;
else if (returnType == c_m3Type_f32)
callerOp = CallCFunction_f32;
else if (returnType == c_m3Type_ptr)
callerOp = CallCFunction_ptr;
if (trappingFunction)
{
// TODO: returned types not implemented!
d_m3Assert (returnType == c_m3Type_void);
callerOp = CallTrappingCFunction_void;
}
else
{
callerOp = CallCFunction_i64;
if (returnType == c_m3Type_f64)
callerOp = CallCFunction_f64;
else if (returnType == c_m3Type_f32)
callerOp = CallCFunction_f32;
else if (returnType == c_m3Type_ptr)
callerOp = CallCFunction_ptr;
}
EmitWord (page, callerOp);

@ -32,13 +32,11 @@ typedef int8_t i8;
typedef u64 m3word_t;
typedef u32 m3halfword_t;
typedef i32 m3halfWordSigned_t;
// typedef i64 m3ret_t;
#else
typedef i32 m3reg_t;
typedef u32 m3word_t;
typedef u16 m3halfword_t;
// typedef i32 m3ret_t;
#endif
typedef const void * m3ret_t;

@ -9,6 +9,7 @@
#include "m3_host.h"
#include "m3_core.h"
#include "m3_env.h"
#include "m3_exception.h"
#include <stdio.h>
#include <assert.h>
@ -213,19 +214,34 @@ void m3Export (const void * i_data, i32 i_size)
fclose (f);
}
m3ret_t m3_exit (i32 i_code)
{
printf ("exit: %d\n", i_code);
return c_m3Err_trapExit;
}
M3Result SuppressLookupFailure (M3Result i_result)
{
if (i_result == c_m3Err_functionLookupFailed)
return c_m3Err_none;
else
return i_result;
}
M3Result m3_LinkCStd (IM3Module io_module)
{
M3Result result = c_m3Err_none;
m3_LinkFunction (io_module, "_printf", "v(**)", (void *) m3_printf);
m3_LinkFunction (io_module, "_fopen", "i(M**)", (void *) m3_fopen);
m3_LinkFunction (io_module, "_fread", "i(*ii*)", (void *) m3_fread);
m3_LinkFunction (io_module, "_fwrite", "i(*ii*)", (void *) m3_fwrite);
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "_printf", "v(**)", (void *) m3_printf)));
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "_fopen", "i(M**)", (void *) m3_fopen)));
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "_fread", "i(*ii*)", (void *) m3_fread)));
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "_fwrite", "i(*ii*)", (void *) m3_fwrite)));
m3_LinkFunction (io_module, "_exit", "v(i)", (void *) exit);
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "_exit", "Tv(i)", (void *) m3_exit)));
m3_LinkFunction (io_module, "g$_stderr", "i(M)", (void *) m3_getStderr);
_ (SuppressLookupFailure (m3_LinkFunction (io_module, "g$_stderr", "i(M)", (void *) m3_getStderr)));
catch: return result;
}

@ -15,26 +15,27 @@
extern "C" {
# endif
void m3StdOut (const char * const i_string);
void m3Export (const void * i_data, int32_t i_size);
double TestReturn (int32_t);
void m3Out_f64 (double i_value);
void m3Out_i32 (int32_t i_value);
void m3TestOut (int32_t i_int, double i_double, int32_t i_int1);
void m3StdOut (const char * const i_string);
void m3Export (const void * i_data, int32_t i_size);
double TestReturn (int32_t);
void m3Out_f64 (double i_value);
void m3Out_i32 (int32_t i_value);
void m3TestOut (int32_t i_int, double i_double, int32_t i_int1);
void m3_printf (cstr_t i_format, const void * i_varArgs);
void m3_printf (cstr_t i_format, const void * i_varArgs);
void m3_abort ();
void m3_abort (i32 i_dunno);
i32 m3_malloc (IM3Module i_module, i32 i_size);
void m3_free (IM3Module i_module, i32 i_data);
void * m3_memset (void * i_ptr, i32 i_value, i32 i_size);
void * m3_memcpy (void * o_dst, void * i_src, i32 i_size);
i32 m3_malloc (IM3Module i_module, i32 i_size);
void m3_free (IM3Module i_module, i32 i_data);
void * m3_memset (void * i_ptr, i32 i_value, i32 i_size);
void * m3_memcpy (void * o_dst, void * i_src, i32 i_size);
i32 m3_fread (void * ptr, i32 size, i32 count, FILE * stream);
i32 m3_fread (void * ptr, i32 size, i32 count, FILE * stream);
m3ret_t m3_exit (i32 i_code);
i32 m3_fopen (IM3Module i_module, ccstr_t i_path, ccstr_t i_mode);
i32 m3_fopen (IM3Module i_module, ccstr_t i_path, ccstr_t i_mode);
M3Result m3_LinkCStd (IM3Module io_module);

@ -26,13 +26,15 @@ void m3Output (const char * i_string)
}
int main (int argc, const char * argv [])
int main (int i_argc, const char * i_argv [])
{
M3Result result = c_m3Err_none;
m3_PrintM3Info ();
if (argc == 2)
if (i_argc >= 2)
{
FILE * f = fopen (argv [1], "rb");
FILE * f = fopen (i_argv [1], "rb");
if (f)
{
@ -46,84 +48,86 @@ int main (int argc, const char * argv [])
if (wasm)
{
fread (wasm, 1, fsize, f);
fclose (f);
IM3Module module;
M3Result result = m3_ParseModule (& module, wasm, (u32) fsize);
IM3Runtime env = nullptr;
if (not result)
try
{
IM3Runtime env = m3_NewRuntime (32768);
fread (wasm, 1, fsize, f);
fclose (f);
result = m3_LoadModule (env, module);
IM3Module module;
result = m3_ParseModule (& module, wasm, (u32) fsize); if (result) throw result;
if (not result)
{
m3_LinkFunction (module, "_m3TestOut", "v(iFi)", (void *) m3TestOut);
m3_LinkFunction (module, "_m3StdOut", "v(*)", (void *) m3Output);
m3_LinkFunction (module, "_m3Export", "v(*i)", (void *) m3Export);
m3_LinkFunction (module, "_m3Out_f64", "v(F)", (void *) m3Out_f64);
m3_LinkFunction (module, "_m3Out_i32", "v(i)", (void *) m3Out_i32);
m3_LinkFunction (module, "_TestReturn", "F(i)", (void *) TestReturn);
m3_LinkFunction (module, "abortStackOverflow", "v(i)", (void *) m3_abort);
m3_LinkFunction (module, "_malloc", "i(Mi)", (void *) m3_malloc);
m3_LinkFunction (module, "_free", "v(Mi)", (void *) m3_free);
m3_LinkFunction (module, "_memset", "*(*ii)", (void *) m3_memset);
m3_LinkFunction (module, "_memcpy", "*(**i)", (void *) m3_memcpy);
m3_LinkCStd (module);
env = m3_NewRuntime (32768);
result = m3_LoadModule (env, module); if (result) throw result;
m3_LinkFunction (module, "_m3TestOut", "v(iFi)", (void *) m3TestOut);
m3_LinkFunction (module, "_m3StdOut", "v(*)", (void *) m3Output);
m3_LinkFunction (module, "_m3Export", "v(*i)", (void *) m3Export);
m3_LinkFunction (module, "_m3Out_f64", "v(F)", (void *) m3Out_f64);
m3_LinkFunction (module, "_m3Out_i32", "v(i)", (void *) m3Out_i32);
m3_LinkFunction (module, "_TestReturn", "F(i)", (void *) TestReturn);
m3_LinkFunction (module, "abortStackOverflow", "v(i)", (void *) m3_abort);
m3_LinkFunction (module, "_malloc", "i(Mi)", (void *) m3_malloc);
m3_LinkFunction (module, "_free", "v(Mi)", (void *) m3_free);
m3_LinkFunction (module, "_memset", "*(*ii)", (void *) m3_memset);
m3_LinkFunction (module, "_memcpy", "*(**i)", (void *) m3_memcpy);
result = m3_LinkCStd (module); if (result) throw result;
m3_PrintRuntimeInfo (env);
m3_PrintRuntimeInfo (env);
IM3Function f;
result = m3_FindFunction (& f, env, "__post_instantiate"); if (result) throw result;
result = m3_Call (f); if (result) throw result;
IM3Function main;
result = m3_FindFunction (& main, env, "_main"); if (result) throw result;
if (main)
{
printf ("found _main\n");
IM3Function f;
result = m3_FindFunction (& f, env, "__post_instantiate");
if (not result)
result = m3_Call (f);
clock_t start = clock ();
IM3Function main;
result = m3_FindFunction (& main, env, "_main");
result = m3_Call (main);
if (not result and main)
{
printf ("found _main\n");
clock_t start = clock ();
result = m3_Call (main);
clock_t end = clock ();
double elapsed_time = (end - start) / (double) CLOCKS_PER_SEC ;
printf("%lf\n", elapsed_time);
printf ("call: %s\n", result);
m3_PrintProfilerInfo ();
}
else printf ("find: %s\n", result);
clock_t end = clock ();
double elapsed_time = (end - start) / (double) CLOCKS_PER_SEC ;
printf("%lf\n", elapsed_time);
printf ("call: %s\n", result);
m3_PrintProfilerInfo ();
}
else printf ("import: %s\n", result);
if (result)
m3_FreeRuntime (env);
env = nullptr;
}
catch (const M3Result & r) {}
if (result)
{
printf ("error: %s\n", result);
if (env)
{
M3ErrorInfo info = m3_GetErrorInfo (env);
printf ("%s\n", info.message);
m3_FreeRuntime (env);
}
m3_FreeRuntime (env);
}
else printf ("parse: %s\n", result);
}
free (wasm);
}
}
else printf ("couldn't open '%s'\n", argv [1]);
else printf ("couldn't open '%s'\n", i_argv [1]);
}
printf ("\n");
return 0;

Loading…
Cancel
Save