typedef struct {
int cur_frame;
int target_frame;
- int variable;
+ int len;
+ int *pos;
} FrameDescData;
static gboolean describe_value(MonoType * type, gpointer addr)
return TRUE;
}
-static gboolean
-describe_async_method_locals (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud)
+static void
+describe_async_method_locals (InterpFrame *frame, MonoMethod *method)
{
//Async methods are special in the way that local variables can be lifted to generated class fields
- FrameDescData *data = (FrameDescData*)ud;
-
- //skip wrappers
- if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) {
- return FALSE;
- }
-
- if (data->cur_frame < data->target_frame) {
- ++data->cur_frame;
- return FALSE;
- }
-
- InterpFrame *frame = (InterpFrame*)info->interp_frame;
- g_assert (frame);
- MonoMethod *method = frame->imethod->method;
- g_assert (method);
gpointer addr = NULL;
if (mono_debug_lookup_method_async_debug_info (method)) {
addr = mini_get_interp_callbacks ()->frame_get_this (frame);
MonoObject *obj = *(MonoObject**)addr;
describe_object_properties(get_object_id(obj), TRUE);
}
- return TRUE;
}
-static gboolean
-describe_this (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud)
+static void
+describe_this (InterpFrame *frame, MonoMethod *method)
{
- //Async methods are special in the way that local variables can be lifted to generated class fields
- FrameDescData *data = (FrameDescData*)ud;
-
- //skip wrappers
- if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) {
- return FALSE;
- }
-
- if (data->cur_frame < data->target_frame) {
- ++data->cur_frame;
- return FALSE;
- }
-
- InterpFrame *frame = (InterpFrame*)info->interp_frame;
- g_assert (frame);
- MonoMethod *method = frame->imethod->method;
- g_assert (method);
gpointer addr = NULL;
if (mono_method_signature_internal (method)->hasthis) {
addr = mini_get_interp_callbacks ()->frame_get_this (frame);
MonoObject *obj = *(MonoObject**)addr;
+ char *class_name = mono_class_full_name (obj->vtable->klass);
+
mono_wasm_add_properties_var("this");
- GString *class_name;
- class_name = g_string_new ("");
- if (*(m_class_get_name_space (obj->vtable->klass))) {
- g_string_append (class_name, m_class_get_name_space (obj->vtable->klass));
- g_string_append_c (class_name, '.');
- }
- g_string_append (class_name, m_class_get_name (obj->vtable->klass));
- mono_wasm_add_obj_var (class_name->str, get_object_id(obj));
- g_string_free(class_name, FALSE);
+ mono_wasm_add_obj_var (class_name, get_object_id(obj));
+ g_free (class_name);
}
- return TRUE;
}
-
static gboolean
-describe_variable (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud)
+describe_variable (InterpFrame *frame, MonoMethod *method, int pos)
{
ERROR_DECL (error);
MonoMethodHeader *header = NULL;
- FrameDescData *data = (FrameDescData*)ud;
-
- //skip wrappers
- if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) {
- return FALSE;
- }
-
- if (data->cur_frame < data->target_frame) {
- ++data->cur_frame;
- return FALSE;
- }
-
- InterpFrame *frame = (InterpFrame*)info->interp_frame;
- g_assert (frame);
- MonoMethod *method = frame->imethod->method;
- g_assert (method);
-
MonoType *type = NULL;
gpointer addr = NULL;
- int pos = data->variable;
if (pos < 0) {
pos = -pos - 1;
type = mono_method_signature_internal (method)->params [pos];
return TRUE;
}
+static gboolean
+describe_variables_on_frame (MonoStackFrameInfo *info, MonoContext *ctx, gpointer ud)
+{
+ FrameDescData *data = (FrameDescData*)ud;
+
+ //skip wrappers
+ if (info->type != FRAME_TYPE_MANAGED && info->type != FRAME_TYPE_INTERP) {
+ return FALSE;
+ }
+
+ if (data->cur_frame < data->target_frame) {
+ ++data->cur_frame;
+ return FALSE;
+ }
+
+ InterpFrame *frame = (InterpFrame*)info->interp_frame;
+ g_assert (frame);
+ MonoMethod *method = frame->imethod->method;
+ g_assert (method);
+
+ for (int i = 0; i < data->len; i++)
+ {
+ describe_variable (frame, method, data->pos[i]);
+ }
+
+ describe_async_method_locals (frame, method);
+ describe_this (frame, method);
+
+ return TRUE;
+}
+
//FIXME this doesn't support getting the return value pseudo-var
EMSCRIPTEN_KEEPALIVE void
mono_wasm_get_var_info (int scope, int* pos, int len)
{
FrameDescData data;
- data.cur_frame = 0;
data.target_frame = scope;
- for (int i = 0; i < len; i++)
- {
- DEBUG_PRINTF (2, "getting var %d of scope %d - %d\n", pos[i], scope, len);
- data.variable = pos[i];
- mono_walk_stack_with_ctx (describe_variable, NULL, MONO_UNWIND_NONE, &data);
- }
- mono_walk_stack_with_ctx (describe_async_method_locals, NULL, MONO_UNWIND_NONE, &data);
- mono_walk_stack_with_ctx (describe_this, NULL, MONO_UNWIND_NONE, &data);
+ data.cur_frame = 0;
+ data.len = len;
+ data.pos = pos;
+
+ mono_walk_stack_with_ctx (describe_variables_on_frame, NULL, MONO_UNWIND_NONE, &data);
}
EMSCRIPTEN_KEEPALIVE void