@@ -59,23 +59,24 @@ extern "C" {
5959#ifdef IMPL_EXECUTE_LOOP
6060
6161#if AVM_NO_JIT
62- #define SET_ERROR (error_type_atom ) \
63- x_regs[0] = ERROR_ATOM; \
64- x_regs[1] = error_type_atom; \
65- x_regs[2] = stacktrace_create_raw(ctx, mod, pc - code, ERROR_ATOM);
62+ #define SET_ERROR (error_type_atom ) \
63+ ctx->exception_class = ERROR_ATOM; \
64+ ctx->exception_reason = error_type_atom; \
65+ ctx->exception_stacktrace = stacktrace_create_raw(ctx, mod, pc - code, ERROR_ATOM);
6666#elif AVM_NO_EMU
67- #define SET_ERROR (error_type_atom ) \
68- x_regs[0] = ERROR_ATOM; \
69- x_regs[1] = error_type_atom; \
70- x_regs[2] = stacktrace_create_raw(ctx, mod, (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM);
67+ #define SET_ERROR (error_type_atom ) \
68+ ctx->exception_class = ERROR_ATOM; \
69+ ctx->exception_reason = error_type_atom; \
70+ ctx->exception_stacktrace = stacktrace_create_raw(ctx, mod, (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM);
7171#else
72- #define SET_ERROR (error_type_atom ) \
73- x_regs[0] = ERROR_ATOM; \
74- x_regs[1] = error_type_atom; \
75- if (mod->native_code) { \
76- x_regs[2] = stacktrace_create_raw(ctx, mod, (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM); \
77- } else { \
78- x_regs[2] = stacktrace_create_raw(ctx, mod, pc - code, ERROR_ATOM); \
72+ #define SET_ERROR (error_type_atom ) \
73+ ctx->exception_class = ERROR_ATOM; \
74+ ctx->exception_reason = error_type_atom; \
75+ if (mod->native_code) { \
76+ ctx->exception_stacktrace = stacktrace_create_raw(ctx, mod, \
77+ (const uint8_t *) native_pc - (const uint8_t *) mod->native_code, ERROR_ATOM); \
78+ } else { \
79+ ctx->exception_stacktrace = stacktrace_create_raw(ctx, mod, pc - code, ERROR_ATOM); \
7980 }
8081#endif
8182
@@ -1312,7 +1313,7 @@ static void destroy_extended_registers(Context *ctx, unsigned int live)
13121313#endif
13131314
13141315#define HANDLE_ERROR () \
1315- x_regs[2] = stacktrace_create_raw(ctx, mod, pc - code, x_regs[0] ); \
1316+ ctx->exception_stacktrace = stacktrace_create_raw(ctx, mod, pc - code, ctx->exception_class ); \
13161317 goto handle_error;
13171318
13181319#define VERIFY_IS_INTEGER (t , opcode_name , label ) \
@@ -3973,6 +3974,9 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
39733974 #ifdef IMPL_EXECUTE_LOOP
39743975 // clears the catch value on stack
39753976 WRITE_REGISTER (dreg , term_nil ());
3977+ ctx -> x [0 ] = ctx -> exception_class ;
3978+ ctx -> x [1 ] = ctx -> exception_reason ;
3979+ ctx -> x [2 ] = ctx -> exception_stacktrace ;
39763980 #endif
39773981 break ;
39783982 }
@@ -4020,9 +4024,9 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
40204024
40214025 #ifdef IMPL_EXECUTE_LOOP
40224026 TRACE ("raise/2 stacktrace=0x%" TERM_X_FMT " exc_value=0x%" TERM_X_FMT "\n" , stacktrace , exc_value );
4023- x_regs [ 0 ] = stacktrace_exception_class (stacktrace );
4024- x_regs [ 1 ] = exc_value ;
4025- x_regs [ 2 ] = stacktrace_create_raw (ctx , mod , saved_pc - code , x_regs [ 0 ] );
4027+ ctx -> exception_class = stacktrace_exception_class (stacktrace );
4028+ ctx -> exception_reason = exc_value ;
4029+ ctx -> exception_stacktrace = stacktrace_create_raw (ctx , mod , saved_pc - code , ctx -> exception_class );
40264030 goto handle_error ;
40274031 #endif
40284032
@@ -4053,19 +4057,19 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
40534057 #ifdef IMPL_EXECUTE_LOOP
40544058 WRITE_REGISTER (dreg , term_nil ());
40554059 // C.f. https://www.erlang.org/doc/reference_manual/expressions.html#catch-and-throw
4056- switch (term_to_atom_index (x_regs [ 0 ] )) {
4060+ switch (term_to_atom_index (ctx -> exception_class )) {
40574061 case THROW_ATOM_INDEX :
4058- x_regs [0 ] = x_regs [ 1 ] ;
4062+ x_regs [0 ] = ctx -> exception_reason ;
40594063 break ;
40604064
40614065 case ERROR_ATOM_INDEX : {
4062- x_regs [2 ] = stacktrace_build (ctx , & x_regs [ 2 ], 3 );
4066+ x_regs [2 ] = stacktrace_build (ctx );
40634067 // MEMORY_CAN_SHRINK because catch_end is classified as gc in beam_ssa_codegen.erl
40644068 if (UNLIKELY (memory_ensure_free_with_roots (ctx , TUPLE_SIZE (2 ) * 2 , 2 , x_regs + 1 , MEMORY_CAN_SHRINK ) != MEMORY_GC_OK )) {
40654069 RAISE_ERROR (OUT_OF_MEMORY_ATOM );
40664070 }
40674071 term reason_tuple = term_alloc_tuple (2 , & ctx -> heap );
4068- term_put_tuple_element (reason_tuple , 0 , x_regs [ 1 ] );
4072+ term_put_tuple_element (reason_tuple , 0 , ctx -> exception_reason );
40694073 term_put_tuple_element (reason_tuple , 1 , x_regs [2 ]);
40704074 term exit_tuple = term_alloc_tuple (2 , & ctx -> heap );
40714075 term_put_tuple_element (exit_tuple , 0 , EXIT_ATOM );
@@ -4081,7 +4085,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
40814085 }
40824086 term exit_tuple = term_alloc_tuple (2 , & ctx -> heap );
40834087 term_put_tuple_element (exit_tuple , 0 , EXIT_ATOM );
4084- term_put_tuple_element (exit_tuple , 1 , x_regs [ 1 ] );
4088+ term_put_tuple_element (exit_tuple , 1 , ctx -> exception_reason );
40854089 x_regs [0 ] = exit_tuple ;
40864090
40874091 break ;
@@ -6569,9 +6573,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
65696573 TRACE ("build_stacktrace/0\n" );
65706574
65716575 #ifdef IMPL_EXECUTE_LOOP
6572-
6573- x_regs [0 ] = stacktrace_build (ctx , & x_regs [0 ], 1 );
6574-
6576+ x_regs [0 ] = stacktrace_build (ctx );
65756577 #endif
65766578 break ;
65776579 }
@@ -6590,6 +6592,9 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
65906592 ex_class != THROW_ATOM )) {
65916593 x_regs [0 ] = BADARG_ATOM ;
65926594 } else {
6595+ ctx -> exception_class = x_regs [0 ];
6596+ ctx -> exception_reason = x_regs [1 ];
6597+ ctx -> exception_stacktrace = x_regs [2 ];
65936598 goto handle_error ;
65946599 }
65956600 #endif
@@ -7567,15 +7572,15 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
75677572
75687573#ifdef AVM_PRINT_PROCESS_CRASH_DUMPS
75697574 // Do not print crash dump if reason is normal or shutdown.
7570- if (x_regs [ 0 ] != LOWERCASE_EXIT_ATOM || (x_regs [ 1 ] != NORMAL_ATOM && x_regs [ 1 ] != SHUTDOWN_ATOM )) {
7575+ if (ctx -> exception_class != LOWERCASE_EXIT_ATOM || (ctx -> exception_reason != NORMAL_ATOM && ctx -> exception_reason != SHUTDOWN_ATOM )) {
75717576 context_dump (ctx );
75727577 }
75737578#endif
75747579
7575- if (x_regs [ 0 ] == LOWERCASE_EXIT_ATOM ) {
7576- ctx -> exit_reason = x_regs [ 1 ] ;
7580+ if (ctx -> exception_class == LOWERCASE_EXIT_ATOM ) {
7581+ ctx -> exit_reason = ctx -> exception_reason ;
75777582 } else {
7578- bool throw = ctx -> x [ 0 ] == THROW_ATOM ;
7583+ bool throw = ctx -> exception_class == THROW_ATOM ;
75797584
75807585 int exit_reason_tuple_size = (throw ? TUPLE_SIZE (2 ) : 0 ) + TUPLE_SIZE (2 );
75817586 if (memory_ensure_free_with_roots (ctx , exit_reason_tuple_size , 1 , x_regs + 1 , MEMORY_CAN_SHRINK ) != MEMORY_GC_OK ) {
@@ -7585,10 +7590,10 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb)
75857590 if (throw ) {
75867591 error_term = term_alloc_tuple (2 , & ctx -> heap );
75877592 term_put_tuple_element (error_term , 0 , NOCATCH_ATOM );
7588- term_put_tuple_element (error_term , 1 , x_regs [ 1 ] );
7593+ term_put_tuple_element (error_term , 1 , ctx -> exception_reason );
75897594 } else {
75907595 // error
7591- error_term = x_regs [ 1 ] ;
7596+ error_term = ctx -> exception_reason ;
75927597 }
75937598
75947599 term exit_reason_tuple = term_alloc_tuple (2 , & ctx -> heap );
0 commit comments