]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
ARM: Catch C++ exceptions in interpreter frames.
authorMike Pall <mike>
Wed, 1 Jun 2011 23:21:32 +0000 (01:21 +0200)
committerMike Pall <mike>
Wed, 1 Jun 2011 23:21:32 +0000 (01:21 +0200)
src/buildvm_asm.c
src/lj_err.c

index 6468912ce340c84ad7c137c29eda970a2249a530..35f413b9cef7f946556bd45f3201dd00fb961c11 100644 (file)
@@ -191,6 +191,14 @@ void emit_asm(BuildCtx *ctx)
   if (ctx->mode != BUILD_machasm)
     fprintf(ctx->fp, ".Lbegin:\n");
 
+#if LJ_TARGET_ARM && defined(__GNUC__)
+  /* This should really be moved into buildvm_arm.dasc. */
+  fprintf(ctx->fp,
+         ".fnstart\n"
+         ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
+         ".pad #28\n");
+#endif
+
   for (i = rel = 0; i < ctx->nsym; i++) {
     int32_t ofs = ctx->sym[i].ofs;
     int32_t next = ctx->sym[i+1].ofs;
@@ -219,6 +227,13 @@ void emit_asm(BuildCtx *ctx)
 #endif
   }
 
+#if LJ_TARGET_ARM && defined(__GNUC__)
+  fprintf(ctx->fp,
+         ".globl lj_err_unwind_arm\n"
+         ".personality lj_err_unwind_arm\n"
+         ".fnend\n");
+#endif
+
   fprintf(ctx->fp, "\n");
   switch (ctx->mode) {
   case BUILD_elfasm:
index d1d326e96ab56f511b006664b88291d0ce18bac7..11f0922fab0b7bde9ef6bf37d8e3721c2fdfbca2 100644 (file)
@@ -531,7 +531,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
 
 /* -- External frame unwinding -------------------------------------------- */
 
-#if defined(__GNUC__) && !LJ_TARGET_ARM
+#if defined(__GNUC__)
 
 #ifdef __clang__
 /* http://llvm.org/bugs/show_bug.cgi?id=8703 */
@@ -545,6 +545,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
 #define LJ_UEXCLASS_CHECK(cl)  (((cl) ^ LJ_UEXCLASS) <= 0xff)
 #define LJ_UEXCLASS_ERRCODE(cl)        ((int)((cl) & 0xff))
 
+#if !LJ_TARGET_ARM
+
 /* DWARF2 personality handler referenced from interpreter .eh_frame. */
 LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions,
   _Unwind_Exception_Class uexclass, struct _Unwind_Exception *uex,
@@ -618,6 +620,33 @@ static void err_raise_ext(int errcode)
 }
 #endif
 
+#else
+
+/* ARM unwinder personality handler referenced from interpreter .ARM.extab. */
+LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state,
+                                              _Unwind_Control_Block *ucb,
+                                              _Unwind_Context *ctx)
+{
+  void *cf = (void *)_Unwind_GetGR(ctx, 13);
+  lua_State *L = cframe_L(cf);
+  if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) {
+    setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP));
+    return _URC_HANDLER_FOUND;
+  }
+  if ((state & _US_ACTION_MASK) == _US_UNWIND_FRAME_STARTING) {
+    _Unwind_DeleteException(ucb);
+    _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw);
+    _Unwind_SetGR(ctx, 0, (_Unwind_Word)L);
+    _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN);
+    return _URC_INSTALL_CONTEXT;
+  }
+  if (__gnu_unwind_frame(ucb, ctx) != _URC_OK)
+    return _URC_FAILURE;
+  return _URC_CONTINUE_UNWIND;
+}
+
+#endif
+
 #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS
 
 /*