Преглед на файлове

[cpp] Add calling convention to function pointers

Hugh преди 10 години
родител
ревизия
05f10acb2e
променени са 13 файла, в които са добавени 54 реда и са изтрити 18 реда
  1. 1 0
      ast.ml
  2. 1 0
      common.ml
  3. 12 6
      gencpp.ml
  4. 5 0
      std/cpp/Callable.hx
  5. 8 9
      std/cpp/Function.hx
  6. 2 2
      std/cpp/Lib.hx
  7. 4 0
      std/cpp/abi/Abi.hx
  8. 4 0
      std/cpp/abi/CDecl.hx
  9. 4 0
      std/cpp/abi/FastCall.hx
  10. 4 0
      std/cpp/abi/StdCall.hx
  11. 4 0
      std/cpp/abi/ThisCall.hx
  12. 4 0
      std/cpp/abi/Winapi.hx
  13. 1 1
      std/cpp/vm/Gc.hx

+ 1 - 0
ast.ml

@@ -30,6 +30,7 @@ module IntMap = Map.Make(struct type t = int let compare a b = a - b end)
 
 module Meta = struct
 	type strict_meta =
+		| Abi
 		| Abstract
 		| Access
 		| Accessor

+ 1 - 0
common.ml

@@ -358,6 +358,7 @@ module MetaInfo = struct
 		| Internal
 
 	let to_string = function
+		| Abi -> ":abi",("Function ABI/calling convention",[Platforms [Cpp]])
 		| Abstract -> ":abstract",("Sets the underlying class implementation as 'abstract'",[Platforms [Java;Cs]])
 		| Access -> ":access",("Forces private access to package, type or field",[HasParam "Target path";UsedOnEither [TClass;TClassField]])
 		| Accessor -> ":accessor",("Used internally by DCE to mark property accessors",[UsedOn TClassField;Internal])

+ 12 - 6
gencpp.ml

@@ -664,7 +664,8 @@ and type_string_suff suffix haxe_type remap =
          (match params with
          | [t] -> "const " ^ (type_string (follow t) ) ^ " *"
          | _ -> assert false)
-      | ["cpp"] , "Function" -> "::cpp::Function< " ^ (cpp_function_signature_params params) ^ " >"
+      | ["cpp"] , "Function" ->
+         "::cpp::Function< " ^ (cpp_function_signature_params params ) ^ " >"
       | _ ->  type_string_suff suffix (apply_params type_def.t_params params type_def.t_type) remap
       )
    | TFun (args,haxe_type) -> "Dynamic" ^ suffix
@@ -708,14 +709,19 @@ and is_dynamic_array_param haxe_type =
          )
    | _ -> false
    )
-and cpp_function_signature tfun =
+and cpp_function_signature tfun abi =
    match follow tfun with
-   | TFun(args,ret) -> (type_string ret) ^ "(" ^ (gen_tfun_interface_arg_list args) ^ ")"
+   | TFun(args,ret) -> (type_string ret) ^ " " ^ abi ^ "( " ^ (gen_tfun_interface_arg_list args) ^ ")"
    | _ -> "void *"
 
 and cpp_function_signature_params params = match params with
-   | [t] -> cpp_function_signature t
-   | _ ->  assert false;
+   | [t; abi] -> (match follow abi with
+       | TInst (klass,_) -> cpp_function_signature t (get_meta_string klass.cl_meta Meta.Abi)
+       | _ -> print_endline (type_string abi);
+           assert false )
+   | _ -> 
+      print_endline ("Params:" ^ (String.concat "," (List.map type_string params) ));
+      assert false;
 
 and gen_interface_arg_type_name name opt typ =
    let type_str = (type_string typ) in
@@ -1954,7 +1960,7 @@ and gen_expression ctx retval expression =
    | TCall (func, arg_list) when is_fromStaticFunction_call func ->
       (match arg_list with
          | [ {eexpr = TField( _, FStatic(klass,field)) } ] ->
-            let signature = cpp_function_signature field.cf_type in
+            let signature = cpp_function_signature field.cf_type "" in
             let name = keyword_remap field.cf_name in
             let void_cast = has_meta_key field.cf_meta Meta.Void in
             output ("::cpp::Function<" ^ signature ^">(");

+ 5 - 0
std/cpp/Callable.hx

@@ -0,0 +1,5 @@
+package cpp;
+
+typedef Callable<T> = Function<T, cpp.abi.Abi >
+
+

+ 8 - 9
std/cpp/Function.hx

@@ -2,22 +2,21 @@ package cpp;
 
 @:coreType @:structAccess @:include("cpp/Pointer.h")
 @:analyzer(no_simplification)
-extern class Function<T>
+extern class Function<T,ABI:cpp.abi.Abi>
 {
    public function new(d:Dynamic);
 
    // Actually a function pointer, but can be called using haxe notation
 	public var call(default,null):T;
 
-   public static function getProcAddress<T>(inModule:String, inFunction:String) : Function<T>;
-   public static function fromStaticFunction<T>(inStaticFunction:T) : Function<T>;
-
-	public function lt(inOther:Function<T>):Bool;
-	public function leq(inOther:Function<T>):Bool;
-	public function gt(inOther:Function<T>):Bool;
-	public function geq(inOther:Function<T>):Bool;
-
+   public static function getProcAddress<T,ABI:cpp.abi.Abi>(inModule:String, inFunction:String) : Function<T,ABI>;
+   public static function fromStaticFunction<T>(inStaticFunction:T) : Callable<T>;
 
+	public function lt(inOther:Function<T,ABI>):Bool;
+	public function leq(inOther:Function<T,ABI>):Bool;
+	public function gt(inOther:Function<T,ABI>):Bool;
+	public function geq(inOther:Function<T,ABI>):Bool;
 }
 
 
+

+ 2 - 2
std/cpp/Lib.hx

@@ -52,7 +52,7 @@ class Lib {
 
    @:analyzer(no_simplification)
 	public static function _loadPrime( lib : String, prim : String, signature : String, quietFail = false ) : Dynamic {
-		var factory:Function< RawConstPointer<Char> -> RawPointer<Object> > =
+		var factory:Callable< RawConstPointer<Char> -> RawPointer<Object> > =
                untyped __global__.__hxcpp_cast_get_proc_address(lib, prim + "__prime", quietFail);
       if (factory!=null)
       {
@@ -167,7 +167,7 @@ class Lib {
       var typeString = parts.length==1 ? "Void" : codeToType(parts.shift());
       for(p in parts)
          typeString += "->" + codeToType(p);
-      typeString = "cpp.Function<" + typeString + ">";
+      typeString = "cpp.Callable<" + typeString + ">";
       var expr = 'new $typeString(cpp.Lib._loadPrime("$inModule","$inName","$inSig",$inAllowFail))';
       return Context.parse( expr, Context.currentPos() );
    }

+ 4 - 0
std/cpp/abi/Abi.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+// Base case, for calling conventions - means "use default"
+extern class Abi { }

+ 4 - 0
std/cpp/abi/CDecl.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+@:abi("__cdecl")
+extern class CDecl extends Abi { }

+ 4 - 0
std/cpp/abi/FastCall.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+@:abi("__fastcall")
+extern class FastCall extends Abi { }

+ 4 - 0
std/cpp/abi/StdCall.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+@:abi("__stdcall")
+extern class StdCall extends Abi { }

+ 4 - 0
std/cpp/abi/ThisCall.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+@:abi("__thiscall")
+extern class ThisCall extends Abi { }

+ 4 - 0
std/cpp/abi/Winapi.hx

@@ -0,0 +1,4 @@
+package cpp.abi;
+
+@:abi("__stdcall")
+extern class Winapi extends Abi { }

+ 1 - 1
std/cpp/vm/Gc.hx

@@ -93,7 +93,7 @@ class Gc
    }
 
    @:unreflective
-   inline static public function setFinalizer<T>(inObject:T, inFinalizer:cpp.Function<T->Void> ) : Void
+   inline static public function setFinalizer<T>(inObject:T, inFinalizer:cpp.Callable<T->Void> ) : Void
    {
       untyped __global__.__hxcpp_set_finalizer(inObject, inFinalizer);
    }