forked from M-Labs/artiq
Implement exception raising.
This commit is contained in:
parent
ef4a06a270
commit
bb5fe60137
|
@ -1,4 +1,4 @@
|
|||
CC ?= clang
|
||||
|
||||
libartiq_personality.so: ../../soc/runtime/artiq_personality.c
|
||||
$(CC) -Wall -Werror -I. -fPIC -shared -o $@ $<
|
||||
libartiq_personality.so: ../../soc/runtime/artiq_personality.c artiq_terminate.c
|
||||
$(CC) -Wall -Werror -I. -I../../soc/runtime -fPIC -shared -o $@ $^
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <unwind.h>
|
||||
#include <artiq_personality.h>
|
||||
|
||||
void __artiq_terminate(struct artiq_exception *exn) {
|
||||
printf("Uncaught %s: %s (%"PRIi64", %"PRIi64", %"PRIi64")\n"
|
||||
"at %s:%"PRIi32":%"PRIi32"",
|
||||
exn->name, exn->message,
|
||||
exn->param[0], exn->param[1], exn->param[1],
|
||||
exn->file, exn->line, exn->column + 1);
|
||||
exit(1);
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
import sys, subprocess
|
||||
exit(not subprocess.call(sys.argv[1:]))
|
|
@ -1,4 +1,6 @@
|
|||
# RUN: %python -m artiq.compiler.testbench.jit %s
|
||||
# RUN: %not %python -m artiq.compiler.testbench.jit %s
|
||||
# REQUIRES: exceptions
|
||||
|
||||
# CHECK-L: Uncaught ZeroDivisionError: cannot divide by zero (0, 0, 0)
|
||||
# CHECK-L: at input.py:${LINE:+1}:0
|
||||
1/0
|
||||
|
|
|
@ -9,9 +9,13 @@ config.test_format = lit.formats.ShTest()
|
|||
config.suffixes = ['.py']
|
||||
|
||||
python_executable = 'python3'
|
||||
|
||||
harness = '{} {}'.format(python_executable, os.path.join(root, 'harness.py'))
|
||||
config.substitutions.append( ('%python', harness) )
|
||||
|
||||
not_ = '{} {}'.format(python_executable, os.path.join(root, 'not.py'))
|
||||
config.substitutions.append( ('%not', not_) )
|
||||
|
||||
if os.name == 'posix':
|
||||
personality_build = os.path.join(root, 'libartiq_personality')
|
||||
if subprocess.call(['make', '-sC', personality_build]) != 0:
|
||||
|
|
|
@ -1,25 +1,41 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unwind.h>
|
||||
#include "artiq_personality.h"
|
||||
|
||||
struct artiq_exception {
|
||||
const char *name;
|
||||
const char *file;
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
const char *message;
|
||||
int64_t param[3];
|
||||
#define ARTIQ_EXCEPTION_CLASS 0x4152545141525451LL // 'ARTQARTQ'
|
||||
|
||||
struct artiq_raised_exception {
|
||||
struct _Unwind_Exception unwind;
|
||||
struct artiq_exception artiq;
|
||||
};
|
||||
|
||||
void __artiq_raise(struct artiq_exception *artiq_exn) {
|
||||
printf("raised %s\n", artiq_exn->name);
|
||||
abort();
|
||||
static void __artiq_cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *exc) {
|
||||
struct artiq_raised_exception *inflight = (struct artiq_raised_exception*) exc;
|
||||
// The in-flight exception is statically allocated, so we don't need to free it.
|
||||
// But, we clear it to mark it as processed.
|
||||
memset(&inflight->artiq, 0, sizeof(struct artiq_exception));
|
||||
}
|
||||
|
||||
_Unwind_Reason_Code __artiq_personality(int version,
|
||||
_Unwind_Action actions, uint64_t exceptionClass,
|
||||
struct _Unwind_Exception *exceptionObject,
|
||||
struct _Unwind_Context *context) {
|
||||
void __artiq_raise(struct artiq_exception *artiq_exn) {
|
||||
static struct artiq_raised_exception inflight;
|
||||
memcpy(&inflight.artiq, artiq_exn, sizeof(struct artiq_exception));
|
||||
inflight.unwind.exception_class = ARTIQ_EXCEPTION_CLASS;
|
||||
inflight.unwind.exception_cleanup = &__artiq_cleanup;
|
||||
|
||||
_Unwind_Reason_Code result = _Unwind_RaiseException(&inflight.unwind);
|
||||
if(result == _URC_END_OF_STACK) {
|
||||
__artiq_terminate(&inflight.artiq);
|
||||
} else {
|
||||
fprintf(stderr, "__artiq_raise: unexpected error (%d)\n", result);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
_Unwind_Reason_Code __artiq_personality(
|
||||
int version, _Unwind_Action actions, uint64_t exceptionClass,
|
||||
struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context) {
|
||||
abort();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef __ARTIQ_PERSONALITY_H
|
||||
#define __ARTIQ_PERSONALITY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct artiq_exception {
|
||||
union {
|
||||
void *typeinfo;
|
||||
const char *name;
|
||||
};
|
||||
const char *file;
|
||||
int32_t line;
|
||||
int32_t column;
|
||||
const char *message;
|
||||
int64_t param[3];
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __artiq_terminate(struct artiq_exception *artiq_exn)
|
||||
__attribute__((noreturn));
|
||||
|
||||
void __artiq_raise(struct artiq_exception *artiq_exn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ARTIQ_PERSONALITY_H */
|
Loading…
Reference in New Issue