diff options
author | William S Fulton <wsf@fultondesigns.co.uk> | 2015-10-11 22:11:09 +0100 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2015-10-11 22:11:09 +0100 |
commit | 3d681571e1e9726510c35cbbd2e0342d010ec09a (patch) | |
tree | 167b35a5d83020c44e9910f3a67474bb8573635f | |
parent | 593c452c37e56ff2c96096711d88fb809bfb28ad (diff) | |
parent | 8275f8158a04351c225a3cdad3787646391fe72a (diff) | |
download | swig-3d681571e1e9726510c35cbbd2e0342d010ec09a.tar.gz |
Merge pull request #498 from lyze/extend-cffi-typemap-machinery
Implement argout, freearg, and check for CFFI.
-rw-r--r-- | Source/Modules/cffi.cxx | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx index 39a1ac763..174bc123c 100644 --- a/Source/Modules/cffi.cxx +++ b/Source/Modules/cffi.cxx @@ -61,6 +61,11 @@ public: virtual int classHandler(Node *n); private: + static void checkConstraints(ParmList *parms, Wrapper *f); + static void argout(ParmList *parms, Wrapper *f); + static String *freearg(ParmList *parms); + static void cleanupFunction(Node *n, Wrapper *f, ParmList *parms); + void emit_defun(Node *n, String *name); void emit_defmethod(Node *n); void emit_initialize_instance(Node *n); @@ -364,6 +369,77 @@ int CFFI::membervariableHandler(Node *n) { return Language::membervariableHandler(n); } + +void CFFI::checkConstraints(ParmList *parms, Wrapper *f) { + Parm *p = parms; + while (p) { + String *tm = Getattr(p, "tmap:check"); + if (!tm) { + p = nextSibling(p); + } else { + tm = Copy(tm); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(f->code, tm, "\n\n", NULL); + Delete(tm); + p = Getattr(p, "tmap:check:next"); + } + } +} + +void CFFI::argout(ParmList *parms, Wrapper *f) { + Parm *p = parms; + while (p) { + String *tm = Getattr(p, "tmap:argout"); + if (!tm) { + p = nextSibling(p); + } else { + tm = Copy(tm); + Replaceall(tm, "$result", Swig_cresult_name()); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(f->code, tm, "\n", NULL); + Delete(tm); + p = Getattr(p, "tmap:argout:next"); + } + } +} + +String *CFFI::freearg(ParmList *parms) { + String *ret = NewString(""); + Parm *p = parms; + while (p) { + String *tm = Getattr(p, "tmap:freearg"); + if (!tm) { + p = nextSibling(p); + } else { + tm = Copy(tm); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(ret, tm, "\n", NULL); + Delete(tm); + p = Getattr(p, "tmap:freearg:next"); + } + } + return ret; +} + +void CFFI::cleanupFunction(Node *n, Wrapper *f, ParmList *parms) { + String *cleanup = freearg(parms); + Printv(f->code, cleanup, NULL); + + if (GetFlag(n, "feature:new")) { + String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); + if (tm) { + Replaceall(tm, "$source", Swig_cresult_name()); + Printv(f->code, tm, "\n", NULL); + Delete(tm); + } + } + + Replaceall(f->code, "$cleanup", cleanup); + Delete(cleanup); + + Replaceall(f->code, "$symname", Getattr(n, "sym:name")); +} + int CFFI::functionWrapper(Node *n) { ParmList *parms = Getattr(n, "parms"); @@ -451,6 +527,9 @@ int CFFI::functionWrapper(Node *n) { // Emit the function definition String *signature = SwigType_str(return_type, name_and_parms); Printf(f->def, "EXPORT %s {", signature); + + checkConstraints(parms, f); + Printf(f->code, " try {\n"); String *actioncode = emit_action(n); @@ -459,9 +538,17 @@ int CFFI::functionWrapper(Node *n) { if (result_convert) { Replaceall(result_convert, "$result", "lresult"); Printf(f->code, "%s\n", result_convert); - if(!is_void_return) Printf(f->code, " return lresult;\n"); - Delete(result_convert); } + Delete(result_convert); + + argout(parms, f); + + cleanupFunction(n, f, parms); + + if (!is_void_return) { + Printf(f->code, " return lresult;\n"); + } + emit_return_variable(n, Getattr(n, "type"), f); Printf(f->code, " } catch (...) {\n"); |