diff --git a/pixie/ffi-infer.pxi b/pixie/ffi-infer.pxi index b2db256b..5e3b086f 100644 --- a/pixie/ffi-infer.pxi +++ b/pixie/ffi-infer.pxi @@ -98,7 +98,8 @@ return 0; (defmethod edn-to-ctype :pointer [{:keys [of-type] :as ptr} in-struct?] (cond - (and (= of-type {:signed? true :size 1 :type :int}) + (and (= (:size of-type) 1) + (= (:type of-type) :int) (not in-struct?)) 'pixie.stdlib/CCharP (= (:type of-type) :function) (callback-type of-type in-struct?) :else 'pixie.stdlib/CVoidP)) diff --git a/pixie/vm/libs/ffi.py b/pixie/vm/libs/ffi.py index 1a30a535..0d346472 100644 --- a/pixie/vm/libs/ffi.py +++ b/pixie/vm/libs/ffi.py @@ -394,8 +394,9 @@ def ffi_set_value(self, ptr, val): vpnt = rffi.cast(rffi.VOIDPP, ptr) vpnt[0] = rffi.cast(rffi.VOIDP, val.raw_data()) else: - print val - affirm(False, u"Cannot encode this type") + frm_name = rt.name(rt.str(val.type())) + to_name = rt.name(rt.str(self)) + affirm(False, u"Cannot encode " + frm_name + u" as " + to_name) def ffi_size(self): @@ -445,7 +446,13 @@ def ffi_get_value(self, ptr): def ffi_set_value(self, ptr, val): pnt = rffi.cast(rffi.VOIDPP, ptr) - if isinstance(val, Buffer): + if isinstance(val, String): + pnt = rffi.cast(rffi.CCHARPP, ptr) + utf8 = unicode_to_utf8(rt.name(val)) + raw = rffi.str2charp(utf8) + pnt[0] = raw + return CCharPToken(raw) + elif isinstance(val, Buffer): pnt[0] = val.buffer() elif isinstance(val, VoidP): pnt[0] = val.raw_data() @@ -454,8 +461,10 @@ def ffi_set_value(self, ptr, val): elif isinstance(val, CStruct): pnt[0] = rffi.cast(rffi.VOIDP, val.raw_data()) else: - print val - affirm(False, u"Cannot encode this type") + frm_name = rt.name(rt.str(val.type())) + to_name = rt.name(rt.str(self)) + affirm(False, u"Cannot encode " + frm_name + u" as " + to_name) + def ffi_size(self): return rffi.sizeof(rffi.VOIDP) diff --git a/pixie/vm/object.py b/pixie/vm/object.py index 2abf674e..32bdd199 100644 --- a/pixie/vm/object.py +++ b/pixie/vm/object.py @@ -151,6 +151,16 @@ def runtime_error(msg): import pixie.vm.rt as rt raise WrappedException(RuntimeException(rt.wrap(msg))) +def safe_invoke(f, args): + try: + f.invoke(args) + except Exception as ex: + if isinstance(ex, WrappedException): + print "UNSAFE EXCEPTION", ex._ex.__repr__() + else: + print "UNSAFE EXCEPTION", ex + return None + class ErrorInfo(Object): _type = Type(u"pixie.stdlib.ErrorInfo") def type(self): diff --git a/pixie/vm/threads.py b/pixie/vm/threads.py index d34b47b8..5140608b 100644 --- a/pixie/vm/threads.py +++ b/pixie/vm/threads.py @@ -1,4 +1,4 @@ -from pixie.vm.object import Object, Type +from pixie.vm.object import Object, Type, safe_invoke from pixie.vm.primitives import true import rpython.rlib.rthread as rthread from pixie.vm.primitives import nil @@ -42,7 +42,7 @@ def bootstrap(): rthread.gc_thread_start() fn = bootstrapper.fn() bootstrapper.release() - fn.invoke([]) + safe_invoke(fn, []) rthread.gc_thread_die() bootstrapper = Bootstrapper()