Browse Source

[cpp] Add fixed field option got anonymous objects

Hugh 9 years ago
parent
commit
02641eb2dd
5 changed files with 35 additions and 13 deletions
  1. 28 11
      src/generators/gencpp.ml
  2. 2 1
      src/syntax/ast.ml
  3. 1 0
      src/typing/common.ml
  4. 3 0
      src/typing/typer.ml
  5. 1 1
      tests/benchs/mandelbrot/Mandelbrot.hx

+ 28 - 11
src/generators/gencpp.ml

@@ -1721,7 +1721,7 @@ and tcpp_expr_expr =
    | CppSet of tcpplvalue * tcppexpr
    | CppModify of Ast.binop * tcpplvalue * tcppexpr
    | CppBinop of Ast.binop * tcppexpr * tcppexpr
-   | CppObjectDecl of (string * tcppexpr) list
+   | CppObjectDecl of (string * tcppexpr) list * bool
    | CppPosition of string * int32 * string * string
    | CppArrayDecl of tcppexpr list
    | CppUnop of tcppunop * tcppexpr
@@ -2330,7 +2330,14 @@ let retype_expression ctx request_type function_args expression_tree =
          | TThrow e1 ->
             CppThrow(retype TCppDynamic e1), TCppVoid
 
-         | TMeta (_,e)
+         | TMeta( (Meta.Fixed,_,_),e) ->
+            let cppType = retype return_type e in
+            (match cppType.cppexpr with
+            | CppObjectDecl(def,false) -> CppObjectDecl(def,true), cppType.cpptype
+            | _ -> cppType.cppexpr, cppType.cpptype
+            )
+
+         | TMeta(_,e)
          | TParenthesis e ->
             let cppType = retype return_type e in
             cppType.cppexpr, cppType.cpptype
@@ -2671,8 +2678,8 @@ let retype_expression ctx request_type function_args expression_tree =
          | TObjectDecl el ->
             let retypedEls = List.map ( fun(v,e) -> v, retype TCppDynamic e) el in
             (match return_type with
-            | TCppVoid -> CppObjectDecl(retypedEls), TCppVoid
-            | _ -> CppObjectDecl(retypedEls), TCppDynamic
+            | TCppVoid -> CppObjectDecl(retypedEls,false), TCppVoid
+            | _ -> CppObjectDecl(retypedEls,false), TCppDynamic
             )
 
          | TVar (v,eo) ->
@@ -3136,16 +3143,26 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection
          )  closure.close_undeclared;
          out "))";
 
-      | CppObjectDecl values ->
+      | CppObjectDecl (values,isStruct) ->
          let length = List.length values in
+         let lengthStr = string_of_int length in
          if (expr.cpptype!=TCppVoid) then out "Dynamic(";
-         out ("hx::Anon_obj::Create(" ^ (string_of_int length) ^")");
-         let sorted = List.sort (fun  (_,_,h0) (_,_,h1) -> Int32.compare h0 h1 )
+         if (isStruct) && length>0 && length<=5 then begin
+            out ("hx::AnonStruct" ^ lengthStr ^"_obj< " ^
+               (String.concat "," (List.map (fun (_,value) ->  tcpp_to_string value.cpptype) values) ) ^
+               " >::Create(" );
+            let sep = ref "" in
+            List.iter (fun (name,value) -> out (!sep ^ (strq name) ^ "," ); sep:=","; gen value ) values;
+            out ")";
+         end else begin
+            out ("hx::Anon_obj::Create(" ^ lengthStr ^")");
+            let sorted = List.sort (fun  (_,_,h0) (_,_,h1) -> Int32.compare h0 h1 )
                 (List.map (fun (name,value) -> name,value,(gen_hash32 0 name ) ) values) in
-         writer#push_indent;
-         ExtList.List.iteri (fun idx (name,value,_) ->
-            out ("\n" ^ spacer); writer#write_i ("->setFixed(" ^ (string_of_int idx) ^ "," ^ (strq name) ^ ","); gen value; out ")";
-         ) sorted;
+            writer#push_indent;
+            ExtList.List.iteri (fun idx (name,value,_) ->
+               out ("\n" ^ spacer); writer#write_i ("->setFixed(" ^ (string_of_int idx) ^ "," ^ (strq name) ^ ","); gen value; out ")";
+            ) sorted;
+         end;
          if (expr.cpptype!=TCppVoid) then out ")";
          writer#pop_indent;
 

+ 2 - 1
src/syntax/ast.ml

@@ -74,6 +74,7 @@ module Meta = struct
 		| FakeEnum
 		| File
 		| Final
+		| Fixed
 		| FlatEnum
 		| Font
 		| Forward
@@ -918,4 +919,4 @@ let full_dot_path mpath tpath =
 		(fst mpath) @ [snd mpath;snd tpath]
 
 let safe_for_all2 f a b =
-	try List.for_all2 f a b with _ -> false
+	try List.for_all2 f a b with _ -> false

+ 1 - 0
src/typing/common.ml

@@ -405,6 +405,7 @@ module MetaInfo = struct
 		| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
 		| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
 		| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
+		| Fixed -> ":fixed",("Delcares an anonymous object to have fixed fields",[ (*UsedOn TObjectDecl(_)*)])
 		| FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; Internal])
 		| Font -> ":font",("Embeds the given TrueType font into the class (must extend flash.text.Font)",[HasParam "TTF path";HasParam "Range String";UsedOn TClass])
 		| Forward -> ":forward",("Forwards field access to underlying type",[HasParam "List of field names";UsedOn TAbstract])

+ 3 - 0
src/typing/typer.ml

@@ -3730,6 +3730,9 @@ and type_expr ctx (e,p) (with_type:with_type) =
 			| (Meta.NoPrivateAccess,_,_) ->
 				ctx.meta <- List.filter (fun(m,_,_) -> m <> Meta.PrivateAccess) ctx.meta;
 				e()
+			| (Meta.Fixed,_,_) when ctx.com.platform=Cpp ->
+				let e = e() in
+				{e with eexpr = TMeta(m,e)}
 			| _ -> e()
 		in
 		ctx.meta <- old;

+ 1 - 1
tests/benchs/mandelbrot/Mandelbrot.hx

@@ -119,7 +119,7 @@ class Mandelbrot
 
 
    #if anon_objects
-   inline public static function createComplex(inI:Float, inJ:Float) return { i:inI, j:inJ };
+   public static function createComplex(inI:Float, inJ:Float) return @:fixed { i:inI, j:inJ };
    #else
    inline public static function createComplex(inI:Float, inJ:Float) return new Complex(inI, inJ);
    #end