1 /**
2  * \file
3  * WASM AOT runtime
4  */
5 
6 #include "config.h"
7 
8 #include <sys/types.h>
9 
10 #include "mini.h"
11 #include "interp/interp.h"
12 
13 #ifdef TARGET_WASM
14 
15 static void
wasm_restore_context(void)16 wasm_restore_context (void)
17 {
18 	g_error ("wasm_restore_context");
19 }
20 
21 static void
wasm_call_filter(void)22 wasm_call_filter (void)
23 {
24 	g_error ("wasm_call_filter");
25 }
26 
27 static void
wasm_throw_exception(void)28 wasm_throw_exception (void)
29 {
30 	g_error ("wasm_throw_exception");
31 }
32 
33 static void
wasm_rethrow_exception(void)34 wasm_rethrow_exception (void)
35 {
36 	g_error ("wasm_rethrow_exception");
37 }
38 
39 static void
wasm_throw_corlib_exception(void)40 wasm_throw_corlib_exception (void)
41 {
42 	g_error ("wasm_throw_corlib_exception");
43 }
44 
45 static char
type_to_c(MonoType * t)46 type_to_c (MonoType *t)
47 {
48 	if (t->byref)
49 		return 'I';
50 
51 handle_enum:
52 	switch (t->type) {
53 	case MONO_TYPE_BOOLEAN:
54 	case MONO_TYPE_CHAR:
55 	case MONO_TYPE_I1:
56 	case MONO_TYPE_U1:
57 	case MONO_TYPE_I2:
58 	case MONO_TYPE_U2:
59 	case MONO_TYPE_I4:
60 	case MONO_TYPE_U4:
61 	case MONO_TYPE_I:
62 	case MONO_TYPE_U:
63 	case MONO_TYPE_PTR:
64 	case MONO_TYPE_SZARRAY:
65 	case MONO_TYPE_CLASS:
66 	case MONO_TYPE_OBJECT:
67 	case MONO_TYPE_STRING:
68 		return 'I';
69 	case MONO_TYPE_R4:
70 		return 'F';
71 	case MONO_TYPE_R8:
72 		return 'D';
73 		break;
74 	case MONO_TYPE_I8:
75 	case MONO_TYPE_U8:
76 		return 'L';
77 	case MONO_TYPE_VOID:
78 		return 'V';
79 	case MONO_TYPE_VALUETYPE:
80 		if (t->data.klass->enumtype) {
81 			t = mono_class_enum_basetype (t->data.klass);
82 			goto handle_enum;
83 		}
84 
85 		return 'I';
86 	case MONO_TYPE_GENERICINST:
87 		if (t->data.klass->valuetype)
88 			return 'S';
89 		return 'I';
90 	default:
91 		g_warning ("CANT TRANSLATE %s", mono_type_full_name (t));
92 		return 'X';
93 	}
94 }
95 
96 #if SIZEOF_VOID_P == 4
97 #define FIDX(x) ((x) * 2)
98 #else
99 #define FIDX(x) (x)
100 #endif
101 
102 
103 
104 typedef union {
105 	gint64 l;
106 	struct {
107 		gint32 lo;
108 		gint32 hi;
109 	} pair;
110 } interp_pair;
111 
112 static inline gint64
get_long_arg(InterpMethodArguments * margs,int idx)113 get_long_arg (InterpMethodArguments *margs, int idx)
114 {
115 	interp_pair p;
116 	p.pair.lo = (gint32)margs->iargs [idx];
117 	p.pair.hi = (gint32)margs->iargs [idx + 1];
118 	return p.l;
119 }
120 
121 #include "wasm_m2n_invoke.g.h"
122 
123 static void
wasm_enter_icall_trampoline(void * target_func,InterpMethodArguments * margs)124 wasm_enter_icall_trampoline (void *target_func, InterpMethodArguments *margs)
125 {
126 	static char cookie [8];
127 	static int c_count;
128 
129 	MonoMethodSignature *sig = margs->sig;
130 
131 	c_count = sig->param_count + sig->hasthis + 1;
132 	cookie [0] = type_to_c (sig->ret);
133 	if (sig->hasthis)
134 		cookie [1] = 'I';
135 	for (int i = 0; i < sig->param_count; ++i)
136 		cookie [1 + sig->hasthis + i ] = type_to_c (sig->params [i]);
137 	cookie [c_count] = 0;
138 
139 	icall_trampoline_dispatch (cookie, target_func, margs);
140 }
141 
142 gpointer
mono_aot_get_trampoline_full(const char * name,MonoTrampInfo ** out_tinfo)143 mono_aot_get_trampoline_full (const char *name, MonoTrampInfo **out_tinfo)
144 {
145 	gpointer code = NULL;
146 
147 	if (!strcmp (name, "restore_context"))
148 		code = wasm_restore_context;
149 	else if (!strcmp (name, "call_filter"))
150 		code = wasm_call_filter;
151 	else if (!strcmp (name, "throw_exception"))
152 		code = wasm_throw_exception;
153 	else if (!strcmp (name, "rethrow_exception"))
154 		code = wasm_rethrow_exception;
155 	else if (!strcmp (name, "throw_corlib_exception"))
156 		code = wasm_throw_corlib_exception;
157 	else if (!strcmp (name, "enter_icall_trampoline"))
158 		code = wasm_enter_icall_trampoline;
159 
160 	g_assert (code);
161 
162 	if (out_tinfo) {
163 		MonoTrampInfo *tinfo = g_new0 (MonoTrampInfo, 1);
164 		tinfo->code = code;
165 		tinfo->code_size = 1;
166 		tinfo->name = g_strdup (name);
167 		tinfo->ji = NULL;
168 		tinfo->unwind_ops = NULL;
169 		tinfo->uw_info = NULL;
170 		tinfo->uw_info_len = 0;
171 		tinfo->owns_uw_info = FALSE;
172 
173 		*out_tinfo = tinfo;
174 	}
175 
176 	return code;
177 }
178 #else /* TARGET_WASM */
179 
180 MONO_EMPTY_SOURCE_FILE (aot_runtime_wasm);
181 
182 #endif /* TARGET_WASM */
183