Explorar o código

[cpp] Add some c++ stdlib externs. Add Pointer setRaw and elementSize externs. Add c++ sizeof feature

Hugh %!s(int64=9) %!d(string=hai) anos
pai
achega
be54ac49b9
Modificáronse 4 ficheiros con 72 adicións e 2 borrados
  1. 32 2
      src/generators/gencpp.ml
  2. 3 0
      std/cpp/ConstPointer.hx
  3. 2 0
      std/cpp/Pointer.hx
  4. 35 0
      std/cpp/Stdlib.hx

+ 32 - 2
src/generators/gencpp.ml

@@ -587,12 +587,14 @@ let is_objc_type t = match follow t with
   | _ -> false
 ;;
 
-let is_addressOf_call func =
+
+let is_sizeof_call func =
    match (remove_parens func).eexpr with
-   | TField (_,FStatic ({cl_path=["cpp"],"Pointer"},{cf_name="addressOf"} ) ) -> true
+   | TField (_,FStatic ({cl_path=["cpp"],"Stdlib"},{cf_name="sizeof"} ) ) -> true
    | _ -> false
 ;;
 
+
 let is_lvalue var =
    match (remove_parens var).eexpr with
    | TLocal _ -> true
@@ -1383,6 +1385,7 @@ and tcppfuncloc =
    | FuncInternal of tcppexpr * string * string
    | FuncGlobal of string
    | FuncFromStaticFunction
+   | FuncSizeof
 
 and tcpparrayloc =
    | ArrayTyped of tcppexpr * tcppexpr
@@ -1418,6 +1421,7 @@ and tcpp_expr_expr =
    | CppEnumField of tenum * tenum_field
    | CppCall of tcppfuncloc * tcppexpr list
    | CppFunctionAddress of tclass * tclass_field
+   | CppSizeof of path * bool
    | CppArray of tcpparrayloc
    | CppCrement of  tcppcrementop * Ast.unop_flag * tcpplvalue
    | CppSet of tcpplvalue * tcppexpr
@@ -1488,8 +1492,10 @@ let rec s_tcpp = function
    | CppCall (FuncInternal _,_) -> "CppCallInternal"
    | CppCall (FuncGlobal _,_) -> "CppCallGlobal"
    | CppCall (FuncFromStaticFunction,_) -> "CppCallFromStaticFunction"
+   | CppCall (FuncSizeof,_) -> "CppCallSizeof"
 
    | CppFunctionAddress  _ -> "CppFunctionAddress"
+   | CppSizeof  _ -> "CppSizeof"
    | CppArray  _ -> "CppArray"
    | CppCrement  _ -> "CppCrement"
    | CppSet  _ -> "CppSet"
@@ -2179,6 +2185,11 @@ let retype_expression ctx request_type function_args expression_tree forInjectio
                let exprType = cpp_type_of member.cf_type in
                CppFunction( FuncFromStaticFunction, funcReturn ), exprType
 
+            | FStatic ( {cl_path=(["cpp"],"Stdlib")}, ({cf_name="sizeof"} as member) ) ->
+               let funcReturn = cpp_member_return_type ctx member in
+               let exprType = cpp_type_of member.cf_type in
+               CppFunction( FuncSizeof, funcReturn ), exprType
+
             | FStatic (clazz,member) ->
                let funcReturn = cpp_member_return_type ctx member in
                let exprType = cpp_type_of member.cf_type in
@@ -2266,6 +2277,12 @@ let retype_expression ctx request_type function_args expression_tree forInjectio
                       CppFunctionAddress(clazz,member), funcReturn
                    | _ -> error "cpp.Function.fromStaticFunction must be called on static function" expr.epos;
                    )
+               |  CppFunction(FuncSizeof ,returnType) ->
+                   ( match retypedArgs with
+                   | [ {cppexpr=CppClassOf(path,native)} ] ->
+                      CppSizeof(path,native), returnType
+                   | _ -> error "cpp.Stdlib.sizeof must be called on a type name" expr.epos;
+                   )
                |  CppEnumIndex(_) ->
                      (* Not actually a TCall...*)
                      retypedFunc.cppexpr, retypedFunc.cpptype
@@ -2748,6 +2765,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection
          | FuncNew _ -> error "Can't create new closure" expr.cpppos
          | FuncEnumConstruct _ -> error "Enum constructor outside of CppCall" expr.cpppos
          | FuncFromStaticFunction -> error "Can't create cpp.Function.fromStaticFunction closure" expr.cpppos
+         | FuncSizeof -> error "Can't create cpp.Stdlib.sizeof closure" expr.cpppos
          );
       | CppCall( FuncInterface(expr,clazz,field), args) when not (is_native_gen_class clazz)->
          out ( cpp_class_name clazz ^ "::" ^ cpp_member_name_of field ^ "(");
@@ -2812,6 +2830,8 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection
 
          | FuncFromStaticFunction ->
               error "Unexpected FuncFromStaticFunction" expr.cpppos
+         | FuncSizeof ->
+              error "Unexpected FuncSizeof" expr.cpppos
          | FuncEnumConstruct(enum,field) ->
             out ((string_of_path enum.e_path) ^ "::" ^ (cpp_enum_name_of field));
 
@@ -2858,6 +2878,16 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection
          out ("::cpp::Function< " ^ signature ^">(hx::AnyCast(");
          out ("&::" ^(join_class_path_remap klass.cl_path "::")^ "_obj::" ^ name );
          out " ))"
+      | CppSizeof(path,native) ->
+         out ("hx::ClassSizeOf< ");
+         let path = "::" ^ (join_class_path_remap (path) "::" ) in
+         if (native) then
+            out path
+         else if (path="::Array") then
+            out "hx::ArrayBase"
+         else
+            out path;
+         out  " >()";
 
       | CppGlobal(name) ->
          out ("::" ^ name)

+ 3 - 0
std/cpp/ConstPointer.hx

@@ -40,8 +40,11 @@ extern class ConstPointer<T>
 	public function gt(inOther:ConstPointer<T>):Bool;
 	public function geq(inOther:ConstPointer<T>):Bool;
 
+   public function setRaw<O>(ptr:RawPointer<O>) : Void;
+
    public static function fromRaw<T>(ptr:RawConstPointer<T>) : ConstPointer<T>;
 
+
    public static function fromPointer<T>(inNativePointer:Dynamic) : ConstPointer<T>;
 
 	public function reinterpret<Other>():Pointer<Other>;

+ 2 - 0
std/cpp/Pointer.hx

@@ -24,6 +24,8 @@
 @:coreType
 extern class Pointer<T> extends ConstPointer<T> implements ArrayAccess<T>
 {
+   public var elementSize(default,never):Int;
+
    @:analyzer(no_simplification)
 	public var ref(get,set):T;
 

+ 35 - 0
std/cpp/Stdlib.hx

@@ -0,0 +1,35 @@
+package cpp;
+
+@:include("stdlib.h")
+extern class Stdlib
+{
+   @:native("malloc")
+   public static function nativeMalloc(bytes:Int) : cpp.RawPointer<Void> return null;
+   @:native("calloc")
+   public static function nativeCalloc(bytes:Int) : cpp.RawPointer<Void> return null;
+   @:native("realloc")
+   public static function nativeRealloc(inPtr:cpp.RawPointer<Void>,bytes:Int) : cpp.RawPointer<Void> return null;
+   @:native("free")
+   public static function nativeFree(ptr:cpp.RawPointer<Void>) : Void { }
+   // This needs a special compiler hack to avoid getting the size of a class pointer
+   @:native("sizeof")
+   public static function sizeof<T>(t:T) : Int { }
+
+   inline public static function malloc<T>(bytes:Int) : cpp.Pointer<T>
+      return cast nativeMalloc(bytes);
+
+   inline public static function calloc<T>(bytes:Int) : cpp.Pointer<T>
+      return cast nativeCalloc(bytes);
+
+   inline public static function realloc<T>(ioPtr:cpp.Pointer<T>, bytes:Int) : Void
+      ioPtr.setRaw( nativeRealloc(cast ioPtr.ptr, bytes) );
+
+   inline public static function free<T>(ptr:cpp.Pointer<T>) : Void
+   {
+      if (ptr!=null)
+      {
+         nativeFree(cast ptr.ptr);
+         ptr.ptr = null;
+      }
+   }
+}