From 7aceeae8759eedc9085a2a5919668e6c38445424 Mon Sep 17 00:00:00 2001 From: Rico Wind Date: Tue, 18 Aug 2015 13:43:50 +0200 Subject: [PATCH] support structs --- Lib/dart/dart.swg | 25 ++---- Source/Modules/dart.cxx | 194 ++++++++++++++++++++++++++++++++++------ 2 files changed, 174 insertions(+), 45 deletions(-) diff --git a/Lib/dart/dart.swg b/Lib/dart/dart.swg index 3d0fd25b2b3..0a2bc099561 100644 --- a/Lib/dart/dart.swg +++ b/Lib/dart/dart.swg @@ -10,27 +10,10 @@ %typemap(darttype) void "void"; %insert(dart_head) %{ -// This is generated code, only touch this if you know what you are\n" -// doing +// This is generated code, only touch this if you know what you are\n +// doing. import 'dart:fletch.ffi'; - -class __FFIWrapper__ { - Map foreignFunctions = - new Map(); - ForeignLibrary library; - - __FFIWrapper__(String libraryFile) { - Uri uri = Uri.base.resolve(libraryFile); - library = new ForeignLibrary.fromName(uri.path); - } - - // TODO(ricow): add support for different signatures for the same name (for - // c++) - ForeignFunction getFunction(String name) => - foreignFunctions.putIfAbsent(name, () => library.lookup(name)); - -} %} %insert(dart_end) %{ @@ -39,6 +22,10 @@ void main() { print("Calling setup: ${setup()}"); print("Calling SetCount(42, 42): ${SetCount(42, 42)}"); print("Calling GetCount: ${GetCount()}"); + var mynode = new node(42, 42.42); + print("node first val: ${mynode.ivalue}"); + print("node first val: ${mynode.dvalue}"); + print("Calling get_i_value: ${get_i_value(mynode)}"); } %} diff --git a/Source/Modules/dart.cxx b/Source/Modules/dart.cxx index 2ccc9bf5d20..3541523acc9 100644 --- a/Source/Modules/dart.cxx +++ b/Source/Modules/dart.cxx @@ -23,8 +23,8 @@ class DART:public Language { // Users can pass in the location of the library file (normally .so on // linux, .dylib on mac. By default we assume that the library file is - // named the same as the module and placed - String libary_file; + // named the same as the module. + String *library_file; public: DART(): @@ -36,24 +36,32 @@ class DART:public Language { * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { + Printf(stdout, "start running\n\n"); + for (int i = 1; i < argc; i++) { - if (argv[i] && strcmp(argv[i],"-library_file") == 0) { - printf("Arg %d: %s\n", i, argv[i]); - Swig_mark_arg(i); + if (argv[i] && strcmp(argv[i], "-soname") == 0) { + if (argv[i + 1]) { + library_file = NewString(argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } } } - /* Set language-specific subdirectory in SWIG library */ - SWIG_library_directory("dart"); + /* Set language-specific subdirectory in SWIG library */ + SWIG_library_directory("dart"); - /* Set language-specific preprocessing symbol */ - Preprocessor_define("SWIGDART 1", 0); + /* Set language-specific preprocessing symbol */ + Preprocessor_define("SWIGDART 1", 0); - /* Set language-specific configuration file */ - SWIG_config_file("dart.swg"); + /* Set language-specific configuration file */ + SWIG_config_file("dart.swg"); - /* Set typemap language (historical) */ - SWIG_typemap_lang("dart"); + /* Set typemap language (historical) */ + SWIG_typemap_lang("dart"); } @@ -74,9 +82,19 @@ class DART:public Language { } void emit_library_load(Node *n) { - String *module = Getattr(n, "name"); + String *module; + if (library_file) { + module = library_file; + } else { + module = NewString(""); + Printf(module, "%s.so", Getattr(n, "name")); + } + Printf(f_dart_body, + "final Uri __$uri__ = Uri.base.resolve('%s');\n", + module); + Printf(f_dart_body, - "__FFIWrapper__ __wrapper__ = new __FFIWrapper__('%s.so');\n\n", + "final __$library__ = new ForeignLibrary.fromName(__$uri__.path);\n\n", module); } @@ -131,14 +149,124 @@ class DART:public Language { return SWIG_OK; } - virtual int functionWrapper(Node *n) { - if (!Strcmp(nodeType(n), "cdecl") == 0) return SWIG_OK; + int getSize(String *type) { + // TODO(ricow): refactor + if (Strcmp(type, "double") == 0) { + return 8; + } else if (Strcmp(type, "int") == 0) { + return 4; + } else { + Printf(stderr, "Don't know size of %s\n", type); + SWIG_exit(EXIT_FAILURE); + return 0; + } + } + + String *getFFIGetter(String *type) { + // TODO(ricow): refactor + if (Strcmp(type, "double") == 0) { + return NewString("getFloat64"); + } else if (Strcmp(type, "int") == 0) { + return NewString("getInt32"); + } else { + Printf(stderr, "Don't know size of %s\n", type); + SWIG_exit(EXIT_FAILURE); + return 0; + + } + } + + String *getFFISetter(String *type) { + // TODO(ricow): refactor + if (Strcmp(type, "double") == 0) { + return NewString("setFloat64"); + } else if (Strcmp(type, "int") == 0) { + return NewString("setInt32"); + } else { + Printf(stderr, "Don't know size of %s\n", type); + SWIG_exit(EXIT_FAILURE); + return 0; + + } + } + + /* We explicitly catch this to not have the class expanded into constructors + All we really need is to know the type and name of the members + */ + virtual int classDeclaration(Node *n) { + // STRUCTS ONLY FOR NOW + String *name = Getattr(n, "name"); + + Printf(stdout, "Calling classDeclaration %s\n", nodeType(n)); + Printf(f_dart_body, "class %s {\n", name); + Printf(f_dart_body, " ForeignMemory __$fmem__;\n"); + + Node *c; + String *constructor_parameters = NewString(""); + String *constructor_initializers = NewString(""); + int struct_size = 0; + for (c = firstChild(n); c; c = nextSibling(c)) { + Printf(stdout, " Sibling %s\n", nodeType(c)); + String *variable_type = Getattr(c, "type"); + String *variable_name = Getattr(c, "name"); + Printf(f_dart_body, " %s get %s => ", variable_type, variable_name); + Printf(f_dart_body, "__$fmem__.%s(%d);\n", getFFIGetter(variable_type), + struct_size); + Printf(f_dart_body, " set %s(%s val) => ", variable_name, variable_type); + Printf(f_dart_body, "__$fmem__.%s(%d, val);\n", + getFFISetter(variable_type), + struct_size); + Printf(constructor_initializers, " __$fmem__.%s(%d, %s);\n", + getFFISetter(variable_type), + struct_size, + variable_name); + + if (struct_size == 0) { + Printf(constructor_parameters, "%s %s", variable_type, variable_name); + } else { + Printf(constructor_parameters, ", %s %s", variable_type, variable_name); + } + + struct_size += getSize(variable_type); + } + Printf(f_dart_body, " %s(%s) {\n", name, constructor_parameters); + Printf(f_dart_body, " __$fmem__ = new ForeignMemory.allocated(%d);\n", + struct_size); + Printf(f_dart_body, "%s\n", + constructor_initializers); + + Printf(f_dart_body, " }\n"); + Printf(f_dart_body, "}\n\n"); + return SWIG_OK; + } + + + virtual int constantWrapper(Node *n) { + Printf(stdout, "Calling constantWrapper %s\n", nodeType(n)); + return SWIG_OK; + } + virtual int variableWrapper(Node *n) { + Printf(stdout, "Calling variableWrapper %s\n", nodeType(n)); + Printf(stdout, "Name %s\n", Getattr(n, "name")); + return SWIG_OK; + } + virtual int nativeWrapper(Node *n) { + Printf(stdout, "Calling nativeWrapper %s\n", nodeType(n)); + return SWIG_OK; + } - String *view = Getattr(n, "view"); - Printf(stdout, "View: %s\n", view); + virtual int classDirector(Node *n) { + Printf(stdout, "Calling classDirector %s\n", nodeType(n)); + return SWIG_OK; + } + + virtual int functionWrapper(Node *n) { + if (!Strcmp(nodeType(n), "cdecl") == 0) { + Printf(stdout, "Not handling: %s\n", nodeType(n)); + return SWIG_OK; + } String *kind = Getattr(n, "kind"); - Printf(stdout, "Kind: %s\n", kind); // Currently no support for variables. if (Strcmp(kind, "variable") == 0) return SWIG_OK; @@ -147,29 +275,43 @@ class DART:public Language { ParmList *pl = Getattr(n, "parms"); Parm *p; String *raw_return_type = Swig_typemap_lookup("darttype", n, "", 0); + // Create lazy initialized function lookup + Printf(f_dart_body, "final __$%s__ = __$library__.lookup('%s');\n", + funcname, funcname); + Printf(f_dart_body, "%s ", raw_return_type); int argnum = 0; Printf(f_dart_body, "%s(", funcname); String *arguments = NewString(""); for (p = pl; p; p = nextSibling(p), argnum++) { String *arg_type = Swig_typemap_lookup("darttype", p, "", 0); + Swig_print(p); String *name = Getattr(p,"name"); if (argnum > 0) Printf(f_dart_body, ", "); Printf(f_dart_body, "%s %s", arg_type, name); // We later pass these on to the icall if (argnum > 0) Printf(arguments, ", "); - Printf(arguments, "%s", name); + + // If there was no arg type we assume that this is a wrapped foreign + // memory. + if (!arg_type) { + Printf(arguments, "%s.__$fmem__", name); + } else { + Printf(arguments, "%s", name); + } + } Printf(f_dart_body, ") {\n"); if (Strcmp(raw_return_type, "int") == 0) { - Printf(f_dart_body, - " ForeignFunction f = __wrapper__.getFunction('%s');\n", - funcname); - Printf(f_dart_body, " return f.icall$%d(%s);\n", argnum, arguments); + // Printf(f_dart_body, + // " ForeignFunction f = __$wrapper__.getFunction('%s');\n", + // funcname); + Printf(f_dart_body, " return __$%s__.icall$%d(%s);\n", + funcname, argnum, arguments); } - Printf(f_dart_body, "}\n"); + Printf(f_dart_body, "}\n\n"); // String *name = Getattr(, "name"); // String *iname = Getattr(n,"sym:name"); // SwigType *type = Getattr(n,"type");