+typedef struct {
+ gboolean in_interp;
+ MonoInterpStackIter interp_iter;
+} Unwinder;
+
+static void
+unwinder_init (Unwinder *unwinder)
+{
+ memset (unwinder, 0, sizeof (Unwinder));
+}
+
+static gboolean
+unwinder_unwind_frame (Unwinder *unwinder,
+ MonoDomain *domain, MonoJitTlsData *jit_tls,
+ MonoJitInfo *prev_ji, MonoContext *ctx,
+ MonoContext *new_ctx, char **trace, MonoLMF **lmf,
+ mgreg_t **save_locations,
+ StackFrameInfo *frame)
+{
+ if (unwinder->in_interp) {
+ unwinder->in_interp = mono_interp_frame_iter_next (&unwinder->interp_iter, frame);
+ if (!unwinder->in_interp) {
+ return unwinder_unwind_frame (unwinder, domain, jit_tls, prev_ji, ctx, new_ctx, trace, lmf, save_locations, frame);
+ }
+ return TRUE;
+ } else {
+ gboolean res = mono_find_jit_info_ext (domain, jit_tls, prev_ji, ctx, new_ctx, trace, lmf,
+ save_locations, frame);
+ if (!res)
+ return FALSE;
+ if (frame->type == FRAME_TYPE_INTERP_TO_MANAGED) {
+ unwinder->in_interp = TRUE;
+ mono_interp_frame_iter_init (&unwinder->interp_iter, frame->interp_exit_data);
+ }
+ return TRUE;
+ }
+}
+