mirror of https://github.com/m-labs/artiq.git
Implement exception raising.
This commit is contained in:
parent
ef4a06a270
commit
bb5fe60137
|
@ -1,4 +1,4 @@
|
||||||
CC ?= clang
|
CC ?= clang
|
||||||
|
|
||||||
libartiq_personality.so: ../../soc/runtime/artiq_personality.c
|
libartiq_personality.so: ../../soc/runtime/artiq_personality.c artiq_terminate.c
|
||||||
$(CC) -Wall -Werror -I. -fPIC -shared -o $@ $<
|
$(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
|
# REQUIRES: exceptions
|
||||||
|
|
||||||
|
# CHECK-L: Uncaught ZeroDivisionError: cannot divide by zero (0, 0, 0)
|
||||||
|
# CHECK-L: at input.py:${LINE:+1}:0
|
||||||
1/0
|
1/0
|
||||||
|
|
|
@ -9,9 +9,13 @@ config.test_format = lit.formats.ShTest()
|
||||||
config.suffixes = ['.py']
|
config.suffixes = ['.py']
|
||||||
|
|
||||||
python_executable = 'python3'
|
python_executable = 'python3'
|
||||||
|
|
||||||
harness = '{} {}'.format(python_executable, os.path.join(root, 'harness.py'))
|
harness = '{} {}'.format(python_executable, os.path.join(root, 'harness.py'))
|
||||||
config.substitutions.append( ('%python', harness) )
|
config.substitutions.append( ('%python', harness) )
|
||||||
|
|
||||||
|
not_ = '{} {}'.format(python_executable, os.path.join(root, 'not.py'))
|
||||||
|
config.substitutions.append( ('%not', not_) )
|
||||||
|
|
||||||
if os.name == 'posix':
|
if os.name == 'posix':
|
||||||
personality_build = os.path.join(root, 'libartiq_personality')
|
personality_build = os.path.join(root, 'libartiq_personality')
|
||||||
if subprocess.call(['make', '-sC', personality_build]) != 0:
|
if subprocess.call(['make', '-sC', personality_build]) != 0:
|
||||||
|
|
|
@ -1,25 +1,41 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unwind.h>
|
#include <unwind.h>
|
||||||
|
#include "artiq_personality.h"
|
||||||
|
|
||||||
struct artiq_exception {
|
#define ARTIQ_EXCEPTION_CLASS 0x4152545141525451LL // 'ARTQARTQ'
|
||||||
const char *name;
|
|
||||||
const char *file;
|
struct artiq_raised_exception {
|
||||||
int32_t line;
|
struct _Unwind_Exception unwind;
|
||||||
int32_t column;
|
struct artiq_exception artiq;
|
||||||
const char *message;
|
|
||||||
int64_t param[3];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void __artiq_raise(struct artiq_exception *artiq_exn) {
|
static void __artiq_cleanup(_Unwind_Reason_Code reason, struct _Unwind_Exception *exc) {
|
||||||
printf("raised %s\n", artiq_exn->name);
|
struct artiq_raised_exception *inflight = (struct artiq_raised_exception*) exc;
|
||||||
abort();
|
// 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,
|
void __artiq_raise(struct artiq_exception *artiq_exn) {
|
||||||
_Unwind_Action actions, uint64_t exceptionClass,
|
static struct artiq_raised_exception inflight;
|
||||||
struct _Unwind_Exception *exceptionObject,
|
memcpy(&inflight.artiq, artiq_exn, sizeof(struct artiq_exception));
|
||||||
struct _Unwind_Context *context) {
|
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();
|
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