From 6f25b8b115ee0c95ed819abdbfe93e0ac0600e78 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Wed, 20 Jul 2022 21:16:41 +0100 Subject: [PATCH 01/39] Initial addition of typed functions to hxcpp --- src/generators/gencpp.ml | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index a51f442044c..79fa4b5c642 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1364,6 +1364,7 @@ type tcpp = | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp + | TCppClosure of tcpp list * tcpp | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp @@ -1619,6 +1620,11 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppAutoCast -> "::cpp::AutoCast" | TCppVariant -> "::cpp::Variant" | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix + | TCppClosure(args, return) -> + let string_args = match args with + | [] -> "void" + | vs -> (String.concat "," (List.map tcpp_to_string vs)) in + "::hx::Closure< " ^ (tcpp_to_string return) ^ ", " ^ string_args ^ ">" | TCppScalar(scalar) -> scalar | TCppString -> "::String" | TCppFastIterator it -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (tcpp_to_string it) ^ " >"; @@ -1790,7 +1796,8 @@ let rec cpp_type_of stack ctx haxe_type = cpp_type_from_path stack ctx type_def.t_path params (fun () -> cpp_type_of stack ctx (apply_typedef type_def params) ) - | TFun _ -> TCppObject + | TFun (args, return) -> + TCppClosure ((List.map (fun (_, _, a) -> cpp_type_of stack ctx a) args), (cpp_type_of stack ctx return)) | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) @@ -2058,6 +2065,7 @@ let cpp_variant_type_of t = match t with | TCppClass | TCppGlobal | TCppNull + | TCppClosure _ | TCppEnum _ -> TCppDynamic | TCppString -> TCppString | TCppFunction _ @@ -2876,6 +2884,7 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in + let tcpp_args = List.map (fun (v,_) -> cpp_type_of v.v_type ) func.tf_args in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; @@ -2895,7 +2904,7 @@ let retype_expression ctx request_type function_args function_type expression_tr uses_this := if !uses_this != None then Some old_this_real else old_uses_this; gc_stack := old_gc_stack; rev_closures := result:: !rev_closures; - CppClosure(result), TCppDynamic + CppClosure(result), (TCppClosure (tcpp_args, result.close_type)) | TArray (e1,e2) -> let retypedObj = retype TCppDynamic e1 in @@ -3824,7 +3833,11 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | CppClosure closure -> - out (" ::Dynamic(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); + let tcpp_args = match closure.close_args with + | [] -> "void" + | vs -> String.concat "," (List.map (fun (v,_) -> tcpp_to_string (cpp_type_of ctx v.v_type)) vs) in + let tcpp_return = tcpp_to_string closure.close_type in + out (" ::hx::Closure<" ^ tcpp_return ^ ", " ^ tcpp_args ^ ">(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); let separator = ref "" in (match closure.close_this with | Some this -> @@ -7088,6 +7101,7 @@ let rec script_cpptype_string cppType = match cppType with | TCppDynamic | TCppUnchanged | TCppWrapped _ + | TCppClosure _ | TCppObject -> "Dynamic" | TCppObjectPtr -> ".*.hx.Object*" | TCppReference t -> ".ref." ^ (script_cpptype_string t) From 9c3cbdf5cc02be963f82ab8858dd5f01a5109b99 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 13 Apr 2023 18:33:03 +0100 Subject: [PATCH 02/39] Generate dynamic versions of functions using specialisations of the callable type --- src/generators/gencpp.ml | 80 ++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 20 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 505b9dff0a2..e93597ef50b 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1382,7 +1382,7 @@ type tcpp = | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp - | TCppClosure of tcpp list * tcpp + | TCppCallable of tcpp list * tcpp | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp @@ -1494,7 +1494,7 @@ and tcpp_expr_expr = | CppThis of tcppthis | CppSuper of tcppthis | CppCode of string * tcppexpr list - | CppClosure of tcpp_closure + | CppCallable of tcpp_closure | CppVar of tcppvarloc | CppExtern of string * bool | CppDynamicField of tcppexpr * string @@ -1552,7 +1552,7 @@ let rec s_tcpp = function | CppThis _ -> "CppThis" | CppSuper _ -> "CppSuper" | CppCode _ -> "CppCode" - | CppClosure _ -> "CppClosure" + | CppCallable _ -> "CppCallable" | CppVar VarLocal(_) -> "CppVarLocal" | CppVar VarClosure(_) -> "CppVarClosure" | CppVar VarThis(_) -> "CppVarThis" @@ -1638,11 +1638,11 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppAutoCast -> "::cpp::AutoCast" | TCppVariant -> "::cpp::Variant" | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix - | TCppClosure(args, return) -> + | TCppCallable(args, return) -> let string_args = match args with | [] -> "void" | vs -> (String.concat "," (List.map tcpp_to_string vs)) in - "::hx::Closure< " ^ (tcpp_to_string return) ^ ", " ^ string_args ^ ">" + "::hx::Callable< " ^ (tcpp_to_string return) ^ "(" ^ string_args ^ ")>" | TCppScalar(scalar) -> scalar | TCppString -> "::String" | TCppFastIterator it -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (tcpp_to_string it) ^ " >"; @@ -1827,7 +1827,7 @@ let rec cpp_type_of stack ctx haxe_type = cpp_type_of stack ctx (apply_typedef type_def params) ) | TFun (args, return) -> - TCppClosure ((List.map (fun (_, _, a) -> cpp_type_of stack ctx a) args), (cpp_type_of stack ctx return)) + TCppCallable ((List.map (fun (_, _, a) -> cpp_type_of stack ctx a) args), (cpp_type_of stack ctx return)) | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) @@ -2085,7 +2085,7 @@ let cpp_variant_type_of t = match t with | TCppClass | TCppGlobal | TCppNull - | TCppClosure _ + | TCppCallable _ | TCppEnum _ -> TCppDynamic | TCppString -> TCppString | TCppFunction _ @@ -2940,7 +2940,7 @@ let retype_expression ctx request_type function_args function_type expression_tr uses_this := if !uses_this != None then Some old_this_real else old_uses_this; gc_stack := old_gc_stack; rev_closures := result:: !rev_closures; - CppClosure(result), (TCppClosure (tcpp_args, result.close_type)) + CppCallable(result), (TCppCallable (tcpp_args, result.close_type)) | TArray (e1,e2) -> let arrayExpr, elemType = match cpp_is_native_array_access (cpp_type_of e1.etype) with @@ -3879,12 +3879,12 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ gen_val_loc loc false; - | CppClosure closure -> + | CppCallable closure -> let tcpp_args = match closure.close_args with | [] -> "void" | vs -> String.concat "," (List.map (fun (v,_) -> tcpp_to_string (cpp_type_of ctx v.v_type)) vs) in let tcpp_return = tcpp_to_string closure.close_type in - out (" ::hx::Closure<" ^ tcpp_return ^ ", " ^ tcpp_args ^ ">(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); + out (" ::hx::Callable<" ^ tcpp_return ^ "(" ^ tcpp_args ^ ")>(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); let separator = ref "" in (match closure.close_this with | Some this -> @@ -4303,16 +4303,18 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ abort "Too many capture variables" closure.close_expr.cpppos; if argc >= 20 || (List.length closure.close_args) >= 20 then writer#add_big_closures; + let func_type = tcpp_to_string closure.close_type in + let func_args = List.map (fun (t, _) -> cpp_var_type_of ctx t) closure.close_args in let argsCount = list_num closure.close_args in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); - out (if closure.close_this != None then "::hx::LocalThisFunc," else "::hx::LocalFunc,"); - out ("_hx_Closure_" ^ (string_of_int closure.close_id) ); + out (if closure.close_this != None then "::hx::CallableThisFunction< " else "::hx::CallableFunction< "); + out (func_type ^ "(" ^ (String.concat ", " func_args) ^ ")>"); + out (",_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> out ("," ^ (cpp_macro_var_type_of ctx var) ^ "," ^ (keyword_remap name)); ) closure.close_undeclared; out (") HXARGC(" ^ argsCount ^")\n"); - let func_type = tcpp_to_string closure.close_type in output_i (func_type ^ " _hx_run(" ^ (cpp_arg_list ctx closure.close_args "__o_") ^ ")"); let prologue = function gc_stack -> @@ -4563,7 +4565,42 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let doDynamic = (nonVirtual || not (is_override field ) ) && (reflective class_def field ) in (* generate dynamic version too ... *) if ( doDynamic ) then begin - let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in + let callable_name = "__" ^ class_name ^ remap_name in + let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type) function_def.tf_args in + let callable_args = String.concat "," (List.map tcpp_to_string tcpp_args) in + let callable_signature = (tcpp_to_string return_type) ^ "(" ^ callable_args ^ ")" in + let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in + ( + output ("struct " ^ callable_name ^ " : public ::hx::CallableFunction<" ^ callable_signature ^ ">\n"); + output "{\n"; + + (if is_static then + output ("\t" ^ callable_name ^ "() {}\n") + else begin + output ("\t" ^ obj_ptr_class_name ^ " obj;\n"); + output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "_obj) : obj(_obj) {}\n"); + end); + + output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); + output "\t{\n"; + + output (if is_void then "\t\t" else "\t\treturn "); + (if is_static then + output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") + else + output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); + + output "\t}\n"; + + (* TODO : Generate mark, visit, compare, __run, etc, etc *) + + output "};\n\n"; + output ("::hx::Callable<" ^ callable_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); + output "{\n"; + output ("\treturn new " ^ callable_name ^ "(" ^ (if is_static then "" else "this") ^ ");\n"); + output "}\n\n"; + ) + (* let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in let wrap = (needsWrapper return_type) || (List.exists needsWrapper tcpp_args) in if wrap then begin let wrapName = "_hx_wrap" ^ class_name ^ "_" ^ remap_name in @@ -4615,7 +4652,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface end else begin if (is_static) then output "STATIC_"; output ("HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ remap_name ^ "," ^ ret ^ ")\n\n"); - end + end *) end; end else begin @@ -4754,7 +4791,9 @@ let gen_member_def ctx class_def is_static is_interface field = output ("inline ::Dynamic &" ^ remap_name ^ "_dyn() " ^ "{return " ^ remap_name^ "; }\n") end end else begin - let return_type = (ctx_type_string ctx function_def.tf_type) in + let return_type = match ctx_type_string ctx function_def.tf_type with + | "Void" -> "void" + | t -> t in if ( not is_static && not nonVirtual ) then begin let scriptable = Common.defined ctx.ctx_common Define.Scriptable in if (not (is_internal_member field.cf_name) && not scriptable ) then begin @@ -4763,7 +4802,7 @@ let gen_member_def ctx class_def is_static is_interface field = end else output "virtual "; end; - output (if return_type="Void" then "void" else return_type ); + output return_type; let remap_name = native_field_name_remap is_static field in output (" " ^ remap_name ^ "(" ); @@ -4771,7 +4810,8 @@ let gen_member_def ctx class_def is_static is_interface field = output ");\n"; if ( doDynamic ) then begin output (if is_static then "\t\tstatic " else "\t\t"); - output ("::Dynamic " ^ remap_name ^ "_dyn();\n" ) + let args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type) function_def.tf_args in + output ("::hx::Callable< " ^ return_type ^ "(" ^ (String.concat ", " (List.map tcpp_to_string args)) ^ ")> " ^ remap_name ^ "_dyn();\n" ) end; end; output "\n"; @@ -7159,7 +7199,7 @@ let rec script_cpptype_string cppType = match cppType with | TCppDynamic | TCppUnchanged | TCppWrapped _ - | TCppClosure _ + | TCppCallable _ | TCppObject -> "Dynamic" | TCppObjectPtr -> ".*.hx.Object*" | TCppReference t -> ".ref." ^ (script_cpptype_string t) @@ -8185,7 +8225,7 @@ class script_writer ctx filename asciiOut = this#write ( (this#op IaEnumI) ^ (this#typeTextString "Dynamic") ^ (string_of_int index) ^ "\n"); gen_expression obj; - | CppClosure closure -> + | CppCallable closure -> this#write ( (this#op IaFun) ^ (this#astType closure.close_type) ^ (string_of_int (List.length closure.close_args)) ^ "\n" ); let close = this#gen_func_args closure.close_args in gen_expression closure.close_expr; From 5db7d539f7dc28dd3611d2c2975706d4af935c4e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 13 Apr 2023 19:09:57 +0100 Subject: [PATCH 03/39] Add callable type to CppCast --- src/generators/gencpp.ml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index e93597ef50b..18a9dabfe73 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1280,10 +1280,6 @@ and is_dynamic_in_cppia ctx expr = | _ -> is_dynamic_in_cpp ctx expr ;; -let cast_if_required ctx expr to_type = - if (is_dynamic_in_cpp ctx expr) then - ctx.ctx_output (".Cast< " ^ to_type ^ " >()" ) -;; let is_matching_interface_type t0 t1 = @@ -3200,6 +3196,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppPointer(_,_) | TCppRawPointer(_,_) | TCppStar(_) + | TCppCallable(_,_) | TCppInst(_) -> CppCast(baseCpp,return_type), return_type | TCppString -> CppCastScalar(baseCpp,"::String"), return_type | TCppCode(t) when baseStr <> (tcpp_to_string t) -> @@ -3257,6 +3254,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppDynamicArray | TCppObjectPtr | TCppVarArg + | TCppCallable (_, _) | TCppInst _ -> mk_cppexpr (CppCast(cppExpr,return_type)) return_type From 06cbd848c045dc18ddd614f7ffd1bca4bcb3b5c3 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 13 Apr 2023 19:14:33 +0100 Subject: [PATCH 04/39] Don't place void in between brackets for callables with no arguments, purely for stylistic consistency --- src/generators/gencpp.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 18a9dabfe73..00f05c771f5 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1636,7 +1636,7 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix | TCppCallable(args, return) -> let string_args = match args with - | [] -> "void" + | [] -> "" | vs -> (String.concat "," (List.map tcpp_to_string vs)) in "::hx::Callable< " ^ (tcpp_to_string return) ^ "(" ^ string_args ^ ")>" | TCppScalar(scalar) -> scalar From e085782612faec570166450a08472cb60c854745 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 13 Apr 2023 21:30:13 +0100 Subject: [PATCH 05/39] Switch to Callable_obj for consistency with Array and Array_obj --- src/generators/gencpp.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 00f05c771f5..544fa8b62be 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4305,7 +4305,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ let func_args = List.map (fun (t, _) -> cpp_var_type_of ctx t) closure.close_args in let argsCount = list_num closure.close_args in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); - out (if closure.close_this != None then "::hx::CallableThisFunction< " else "::hx::CallableFunction< "); + out (if closure.close_this != None then "::hx::CallableThis_obj< " else "::hx::Callable_obj< "); out (func_type ^ "(" ^ (String.concat ", " func_args) ^ ")>"); out (",_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> @@ -4569,7 +4569,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let callable_signature = (tcpp_to_string return_type) ^ "(" ^ callable_args ^ ")" in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in ( - output ("struct " ^ callable_name ^ " : public ::hx::CallableFunction<" ^ callable_signature ^ ">\n"); + output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ callable_signature ^ ">\n"); output "{\n"; (if is_static then From 3b517687a3ec917c5f58cc3355e39ec164f3d87e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 14 Apr 2023 13:31:25 +0100 Subject: [PATCH 06/39] Implement the dynamic run functions --- src/generators/gencpp.ml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 544fa8b62be..5ca2ad7ff24 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4579,6 +4579,8 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "_obj) : obj(_obj) {}\n"); end); + (* Implement the pure virtual function *) + output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); output "\t{\n"; @@ -4590,6 +4592,15 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output "\t}\n"; + (* Override the dynamic run functions *) + + output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); + output (String.concat ", " (List.init (List.length tcpp_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); + output "); return null(); }\n"; + + output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) tcpp_args)) ^ ")"); + output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) tcpp_args)) ^ "); return null(); }\n"); + (* TODO : Generate mark, visit, compare, __run, etc, etc *) output "};\n\n"; From f751fa18efe126bdf1f9a86867a426dd4f58c9f9 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 15 Apr 2023 12:29:48 +0100 Subject: [PATCH 07/39] Correctly print out ::hx::Null for default value class functions args --- src/generators/gencpp.ml | 42 ++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 5ca2ad7ff24..0f4af65fecf 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1378,7 +1378,7 @@ type tcpp = | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp - | TCppCallable of tcpp list * tcpp + | TCppCallable of (tcpp * bool) list * tcpp | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp @@ -1637,7 +1637,15 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppCallable(args, return) -> let string_args = match args with | [] -> "" - | vs -> (String.concat "," (List.map tcpp_to_string vs)) in + | vs -> (String.concat "," (List.map (fun (typ, opt) -> + let cant_be_null = fun tcpp -> match tcpp with + | TCppScalar _ -> true + | _ -> false in + let type_str = tcpp_to_string typ in + if (opt && (cant_be_null typ) && typ<>TCppDynamic) then + "::hx::Null< " ^ type_str ^ " > " + else + type_str) vs)) in "::hx::Callable< " ^ (tcpp_to_string return) ^ "(" ^ string_args ^ ")>" | TCppScalar(scalar) -> scalar | TCppString -> "::String" @@ -1823,7 +1831,7 @@ let rec cpp_type_of stack ctx haxe_type = cpp_type_of stack ctx (apply_typedef type_def params) ) | TFun (args, return) -> - TCppCallable ((List.map (fun (_, _, a) -> cpp_type_of stack ctx a) args), (cpp_type_of stack ctx return)) + TCppCallable ((List.map (fun (_, o, a) -> (cpp_type_of stack ctx a), o) args), (cpp_type_of stack ctx return)) | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) @@ -2916,7 +2924,7 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in - let tcpp_args = List.map (fun (v,_) -> cpp_type_of v.v_type ) func.tf_args in + let tcpp_args = List.map (fun (v,o) -> (cpp_type_of v.v_type), o<>None) func.tf_args in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; @@ -4564,8 +4572,17 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* generate dynamic version too ... *) if ( doDynamic ) then begin let callable_name = "__" ^ class_name ^ remap_name in - let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type) function_def.tf_args in - let callable_args = String.concat "," (List.map tcpp_to_string tcpp_args) in + let tcpp_args = List.map (fun (v,o) -> (cpp_type_of ctx v.v_type), o<>None) function_def.tf_args in + let stringify = (fun (tcpp, opt) -> + let cant_be_null = match tcpp with + | TCppScalar _ -> true + | _ -> false in + let type_str = tcpp_to_string tcpp in + if (opt && cant_be_null && tcpp<>TCppDynamic) then + "::hx::Null< " ^ type_str ^ " > " + else + type_str) in + let callable_args = String.concat "," (List.map stringify tcpp_args) in let callable_signature = (tcpp_to_string return_type) ^ "(" ^ callable_args ^ ")" in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in ( @@ -4819,8 +4836,17 @@ let gen_member_def ctx class_def is_static is_interface field = output ");\n"; if ( doDynamic ) then begin output (if is_static then "\t\tstatic " else "\t\t"); - let args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type) function_def.tf_args in - output ("::hx::Callable< " ^ return_type ^ "(" ^ (String.concat ", " (List.map tcpp_to_string args)) ^ ")> " ^ remap_name ^ "_dyn();\n" ) + let args = List.map (fun (v,o) -> (cpp_type_of ctx v.v_type), o<>None) function_def.tf_args in + let stringify = (fun (tcpp, opt) -> + let cant_be_null = match tcpp with + | TCppScalar _ -> true + | _ -> false in + let type_str = tcpp_to_string tcpp in + if (opt && cant_be_null && tcpp<>TCppDynamic) then + "::hx::Null< " ^ type_str ^ " > " + else + type_str) in + output ("::hx::Callable< " ^ return_type ^ "(" ^ (String.concat ", " (List.map stringify args)) ^ ")> " ^ remap_name ^ "_dyn();\n" ) end; end; output "\n"; From f2229e3d684cbe7964b32f9e8b76e0b70158cf78 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 15 Apr 2023 16:31:32 +0100 Subject: [PATCH 08/39] Further attempts at working around hx::Null optimisation case --- src/generators/gencpp.ml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 0f4af65fecf..b61ce5a8c2e 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -2924,12 +2924,24 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in - let tcpp_args = List.map (fun (v,o) -> (cpp_type_of v.v_type), o<>None) func.tf_args in + let retype_arg = (fun (tvar, default_value) -> + match default_value with + | Some _ when (ctx_cant_be_null ctx tvar.v_type) -> { tvar with v_type = TDynamic None }, default_value + | _ -> tvar, default_value) in + let retyped_args = List.map retype_arg func.tf_args in + let tcpp_args = List.map (fun (tvar,default_value) -> + let tcpp = cpp_type_of tvar.v_type in + let cant_be_null = match tcpp with + | TCppScalar _ -> true + | _ -> false in + match default_value with + | Some _ when cant_be_null -> tcpp, true + | _ -> tcpp, false) retyped_args in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; close_type= ret; - close_args= func.tf_args; + close_args= retyped_args; close_this= !uses_this; } in incr closureId; @@ -3887,7 +3899,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | CppCallable closure -> let tcpp_args = match closure.close_args with - | [] -> "void" + | [] -> "" | vs -> String.concat "," (List.map (fun (v,_) -> tcpp_to_string (cpp_type_of ctx v.v_type)) vs) in let tcpp_return = tcpp_to_string closure.close_type in out (" ::hx::Callable<" ^ tcpp_return ^ "(" ^ tcpp_args ^ ")>(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); From 03e3ae94fbc487e7822a341ae2506db9b0f6d9bf Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 15 Apr 2023 17:53:30 +0100 Subject: [PATCH 09/39] Generate mark and visit functions for class function callables --- src/generators/gencpp.ml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index b61ce5a8c2e..ba09e8124c5 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4630,7 +4630,14 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) tcpp_args)) ^ ")"); output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) tcpp_args)) ^ "); return null(); }\n"); - (* TODO : Generate mark, visit, compare, __run, etc, etc *) + if (not is_static) then begin + output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(obj); }\n"; + output "#ifdef HXCPP_VISIT_ALLOCS\n"; + output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(obj); }\n"; + output "#endif\n"; + end; + + (* TODO : Generate, compare, etc, etc *) output "};\n\n"; output ("::hx::Callable<" ^ callable_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); From ce988eaa108895fe3f037896c7e47d9cbd001cd9 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Wed, 19 Apr 2023 21:20:36 +0100 Subject: [PATCH 10/39] attempt to cleanup optional / null arguments --- src/generators/gencpp.ml | 142 ++++++++++++++------------------------- 1 file changed, 52 insertions(+), 90 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 705e29459b9..84814b6fac6 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1378,7 +1378,7 @@ type tcpp = | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp - | TCppCallable of (tcpp * bool) list * tcpp + | TCppCallable of string | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp @@ -1634,19 +1634,8 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppAutoCast -> "::cpp::AutoCast" | TCppVariant -> "::cpp::Variant" | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix - | TCppCallable(args, return) -> - let string_args = match args with - | [] -> "" - | vs -> (String.concat "," (List.map (fun (typ, opt) -> - let cant_be_null = fun tcpp -> match tcpp with - | TCppScalar _ -> true - | _ -> false in - let type_str = tcpp_to_string typ in - if (opt && (cant_be_null typ) && typ<>TCppDynamic) then - "::hx::Null< " ^ type_str ^ " > " - else - type_str) vs)) in - "::hx::Callable< " ^ (tcpp_to_string return) ^ "(" ^ string_args ^ ")>" + | TCppCallable signature -> + "::hx::Callable< " ^ signature ^ ">" | TCppScalar(scalar) -> scalar | TCppString -> "::String" | TCppFastIterator it -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (tcpp_to_string it) ^ " >"; @@ -1659,7 +1648,7 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with (tcpp_objc_block_struct argTypes retType) ^ "::t" | TCppDynamicArray -> "::cpp::VirtualArray" ^ suffix | TCppObjectArray _ -> "::Array" ^ suffix ^ "< ::Dynamic>" - | TCppWrapped _ -> " ::Dynamic" + | TCppWrapped t -> " ::hx::Null< " ^ (tcpp_to_string t) ^ " >" | TCppScalarArray(value) -> "::Array" ^ suffix ^ "< " ^ (tcpp_to_string value) ^ " >" | TCppObjC klass -> let path = join_class_path_remap klass.cl_path "::" in @@ -1831,7 +1820,11 @@ let rec cpp_type_of stack ctx haxe_type = cpp_type_of stack ctx (apply_typedef type_def params) ) | TFun (args, return) -> - TCppCallable ((List.map (fun (_, o, a) -> (cpp_type_of stack ctx a), o) args), (cpp_type_of stack ctx return)) + let fargs = List.map (fun (_, o, t) -> cpp_tfun_arg_type_of stack ctx o t) args |> List.map tcpp_to_string in + let ret = cpp_type_of stack ctx return |> tcpp_to_string in + let signature = ret ^ "(" ^ (String.concat "," fargs) ^ ")" in + + TCppCallable (signature) | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) @@ -1930,14 +1923,14 @@ let rec cpp_type_of stack ctx haxe_type = ) | ([],"Null"), [p] -> - cpp_type_of_null stack ctx p + cpp_type_of_null stack ctx p false | _ -> default () - and cpp_type_of_null stack ctx p = + and cpp_type_of_null stack ctx p wrap = let baseType = cpp_type_of stack ctx p in if (type_has_meta_key p Meta.NotNull) || (is_cpp_scalar baseType) then - TCppObject + if wrap then TCppWrapped baseType else TCppObject else baseType and cpp_type_of_pointer stack ctx p = @@ -1947,11 +1940,17 @@ let rec cpp_type_of stack ctx haxe_type = (* Optional types are Dynamic if they norally could not be null *) and cpp_fun_arg_type_of stack ctx tvar opt = match opt with - | Some _ -> cpp_type_of_null stack ctx tvar.t_type + | Some {eexpr = TConst TNull} -> cpp_type_of stack ctx tvar.t_type + | Some _ when (cant_be_null tvar.t_type) -> TCppWrapped (cpp_type_of stack ctx tvar.t_type) | _ -> cpp_type_of stack ctx tvar.t_type and cpp_tfun_arg_type_of stack ctx opt t = - if opt then cpp_type_of_null stack ctx t else cpp_type_of stack ctx t + if opt then + match t with + | TAbstract({ a_path = ([], "Null") }, [ inner ]) -> cpp_type_of_null stack ctx inner true + | _ -> cpp_type_of stack ctx t + else + cpp_type_of stack ctx t and cpp_function_type_of stack ctx function_type abi = let abi = (match follow abi with @@ -1969,7 +1968,7 @@ let rec cpp_type_of stack ctx haxe_type = (* Optional types are Dynamic if they norally could not be null *) let cpp_arg_type_of = fun(_,optional,haxe_type) -> if optional then - cpp_type_of_null stack ctx haxe_type + cpp_type_of_null stack ctx haxe_type true else cpp_type_of stack ctx haxe_type in @@ -2164,7 +2163,7 @@ let ctx_arg_type_name ctx name default_val arg_type prefix = let type_str = (ctx_type_string ctx arg_type) in match default_val with | Some {eexpr = TConst TNull} -> (type_str,remap_name) - | Some constant when (ctx_cant_be_null ctx arg_type) -> ("::hx::Null< " ^ type_str ^ " > ",prefix ^ remap_name) + | Some constant when (ctx_cant_be_null ctx constant.etype) -> ("::hx::Null< " ^ (ctx_type_string ctx constant.etype) ^ " > ",prefix ^ remap_name) | Some constant -> (type_str,prefix ^ remap_name) | _ -> (type_str,remap_name);; @@ -2207,6 +2206,12 @@ let rec ctx_tfun_arg_list ctx include_names arg_list = | (name,o,arg_type) :: remaining -> (oType o arg_type) ^ (if include_names then " " ^ (keyword_remap name) else "") ^ "," ^ (ctx_tfun_arg_list ctx include_names remaining) +let ctx_tfun_arg_list_signature ctx function_def = + let return = cpp_type_of ctx function_def.tf_type |> tcpp_to_string in + let args = String.concat "," (List.map (fun (v,o) -> fst ( ctx_arg_type_name ctx v.v_name o v.v_type "" ) ) function_def.tf_args) in + return ^ " ( " ^ args ^ " )" +;; + let cpp_var_type_of ctx var = tcpp_to_string (cpp_type_of ctx var.v_type) ;; @@ -2924,24 +2929,12 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in - let retype_arg = (fun (tvar, default_value) -> - match default_value with - | Some _ when (ctx_cant_be_null ctx tvar.v_type) -> { tvar with v_type = TDynamic None }, default_value - | _ -> tvar, default_value) in - let retyped_args = List.map retype_arg func.tf_args in - let tcpp_args = List.map (fun (tvar,default_value) -> - let tcpp = cpp_type_of tvar.v_type in - let cant_be_null = match tcpp with - | TCppScalar _ -> true - | _ -> false in - match default_value with - | Some _ when cant_be_null -> tcpp, true - | _ -> tcpp, false) retyped_args in + let signature = ctx_tfun_arg_list_signature ctx func in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; close_type= ret; - close_args= retyped_args; + close_args= func.tf_args; close_this= !uses_this; } in incr closureId; @@ -2956,7 +2949,7 @@ let retype_expression ctx request_type function_args function_type expression_tr uses_this := if !uses_this != None then Some old_this_real else old_uses_this; gc_stack := old_gc_stack; rev_closures := result:: !rev_closures; - CppCallable(result), (TCppCallable (tcpp_args, result.close_type)) + CppCallable(result), (TCppCallable signature) | TArray (e1,e2) -> let arrayExpr, elemType = match cpp_is_native_array_access (cpp_type_of e1.etype) with @@ -3216,7 +3209,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppPointer(_,_) | TCppRawPointer(_,_) | TCppStar(_) - | TCppCallable(_,_) + | TCppCallable(_) | TCppInst(_) -> CppCast(baseCpp,return_type), return_type | TCppString -> CppCastScalar(baseCpp,"::String"), return_type | TCppCode(t) when baseStr <> (tcpp_to_string t) -> @@ -3274,7 +3267,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppDynamicArray | TCppObjectPtr | TCppVarArg - | TCppCallable (_, _) + | TCppCallable _ | TCppInst _ -> mk_cppexpr (CppCast(cppExpr,return_type)) return_type @@ -3404,14 +3397,6 @@ let mk_injection prologue set_var tail = ;; -let cpp_arg_type_name ctx tvar default_val prefix = - let remap_name = (cpp_var_name_of tvar) in - let type_str = (cpp_var_type_of ctx tvar) in - match default_val with - | Some {eexpr = TConst TNull} -> (tcpp_to_string (cpp_type_of_null ctx tvar.v_type)),remap_name - | Some constant -> (tcpp_to_string (cpp_type_of_null ctx tvar.v_type)),prefix ^ remap_name - | _ -> type_str,remap_name -;; @@ -3434,11 +3419,11 @@ match value.eexpr with let cpp_gen_default_values ctx args prefix = List.iter ( fun (tvar,o) -> - let vtype = cpp_type_of ctx tvar.v_type in - let not_null = (type_has_meta_key tvar.v_type Meta.NotNull) || (is_cpp_scalar vtype) in match o with | Some {eexpr = TConst TNull} -> () | Some const -> + let vtype = cpp_type_of ctx const.etype in + let not_null = (type_has_meta_key tvar.v_type Meta.NotNull) || (is_cpp_scalar vtype) in let name = cpp_var_name_of tvar in let spacer = if (ctx.ctx_debug_level>0) then " \t" else "" in let pname = prefix ^ name in @@ -3483,7 +3468,7 @@ let cpp_is_const_scalar_array arrayType expressions = (* Generate prototype text, including allowing default values to be null *) let cpp_arg_string ctx tvar default_val prefix = - let t,n = cpp_arg_type_name ctx tvar default_val prefix in + let t,n = ctx_arg_type_name ctx tvar.v_name default_val tvar.v_type prefix in t ^ " " ^ n ;; @@ -3497,7 +3482,11 @@ let gen_type ctx haxe_type = ;; - +let cpp_closure_signature ctx closure = + let func_type = tcpp_to_string closure.close_type in + let func_args = String.concat "," (List.map (fun (v,o) -> fst ( ctx_arg_type_name ctx v.v_name o v.v_type "" ) ) closure.close_args) in + func_type ^ "(" ^ func_args ^ ")" +;; let rec implements_native_interface class_def = @@ -3898,11 +3887,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | CppCallable closure -> - let tcpp_args = match closure.close_args with - | [] -> "" - | vs -> String.concat "," (List.map (fun (v,_) -> tcpp_to_string (cpp_type_of ctx v.v_type)) vs) in - let tcpp_return = tcpp_to_string closure.close_type in - out (" ::hx::Callable<" ^ tcpp_return ^ "(" ^ tcpp_args ^ ")>(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); + out (" ::hx::Callable<" ^ (cpp_closure_signature ctx closure )^ ">(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); let separator = ref "" in (match closure.close_this with | Some this -> @@ -4321,19 +4306,17 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ abort "Too many capture variables" closure.close_expr.cpppos; if argc >= 20 || (List.length closure.close_args) >= 20 then writer#add_big_closures; - let func_type = tcpp_to_string closure.close_type in - let func_args = List.map (fun (t, _) -> cpp_var_type_of ctx t) closure.close_args in let argsCount = list_num closure.close_args in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); out (if closure.close_this != None then "::hx::CallableThis_obj< " else "::hx::Callable_obj< "); - out (func_type ^ "(" ^ (String.concat ", " func_args) ^ ")>"); - out (",_hx_Closure_" ^ (string_of_int closure.close_id) ); + out (cpp_closure_signature ctx closure); + out (">,_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> out ("," ^ (cpp_macro_var_type_of ctx var) ^ "," ^ (keyword_remap name)); ) closure.close_undeclared; out (") HXARGC(" ^ argsCount ^")\n"); - output_i (func_type ^ " _hx_run(" ^ (cpp_arg_list ctx closure.close_args "__o_") ^ ")"); + output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (cpp_arg_list ctx closure.close_args "__o_") ^ ")"); let prologue = function gc_stack -> cpp_gen_default_values ctx closure.close_args "__o_"; @@ -4584,21 +4567,10 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* generate dynamic version too ... *) if ( doDynamic ) then begin let callable_name = "__" ^ class_name ^ remap_name in - let tcpp_args = List.map (fun (v,o) -> (cpp_type_of ctx v.v_type), o<>None) function_def.tf_args in - let stringify = (fun (tcpp, opt) -> - let cant_be_null = match tcpp with - | TCppScalar _ -> true - | _ -> false in - let type_str = tcpp_to_string tcpp in - if (opt && cant_be_null && tcpp<>TCppDynamic) then - "::hx::Null< " ^ type_str ^ " > " - else - type_str) in - let callable_args = String.concat "," (List.map stringify tcpp_args) in - let callable_signature = (tcpp_to_string return_type) ^ "(" ^ callable_args ^ ")" in + let func_signature = ctx_tfun_arg_list_signature ctx function_def in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in ( - output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ callable_signature ^ ">\n"); + output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); output "{\n"; (if is_static then @@ -4624,11 +4596,11 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* Override the dynamic run functions *) output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); - output (String.concat ", " (List.init (List.length tcpp_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); + output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); output "); return null(); }\n"; - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) tcpp_args)) ^ ")"); - output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) tcpp_args)) ^ "); return null(); }\n"); + output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); + output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); if (not is_static) then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(obj); }\n"; @@ -4640,7 +4612,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* TODO : Generate, compare, etc, etc *) output "};\n\n"; - output ("::hx::Callable<" ^ callable_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); + output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); output "{\n"; output ("\treturn new " ^ callable_name ^ "(" ^ (if is_static then "" else "this") ^ ");\n"); output "}\n\n"; @@ -4855,17 +4827,7 @@ let gen_member_def ctx class_def is_static is_interface field = output ");\n"; if ( doDynamic ) then begin output (if is_static then "\t\tstatic " else "\t\t"); - let args = List.map (fun (v,o) -> (cpp_type_of ctx v.v_type), o<>None) function_def.tf_args in - let stringify = (fun (tcpp, opt) -> - let cant_be_null = match tcpp with - | TCppScalar _ -> true - | _ -> false in - let type_str = tcpp_to_string tcpp in - if (opt && cant_be_null && tcpp<>TCppDynamic) then - "::hx::Null< " ^ type_str ^ " > " - else - type_str) in - output ("::hx::Callable< " ^ return_type ^ "(" ^ (String.concat ", " (List.map stringify args)) ^ ")> " ^ remap_name ^ "_dyn();\n" ) + output ("::hx::Callable< " ^ (ctx_tfun_arg_list_signature ctx function_def) ^ "> " ^ remap_name ^ "_dyn();\n" ); end; end; output "\n"; From d2f018058eabd5aad1de5eee902f5151a3bbe2c6 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 22 Apr 2023 11:37:52 +0100 Subject: [PATCH 11/39] Generate dynamic functions using callables --- src/generators/gencpp.ml | 219 +++++++++++++++++++-------------------- 1 file changed, 107 insertions(+), 112 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 84814b6fac6..5d9d9f11b4c 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -2403,6 +2403,7 @@ let is_object_element ctx member_type = | TCppWrapped _ | TCppScalarArray _ | TCppClass + | TCppCallable _ -> true | _ -> false ;; @@ -4542,8 +4543,8 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let orig_debug = ctx.ctx_debug_level in let no_debug = has_meta_key field.cf_meta Meta.NoDebug in + (* The actual function definition *) if (not (is_dynamic_haxe_method field)) then begin - (* The actual function definition *) let nativeImpl = get_meta_string field.cf_meta Meta.Native in let remap_name = native_field_name_remap is_static field in output (if is_void then "void" else return_type_str ); @@ -4560,132 +4561,125 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output "}\n\n"; end else gen_cpp_function_body ctx class_def is_static field.cf_name function_def code tail_code no_debug; + end; - output "\n\n"; - let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in - let doDynamic = (nonVirtual || not (is_override field ) ) && (reflective class_def field ) in - (* generate dynamic version too ... *) - if ( doDynamic ) then begin - let callable_name = "__" ^ class_name ^ remap_name in - let func_signature = ctx_tfun_arg_list_signature ctx function_def in - let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in - ( - output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); - output "{\n"; - - (if is_static then - output ("\t" ^ callable_name ^ "() {}\n") - else begin - output ("\t" ^ obj_ptr_class_name ^ " obj;\n"); - output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "_obj) : obj(_obj) {}\n"); - end); + output "\n\n"; + let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in + let doDynamic = (nonVirtual || not (is_override field ) ) && (reflective class_def field ) in + (* generate dynamic version too ... *) + if ( doDynamic ) then begin + let callable_name = if (is_dynamic_haxe_method field) then "__default_" ^ remap_name else "__" ^ class_name ^ remap_name in + let func_signature = ctx_tfun_arg_list_signature ctx function_def in + let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in + ( + output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); + output "{\n"; + + (if is_static then + output ("\t" ^ callable_name ^ "() {}\n") + else begin + output ("\t" ^ obj_ptr_class_name ^ " obj;\n"); + output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "_obj) : obj(_obj) {}\n"); + end); + + (* Implement the pure virtual function *) + + output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); + output "\t{\n"; + + output (if is_void then "\t\t" else "\t\treturn "); + (if is_static then + output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") + else + output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); - (* Implement the pure virtual function *) + output "\t}\n"; - output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); - output "\t{\n"; + (* Override the dynamic run functions *) - output (if is_void then "\t\t" else "\t\treturn "); - (if is_static then - output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") - else - output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); + output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); + output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); + output "); return null(); }\n"; - output "\t}\n"; + output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); + output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); - (* Override the dynamic run functions *) + if (not is_static) then begin + output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(obj); }\n"; + output "#ifdef HXCPP_VISIT_ALLOCS\n"; + output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(obj); }\n"; + output "#endif\n"; + end; - output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); - output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); - output "); return null(); }\n"; + (* TODO : Generate, compare, etc, etc *) - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); - output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); + output "};\n\n"; - if (not is_static) then begin - output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(obj); }\n"; - output "#ifdef HXCPP_VISIT_ALLOCS\n"; - output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(obj); }\n"; - output "#endif\n"; + if is_dynamic_haxe_method field then begin + if is_static then begin + output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ ";\n\n") end; - - (* TODO : Generate, compare, etc, etc *) - - output "};\n\n"; + end else begin output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); output "{\n"; output ("\treturn new " ^ callable_name ^ "(" ^ (if is_static then "" else "this") ^ ");\n"); output "}\n\n"; - ) - (* let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in - let wrap = (needsWrapper return_type) || (List.exists needsWrapper tcpp_args) in - if wrap then begin - let wrapName = "_hx_wrap" ^ class_name ^ "_" ^ remap_name in - output ("static ::Dynamic " ^ wrapName ^ "( " ); - let sep = ref " " in - if not is_static then begin - output "::hx::Object *obj"; - sep := ","; - end; - ExtList.List.iteri (fun i _ -> output (!sep ^ "const Dynamic &a" ^ (string_of_int i)) ; sep:=",") tcpp_args; - output ( ") {\n\t"); - if not is_void then begin - match return_type with - | TCppStar _ -> - output "return (cpp::Pointer) " - | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> - output ("return (cpp::Struct< " ^ (tcpp_to_string return_type) ^ " >) "); - | _ -> output "return "; - end; - - if is_static then - output (class_name ^ "::" ^ remap_name ^ "(") - else - output ("reinterpret_cast< " ^ class_name ^ " *>(obj)->" ^ remap_name ^ "("); - - sep := ""; - ExtList.List.iteri (fun i arg -> - output !sep; sep := ","; - (match arg with - | TCppStar (t,const) -> - output ("(cpp::" ^ (if const then "Const" else "") ^"Pointer<" ^ (tcpp_to_string t)^" >) ") - | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> - output ("(cpp::Struct< " ^ (tcpp_to_string arg) ^ " >) "); - | _ -> () ); - output ("a" ^ (string_of_int i)); - ) tcpp_args; - - output ");\n"; - - if is_void then output "\treturn null();\n"; - output "}\n"; - let nName = string_of_int (List.length tcpp_args) in - output ("::Dynamic " ^ class_name ^ "::" ^ remap_name ^ "_dyn() {\n\treturn "); - if is_static then - output ("::hx::CreateStaticFunction" ^ nName ^ "(\"" ^ remap_name ^ "\"," ^ wrapName ^ ");") - else - output ("::hx::CreateMemberFunction" ^ nName ^ "(\"" ^ remap_name ^ "\",this," ^ wrapName ^ ");"); - output "}\n"; - end else begin - if (is_static) then output "STATIC_"; - output ("HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ remap_name ^ "," ^ ret ^ ")\n\n"); - end *) - end; + end; + ) + (* let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in + let wrap = (needsWrapper return_type) || (List.exists needsWrapper tcpp_args) in + if wrap then begin + let wrapName = "_hx_wrap" ^ class_name ^ "_" ^ remap_name in + output ("static ::Dynamic " ^ wrapName ^ "( " ); + let sep = ref " " in + if not is_static then begin + output "::hx::Object *obj"; + sep := ","; + end; + ExtList.List.iteri (fun i _ -> output (!sep ^ "const Dynamic &a" ^ (string_of_int i)) ; sep:=",") tcpp_args; + output ( ") {\n\t"); + if not is_void then begin + match return_type with + | TCppStar _ -> + output "return (cpp::Pointer) " + | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> + output ("return (cpp::Struct< " ^ (tcpp_to_string return_type) ^ " >) "); + | _ -> output "return "; + end; - end else begin - ctx.ctx_real_this_ptr <- false; - let func_name = "__default_" ^ (remap_name) in - output ("HX_BEGIN_DEFAULT_FUNC(" ^ func_name ^ "," ^ class_name ^ ")\n"); - output return_type_str; - output (" _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")"); - gen_cpp_function_body ctx class_def is_static func_name function_def "" "" no_debug; + if is_static then + output (class_name ^ "::" ^ remap_name ^ "(") + else + output ("reinterpret_cast< " ^ class_name ^ " *>(obj)->" ^ remap_name ^ "("); + + sep := ""; + ExtList.List.iteri (fun i arg -> + output !sep; sep := ","; + (match arg with + | TCppStar (t,const) -> + output ("(cpp::" ^ (if const then "Const" else "") ^"Pointer<" ^ (tcpp_to_string t)^" >) ") + | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> + output ("(cpp::Struct< " ^ (tcpp_to_string arg) ^ " >) "); + | _ -> () ); + output ("a" ^ (string_of_int i)); + ) tcpp_args; - output ("HX_END_LOCAL_FUNC" ^ nargs ^ "(" ^ ret ^ ")\n"); - output ("HX_END_DEFAULT_FUNC\n\n"); + output ");\n"; - if (is_static) then - output ( "::Dynamic " ^ class_name ^ "::" ^ remap_name ^ ";\n\n"); - end; + if is_void then output "\treturn null();\n"; + output "}\n"; + let nName = string_of_int (List.length tcpp_args) in + output ("::Dynamic " ^ class_name ^ "::" ^ remap_name ^ "_dyn() {\n\treturn "); + if is_static then + output ("::hx::CreateStaticFunction" ^ nName ^ "(\"" ^ remap_name ^ "\"," ^ wrapName ^ ");") + else + output ("::hx::CreateMemberFunction" ^ nName ^ "(\"" ^ remap_name ^ "\",this," ^ wrapName ^ ");"); + output "}\n"; + end else begin + if (is_static) then output "STATIC_"; + output ("HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ remap_name ^ "," ^ ret ^ ")\n\n"); + end *) + end; ctx.ctx_debug_level <- orig_debug (* Data field *) @@ -4801,11 +4795,12 @@ let gen_member_def ctx class_def is_static is_interface field = | Some { eexpr = TFunction function_def } -> if ( is_dynamic_haxe_method field ) then begin if ( doDynamic ) then begin - output ("::Dynamic " ^ remap_name ^ ";\n"); + let func_signature = "::hx::Callable< " ^ (ctx_tfun_arg_list_signature ctx function_def) ^ " > " in + output (func_signature ^ remap_name ^ ";\n"); if (not is_static) && (is_gc_element ctx TCppDynamic) then output ("\t\tinline ::Dynamic _hx_set_" ^ remap_name ^ "(::hx::StackContext *_hx_ctx,::Dynamic _hx_v) { HX_OBJ_WB(this,_hx_v.mPtr) return " ^ remap_name ^ "=_hx_v; }\n"); output (if is_static then "\t\tstatic " else "\t\t"); - output ("inline ::Dynamic &" ^ remap_name ^ "_dyn() " ^ "{return " ^ remap_name^ "; }\n") + output ("inline " ^ func_signature ^ "&" ^ remap_name ^ "_dyn() " ^ "{return " ^ remap_name^ "; }\n") end end else begin let return_type = match ctx_type_string ctx function_def.tf_type with From bce1546ae552acbc5531e5c431467ebc2fc7d8d7 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 22 Apr 2023 20:48:14 +0100 Subject: [PATCH 12/39] Correctly generate default function bodies --- src/generators/gencpp.ml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 5d9d9f11b4c..a212b05ba84 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4587,11 +4587,15 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); output "\t{\n"; - output (if is_void then "\t\t" else "\t\treturn "); - (if is_static then - output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") - else - output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); + if is_dynamic_haxe_method field then begin + gen_cpp_function_body ctx class_def is_static ("__default_" ^ remap_name) function_def "" "" no_debug; + end else begin + output (if is_void then "\t\t" else "\t\treturn "); + (if is_static then + output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") + else + output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); + end; output "\t}\n"; From c07a870bb0456745de64378f10a8226ba93b0970 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sun, 23 Apr 2023 11:32:27 +0100 Subject: [PATCH 13/39] lets not try and get fancy with dynamic function code path --- src/generators/gencpp.ml | 184 +++++++++++++++------------------------ 1 file changed, 68 insertions(+), 116 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index a212b05ba84..bb72e21db89 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4543,6 +4543,48 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let orig_debug = ctx.ctx_debug_level in let no_debug = has_meta_key field.cf_meta Meta.NoDebug in + let func_signature = ctx_tfun_arg_list_signature ctx function_def in + let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in + let write_closure_header callable_name captures_obj = + output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); + output "{\n"; + + if captures_obj then begin + output ("\t" ^ obj_ptr_class_name ^ " __this;\n"); + output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "obj = null()) : __this(obj) {}\n"); + end else begin + output ("\t" ^ callable_name ^ "() {}\n"); + end; + + (* Implement the pure virtual function *) + + output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); + output "\t{\n"; + in + let write_closure_trailer captures_obj = + output "\t}\n"; + + (* Override the dynamic run functions *) + + output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); + output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); + output "); return null(); }\n"; + + output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); + output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); + + if captures_obj then begin + output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(__this); }\n"; + output "#ifdef HXCPP_VISIT_ALLOCS\n"; + output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(__this); }\n"; + output "#endif\n"; + end; + + (* TODO : Generate, compare, etc, etc *) + + output "};\n\n"; + in + (* The actual function definition *) if (not (is_dynamic_haxe_method field)) then begin let nativeImpl = get_meta_string field.cf_meta Meta.Native in @@ -4561,129 +4603,39 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output "}\n\n"; end else gen_cpp_function_body ctx class_def is_static field.cf_name function_def code tail_code no_debug; - end; - - output "\n\n"; - let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in - let doDynamic = (nonVirtual || not (is_override field ) ) && (reflective class_def field ) in - (* generate dynamic version too ... *) - if ( doDynamic ) then begin - let callable_name = if (is_dynamic_haxe_method field) then "__default_" ^ remap_name else "__" ^ class_name ^ remap_name in - let func_signature = ctx_tfun_arg_list_signature ctx function_def in - let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in - ( - output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); - output "{\n"; - - (if is_static then - output ("\t" ^ callable_name ^ "() {}\n") - else begin - output ("\t" ^ obj_ptr_class_name ^ " obj;\n"); - output ("\t" ^ callable_name ^ "(" ^ obj_ptr_class_name ^ "_obj) : obj(_obj) {}\n"); - end); - - (* Implement the pure virtual function *) - - output ("\t" ^ (tcpp_to_string return_type) ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); - output "\t{\n"; - - if is_dynamic_haxe_method field then begin - gen_cpp_function_body ctx class_def is_static ("__default_" ^ remap_name) function_def "" "" no_debug; - end else begin - output (if is_void then "\t\t" else "\t\treturn "); - (if is_static then - output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") - else - output ("obj->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n")); - end; - - output "\t}\n"; - - (* Override the dynamic run functions *) - - output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); - output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); - output "); return null(); }\n"; - - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); - output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); - - if (not is_static) then begin - output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(obj); }\n"; - output "#ifdef HXCPP_VISIT_ALLOCS\n"; - output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(obj); }\n"; - output "#endif\n"; - end; - (* TODO : Generate, compare, etc, etc *) - - output "};\n\n"; - - if is_dynamic_haxe_method field then begin - if is_static then begin - output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ ";\n\n") - end; - end else begin - output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); - output "{\n"; - output ("\treturn new " ^ callable_name ^ "(" ^ (if is_static then "" else "this") ^ ");\n"); - output "}\n\n"; - end; - ) - (* let tcpp_args = List.map (fun (v,_) -> cpp_type_of ctx v.v_type ) function_def.tf_args in - let wrap = (needsWrapper return_type) || (List.exists needsWrapper tcpp_args) in - if wrap then begin - let wrapName = "_hx_wrap" ^ class_name ^ "_" ^ remap_name in - output ("static ::Dynamic " ^ wrapName ^ "( " ); - let sep = ref " " in - if not is_static then begin - output "::hx::Object *obj"; - sep := ","; - end; - ExtList.List.iteri (fun i _ -> output (!sep ^ "const Dynamic &a" ^ (string_of_int i)) ; sep:=",") tcpp_args; - output ( ") {\n\t"); - if not is_void then begin - match return_type with - | TCppStar _ -> - output "return (cpp::Pointer) " - | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> - output ("return (cpp::Struct< " ^ (tcpp_to_string return_type) ^ " >) "); - | _ -> output "return "; - end; + output "\n\n"; + let nonVirtual = has_meta_key field.cf_meta Meta.NonVirtual in + let doDynamic = (nonVirtual || not (is_override field ) ) && (reflective class_def field ) in + (* generate dynamic version too ... *) + if ( doDynamic ) then begin + let callable_name = ("__" ^ class_name ^ remap_name) in + write_closure_header callable_name (not is_static); + output (if is_void then "\t\t" else "\t\treturn "); if is_static then - output (class_name ^ "::" ^ remap_name ^ "(") + output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") else - output ("reinterpret_cast< " ^ class_name ^ " *>(obj)->" ^ remap_name ^ "("); - - sep := ""; - ExtList.List.iteri (fun i arg -> - output !sep; sep := ","; - (match arg with - | TCppStar (t,const) -> - output ("(cpp::" ^ (if const then "Const" else "") ^"Pointer<" ^ (tcpp_to_string t)^" >) ") - | TCppInst(t, _) when has_meta_key t.cl_meta Meta.StructAccess -> - output ("(cpp::Struct< " ^ (tcpp_to_string arg) ^ " >) "); - | _ -> () ); - output ("a" ^ (string_of_int i)); - ) tcpp_args; + output ("__this->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n"); - output ");\n"; + write_closure_trailer (not is_static); - if is_void then output "\treturn null();\n"; - output "}\n"; - let nName = string_of_int (List.length tcpp_args) in - output ("::Dynamic " ^ class_name ^ "::" ^ remap_name ^ "_dyn() {\n\treturn "); - if is_static then - output ("::hx::CreateStaticFunction" ^ nName ^ "(\"" ^ remap_name ^ "\"," ^ wrapName ^ ");") - else - output ("::hx::CreateMemberFunction" ^ nName ^ "(\"" ^ remap_name ^ "\",this," ^ wrapName ^ ");"); - output "}\n"; - end else begin - if (is_static) then output "STATIC_"; - output ("HX_DEFINE_DYNAMIC_FUNC" ^ nargs ^ "(" ^ class_name ^ "," ^ remap_name ^ "," ^ ret ^ ")\n\n"); - end *) + output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ "_dyn()\n"); + output "{\n"; + output ("\treturn new " ^ callable_name ^ "(" ^ (if is_static then "" else "this") ^ ");\n"); + output "}\n\n"; end; + end else begin + write_closure_header ("__default_" ^ remap_name) true; + + ctx.ctx_real_this_ptr <- false; + gen_cpp_function_body ctx class_def is_static ("__default_" ^ remap_name) function_def "" "" no_debug; + + write_closure_trailer true; + + if is_static then + output ("::hx::Callable<" ^ func_signature ^ "> " ^ class_name ^ "::" ^ remap_name ^ ";\n\n") + end; ctx.ctx_debug_level <- orig_debug (* Data field *) From 1263f51d7d5ed7d6557deee8a82088e8863113d3 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Tue, 25 Apr 2023 18:05:41 +0100 Subject: [PATCH 14/39] round and round we go... --- src/generators/gencpp.ml | 75 +++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index bb72e21db89..69e69b7deac 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1390,7 +1390,6 @@ type tcpp = | TCppAutoCast | TCppDynamicArray | TCppObjectArray of tcpp - | TCppWrapped of tcpp | TCppScalarArray of tcpp | TCppObjC of tclass | TCppNativePointer of tclass @@ -1648,7 +1647,6 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with (tcpp_objc_block_struct argTypes retType) ^ "::t" | TCppDynamicArray -> "::cpp::VirtualArray" ^ suffix | TCppObjectArray _ -> "::Array" ^ suffix ^ "< ::Dynamic>" - | TCppWrapped t -> " ::hx::Null< " ^ (tcpp_to_string t) ^ " >" | TCppScalarArray(value) -> "::Array" ^ suffix ^ "< " ^ (tcpp_to_string value) ^ " >" | TCppObjC klass -> let path = join_class_path_remap klass.cl_path "::" in @@ -1777,7 +1775,7 @@ let rec cpp_is_native_array_access t = ;; let cpp_is_dynamic_type = function - | TCppDynamic | TCppObject | TCppVariant | TCppWrapped _ | TCppGlobal | TCppNull + | TCppDynamic | TCppObject | TCppVariant | TCppGlobal | TCppNull | TCppInterface _ -> true | _ -> false @@ -1903,7 +1901,6 @@ let rec cpp_type_of stack ctx haxe_type = | TCppVoid (* ? *) | TCppDynamic -> TCppDynamicArray - | TCppObject | TCppObjectPtr | TCppReference _ @@ -1923,14 +1920,14 @@ let rec cpp_type_of stack ctx haxe_type = ) | ([],"Null"), [p] -> - cpp_type_of_null stack ctx p false + cpp_type_of_null stack ctx p | _ -> default () - and cpp_type_of_null stack ctx p wrap = + and cpp_type_of_null stack ctx p = let baseType = cpp_type_of stack ctx p in if (type_has_meta_key p Meta.NotNull) || (is_cpp_scalar baseType) then - if wrap then TCppWrapped baseType else TCppObject + TCppObject else baseType and cpp_type_of_pointer stack ctx p = @@ -1938,19 +1935,13 @@ let rec cpp_type_of stack ctx haxe_type = | TAbstract ({ a_path = ([],"Null") },[t]) -> cpp_type_of stack ctx t | x -> cpp_type_of stack ctx x (* Optional types are Dynamic if they norally could not be null *) - and cpp_fun_arg_type_of stack ctx tvar opt = + and cpp_fun_arg_type_of stack ctx t opt = match opt with - | Some {eexpr = TConst TNull} -> cpp_type_of stack ctx tvar.t_type - | Some _ when (cant_be_null tvar.t_type) -> TCppWrapped (cpp_type_of stack ctx tvar.t_type) - | _ -> cpp_type_of stack ctx tvar.t_type + | Some _ -> cpp_type_of_null stack ctx t + | _ -> cpp_type_of stack ctx t and cpp_tfun_arg_type_of stack ctx opt t = - if opt then - match t with - | TAbstract({ a_path = ([], "Null") }, [ inner ]) -> cpp_type_of_null stack ctx inner true - | _ -> cpp_type_of stack ctx t - else - cpp_type_of stack ctx t + if opt then cpp_type_of_null stack ctx t else cpp_type_of stack ctx t and cpp_function_type_of stack ctx function_type abi = let abi = (match follow abi with @@ -1968,7 +1959,7 @@ let rec cpp_type_of stack ctx haxe_type = (* Optional types are Dynamic if they norally could not be null *) let cpp_arg_type_of = fun(_,optional,haxe_type) -> if optional then - cpp_type_of_null stack ctx haxe_type true + cpp_type_of_null stack ctx haxe_type else cpp_type_of stack ctx haxe_type in @@ -2043,7 +2034,6 @@ let rec cpp_object_name = function | TCppFunction(argTypes,retType,abi) -> let args = (String.concat "," (List.map tcpp_to_string argTypes)) in "::cpp::Function< " ^ abi ^ " " ^ (tcpp_to_string retType) ^ "(" ^ args ^ ") >" - | TCppWrapped _ -> "Dynamic" | TCppNativePointer klass -> (cpp_class_path_of klass) ^ " *" | TCppGlobal -> ""; | TCppNull -> "Dynamic"; @@ -2077,7 +2067,6 @@ let cpp_variant_type_of t = match t with | TCppDynamicArray | TCppObjectArray _ | TCppScalarArray _ - | TCppWrapped _ | TCppObjC _ | TCppObjCBlock _ | TCppRest _ @@ -2163,12 +2152,10 @@ let ctx_arg_type_name ctx name default_val arg_type prefix = let type_str = (ctx_type_string ctx arg_type) in match default_val with | Some {eexpr = TConst TNull} -> (type_str,remap_name) - | Some constant when (ctx_cant_be_null ctx constant.etype) -> ("::hx::Null< " ^ (ctx_type_string ctx constant.etype) ^ " > ",prefix ^ remap_name) + | Some constant when (ctx_cant_be_null ctx arg_type) -> ("::hx::Null< " ^ type_str ^ " > ",prefix ^ remap_name) | Some constant -> (type_str,prefix ^ remap_name) | _ -> (type_str,remap_name);; - - (* Generate prototype text, including allowing default values to be null *) let ctx_arg ctx name default_val arg_type prefix = let pair = ctx_arg_type_name ctx name default_val arg_type prefix in @@ -2206,12 +2193,24 @@ let rec ctx_tfun_arg_list ctx include_names arg_list = | (name,o,arg_type) :: remaining -> (oType o arg_type) ^ (if include_names then " " ^ (keyword_remap name) else "") ^ "," ^ (ctx_tfun_arg_list ctx include_names remaining) -let ctx_tfun_arg_list_signature ctx function_def = +let ctx_callable_signature ctx function_def = let return = cpp_type_of ctx function_def.tf_type |> tcpp_to_string in - let args = String.concat "," (List.map (fun (v,o) -> fst ( ctx_arg_type_name ctx v.v_name o v.v_type "" ) ) function_def.tf_args) in + let args = String.concat "," (List.map (fun (v,o) -> tcpp_to_string (cpp_fun_arg_type_of ctx v.v_type o) ) function_def.tf_args) in return ^ " ( " ^ args ^ " )" ;; +let ctx_callable_args ctx arg_list prefix = + let make_arg (v, o) = + let name = keyword_remap v.v_name in + let return = tcpp_to_string (cpp_fun_arg_type_of ctx v.v_type o) in + let prefixed = match o with + | Some {eexpr = TConst TNull} -> name + | Some _ -> prefix ^ name + | None -> name in + return ^ " " ^ prefixed in + String.concat "," (List.map make_arg arg_list) +;; + let cpp_var_type_of ctx var = tcpp_to_string (cpp_type_of ctx var.v_type) ;; @@ -2400,7 +2399,6 @@ let is_object_element ctx member_type = | TCppFunction _ | TCppDynamicArray | TCppObjectArray _ - | TCppWrapped _ | TCppScalarArray _ | TCppClass | TCppCallable _ @@ -2930,7 +2928,7 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in - let signature = ctx_tfun_arg_list_signature ctx func in + let signature = ctx_callable_signature ctx func in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; @@ -3485,7 +3483,7 @@ let gen_type ctx haxe_type = let cpp_closure_signature ctx closure = let func_type = tcpp_to_string closure.close_type in - let func_args = String.concat "," (List.map (fun (v,o) -> fst ( ctx_arg_type_name ctx v.v_name o v.v_type "" ) ) closure.close_args) in + let func_args = ctx_callable_args ctx closure.close_args "" in func_type ^ "(" ^ func_args ^ ")" ;; @@ -4317,7 +4315,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ ) closure.close_undeclared; out (") HXARGC(" ^ argsCount ^")\n"); - output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (cpp_arg_list ctx closure.close_args "__o_") ^ ")"); + output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ")"); let prologue = function gc_stack -> cpp_gen_default_values ctx closure.close_args "__o_"; @@ -4543,9 +4541,9 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let orig_debug = ctx.ctx_debug_level in let no_debug = has_meta_key field.cf_meta Meta.NoDebug in - let func_signature = ctx_tfun_arg_list_signature ctx function_def in + let func_signature = ctx_callable_signature ctx function_def in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in - let write_closure_header callable_name captures_obj = + let write_closure_header callable_name captures_obj prefix = output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); output "{\n"; @@ -4558,7 +4556,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* Implement the pure virtual function *) - output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_arg_list ctx function_def.tf_args "__o_") ^ ")\n"); + output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ")\n"); output "\t{\n"; in let write_closure_trailer captures_obj = @@ -4610,13 +4608,13 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* generate dynamic version too ... *) if ( doDynamic ) then begin let callable_name = ("__" ^ class_name ^ remap_name) in - write_closure_header callable_name (not is_static); + write_closure_header callable_name (not is_static) ""; output (if is_void then "\t\t" else "\t\treturn "); if is_static then - output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n") + output (class_name ^ "::" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "") ^ ");\n") else - output ("__this->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "__o_") ^ ");\n"); + output ("__this->" ^ remap_name ^ "(" ^ (ctx_arg_list_name ctx function_def.tf_args "") ^ ");\n"); write_closure_trailer (not is_static); @@ -4626,7 +4624,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output "}\n\n"; end; end else begin - write_closure_header ("__default_" ^ remap_name) true; + write_closure_header ("__default_" ^ remap_name) true "__o_"; ctx.ctx_real_this_ptr <- false; gen_cpp_function_body ctx class_def is_static ("__default_" ^ remap_name) function_def "" "" no_debug; @@ -4751,7 +4749,7 @@ let gen_member_def ctx class_def is_static is_interface field = | Some { eexpr = TFunction function_def } -> if ( is_dynamic_haxe_method field ) then begin if ( doDynamic ) then begin - let func_signature = "::hx::Callable< " ^ (ctx_tfun_arg_list_signature ctx function_def) ^ " > " in + let func_signature = "::hx::Callable< " ^ (ctx_callable_signature ctx function_def) ^ " > " in output (func_signature ^ remap_name ^ ";\n"); if (not is_static) && (is_gc_element ctx TCppDynamic) then output ("\t\tinline ::Dynamic _hx_set_" ^ remap_name ^ "(::hx::StackContext *_hx_ctx,::Dynamic _hx_v) { HX_OBJ_WB(this,_hx_v.mPtr) return " ^ remap_name ^ "=_hx_v; }\n"); @@ -4778,7 +4776,7 @@ let gen_member_def ctx class_def is_static is_interface field = output ");\n"; if ( doDynamic ) then begin output (if is_static then "\t\tstatic " else "\t\t"); - output ("::hx::Callable< " ^ (ctx_tfun_arg_list_signature ctx function_def) ^ "> " ^ remap_name ^ "_dyn();\n" ); + output ("::hx::Callable< " ^ (ctx_callable_signature ctx function_def) ^ "> " ^ remap_name ^ "_dyn();\n" ); end; end; output "\n"; @@ -7165,7 +7163,6 @@ let rec script_type_string haxe_type = let rec script_cpptype_string cppType = match cppType with | TCppDynamic | TCppUnchanged - | TCppWrapped _ | TCppCallable _ | TCppObject -> "Dynamic" | TCppObjectPtr -> ".*.hx.Object*" From 6cad8e2986db1b90c6453b75aff9cee93b190631 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Tue, 25 Apr 2023 18:42:47 +0100 Subject: [PATCH 15/39] Generate DoMarkThis / DoVisitThis functions for closures --- src/generators/gencpp.ml | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 69e69b7deac..99828d1166e 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4307,13 +4307,13 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ writer#add_big_closures; let argsCount = list_num closure.close_args in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); - out (if closure.close_this != None then "::hx::CallableThis_obj< " else "::hx::Callable_obj< "); + out ("::hx::Callable_obj< "); out (cpp_closure_signature ctx closure); out (">,_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> out ("," ^ (cpp_macro_var_type_of ctx var) ^ "," ^ (keyword_remap name)); ) closure.close_undeclared; - out (") HXARGC(" ^ argsCount ^")\n"); + out (")\n"); output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ")"); @@ -4333,6 +4333,18 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ in gen_with_injection (mk_injection prologue "" "") closure.close_expr true; + if closure.close_this=None then begin + output_i "inline void DoMarkThis(hx::MarkContext* __inCtx) {}\n"; + out "#ifdef HXCPP_VISIT_ALLOCS\n"; + output_i "inline void DoVisitThis(hx::VisitContext* __inCtx) {}\n"; + out "#endif\n"; + end else begin + output_i "inline void DoMarkThis(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(__this); }\n"; + out "#ifdef HXCPP_VISIT_ALLOCS\n"; + output_i "inline void DoVisitThis(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(__this); }\n"; + out "#endif\n"; + end; + let return = match closure.close_type with TCppVoid -> "(void)" | _ -> "return" in output_i ("HX_END_LOCAL_FUNC" ^ argsCount ^ "(" ^ return ^ ")\n\n"); @@ -4572,9 +4584,9 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); if captures_obj then begin - output "\tvoid __Mark(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(__this); }\n"; + output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; output "#ifdef HXCPP_VISIT_ALLOCS\n"; - output "\tvoid __Visit(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(__this); }\n"; + output "\tvoid __Visit(hx::VisitContext* __inCtx) override { HX_VISIT_MEMBER(__this); }\n"; output "#endif\n"; end; From bd6ed313484eee806670e8f233d45126b22e7c01 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Tue, 25 Apr 2023 20:28:25 +0100 Subject: [PATCH 16/39] generate compare overloads --- src/generators/gencpp.ml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 99828d1166e..cc799d0f0bc 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4306,16 +4306,17 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ if argc >= 20 || (List.length closure.close_args) >= 20 then writer#add_big_closures; let argsCount = list_num closure.close_args in + let signature = cpp_closure_signature ctx closure in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); out ("::hx::Callable_obj< "); - out (cpp_closure_signature ctx closure); + out signature; out (">,_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> out ("," ^ (cpp_macro_var_type_of ctx var) ^ "," ^ (keyword_remap name)); ) closure.close_undeclared; out (")\n"); - output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ")"); + output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ") override"); let prologue = function gc_stack -> cpp_gen_default_values ctx closure.close_args "__o_"; @@ -4333,6 +4334,10 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ in gen_with_injection (mk_injection prologue "" "") closure.close_expr true; + output_i "int __Compare(const ::hx::Object* inRhs) const override {\n"; + output_i ("\treturn dynamic_cast*>(inRhs) ? 0 : -1;\n"); + output_i "}\n"; + if closure.close_this=None then begin output_i "inline void DoMarkThis(hx::MarkContext* __inCtx) {}\n"; out "#ifdef HXCPP_VISIT_ALLOCS\n"; @@ -4566,9 +4571,11 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("\t" ^ callable_name ^ "() {}\n"); end; - (* Implement the pure virtual function *) + output "\tint __Compare(const ::hx::Object* inRhs) const override {\n"; + output ("\t\treturn dynamic_cast(inRhs) ? 0 : -1;\n"); + output "\t}\n"; - output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ")\n"); + output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ") override\n"); output "\t{\n"; in let write_closure_trailer captures_obj = From 94430861558cc2ba0e3c753ed8e65f000bdcd46e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 27 Apr 2023 16:45:23 +0100 Subject: [PATCH 17/39] Bump API level to 500 --- src/compiler/compiler.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/compiler.ml b/src/compiler/compiler.ml index e3dcd568ba6..0ae206f8781 100644 --- a/src/compiler/compiler.ml +++ b/src/compiler/compiler.ml @@ -119,7 +119,7 @@ module Setup = struct add_std "php"; "php" | Cpp -> - Common.define_value com Define.HxcppApiLevel "430"; + Common.define_value com Define.HxcppApiLevel "500"; add_std "cpp"; if Common.defined com Define.Cppia then actx.classes <- (Path.parse_path "cpp.cppia.HostClasses" ) :: actx.classes; From cd2d0ebe8f87da4769f979c0fd7e7f8945afe092 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 27 Apr 2023 16:46:08 +0100 Subject: [PATCH 18/39] Remove unused close_this from closure structure --- src/generators/gencpp.ml | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index cc799d0f0bc..c53cab81bb9 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1415,7 +1415,6 @@ and tcpp_closure = { close_expr : tcppexpr; close_id : int; close_undeclared : (string,tvar) Hashtbl.t; - close_this : tcppthis option; } @@ -2934,7 +2933,6 @@ let retype_expression ctx request_type function_args function_type expression_tr close_undeclared= !undeclared; close_type= ret; close_args= func.tf_args; - close_this= !uses_this; } in incr closureId; declarations := old_declarations; @@ -3888,11 +3886,6 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | CppCallable closure -> out (" ::hx::Callable<" ^ (cpp_closure_signature ctx closure )^ ">(new _hx_Closure_" ^ (string_of_int(closure.close_id)) ^ "("); let separator = ref "" in - (match closure.close_this with - | Some this -> - out (if this=ThisReal then "this" else "__this"); - separator := ","; - | _ -> () ); Hashtbl.iter (fun name value -> out !separator; separator := ","; @@ -4322,10 +4315,9 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ cpp_gen_default_values ctx closure.close_args "__o_"; hx_stack_push ctx output_i class_name func_name closure.close_expr.cpppos gc_stack; if (ctx.ctx_debug_level>=2) then begin - if (closure.close_this != None) then - output_i ("HX_STACK_THIS(__this.mPtr)\n"); - List.iter (fun (v,_) -> output_i ("HX_STACK_ARG(" ^ (cpp_var_name_of v) ^ ",\"" ^ (cpp_debug_name_of v) ^"\")\n") ) - (List.filter (cpp_debug_var_visible ctx) closure.close_args); + List.iter + (fun (v,_) -> output_i ("HX_STACK_ARG(" ^ (cpp_var_name_of v) ^ ",\"" ^ (cpp_debug_name_of v) ^"\")\n") ) + (List.filter (cpp_debug_var_visible ctx) closure.close_args); let line = Lexer.get_error_line closure.close_expr.cpppos in let lineName = Printf.sprintf "%4d" line in @@ -4338,18 +4330,6 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ output_i ("\treturn dynamic_cast*>(inRhs) ? 0 : -1;\n"); output_i "}\n"; - if closure.close_this=None then begin - output_i "inline void DoMarkThis(hx::MarkContext* __inCtx) {}\n"; - out "#ifdef HXCPP_VISIT_ALLOCS\n"; - output_i "inline void DoVisitThis(hx::VisitContext* __inCtx) {}\n"; - out "#endif\n"; - end else begin - output_i "inline void DoMarkThis(hx::MarkContext* __inCtx) { HX_MARK_MEMBER(__this); }\n"; - out "#ifdef HXCPP_VISIT_ALLOCS\n"; - output_i "inline void DoVisitThis(hx::VisitContext* __inCtx) { HX_VISIT_MEMBER(__this); }\n"; - out "#endif\n"; - end; - let return = match closure.close_type with TCppVoid -> "(void)" | _ -> "return" in output_i ("HX_END_LOCAL_FUNC" ^ argsCount ^ "(" ^ return ^ ")\n\n"); From a47b9e0fa9974988bc590743c728e726b92d303d Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 27 Apr 2023 16:46:50 +0100 Subject: [PATCH 19/39] Use pre-existing macros for generating dynamic run functions --- src/generators/gencpp.ml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index c53cab81bb9..26b15aa50cc 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4309,7 +4309,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ ) closure.close_undeclared; out (")\n"); - output_i ((tcpp_to_string closure.close_type) ^ " _hx_run(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ") override"); + output_i ((tcpp_to_string closure.close_type) ^ " HX_LOCAL_RUN(" ^ (ctx_callable_args ctx closure.close_args "__o_") ^ ") override"); let prologue = function gc_stack -> cpp_gen_default_values ctx closure.close_args "__o_"; @@ -4555,20 +4555,13 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output ("\t\treturn dynamic_cast(inRhs) ? 0 : -1;\n"); output "\t}\n"; - output ("\t" ^ return_type_str ^ " _hx_run(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ") override\n"); + output ("\t" ^ return_type_str ^ " HX_LOCAL_RUN(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ") override\n"); output "\t{\n"; in let write_closure_trailer captures_obj = output "\t}\n"; - (* Override the dynamic run functions *) - - output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ (if is_void then "" else "return") ^ " _hx_run("); - output (String.concat ", " (List.init (List.length function_def.tf_args) (fun i -> ("inArgs[" ^ (string_of_int i) ^ "]")))); - output "); return null(); }\n"; - - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); - output ("{" ^ (if is_void then "" else "return") ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i _ -> ("inArg" ^ (string_of_int i))) function_def.tf_args)) ^ "); return null(); }\n"); + output ( "HX_DYNAMIC_CALL" ^ string_of_int (List.length function_def.tf_args) ^ "(" ^ (if is_void then "" else "return") ^ ", HX_LOCAL_RUN)"); if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; From 11e2d078480c0cb305571aae480de7d531189d4e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 27 Apr 2023 21:42:28 +0100 Subject: [PATCH 20/39] Mangle default function objects in the same way as _dyn function objects --- src/generators/gencpp.ml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 26b15aa50cc..2320863d9d5 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4561,7 +4561,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let write_closure_trailer captures_obj = output "\t}\n"; - output ( "HX_DYNAMIC_CALL" ^ string_of_int (List.length function_def.tf_args) ^ "(" ^ (if is_void then "" else "return") ^ ", HX_LOCAL_RUN)"); + output ( "HX_DYNAMIC_CALL" ^ nargs ^ "(" ^ (if is_void then "" else "return") ^ ", HX_LOCAL_RUN)"); if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; @@ -4616,10 +4616,10 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface output "}\n\n"; end; end else begin - write_closure_header ("__default_" ^ remap_name) true "__o_"; + write_closure_header ("__default_" ^ class_name ^ remap_name) true "__o_"; ctx.ctx_real_this_ptr <- false; - gen_cpp_function_body ctx class_def is_static ("__default_" ^ remap_name) function_def "" "" no_debug; + gen_cpp_function_body ctx class_def is_static ("__default_" ^ class_name ^ remap_name) function_def "" "" no_debug; write_closure_trailer true; @@ -4664,7 +4664,9 @@ let gen_field_init ctx class_def field = (* Function field *) | Some { eexpr = TFunction function_def } -> if (is_dynamic_haxe_method field) then begin - let func_name = "__default_" ^ (remap_name) in + let nativeGen = has_meta_key class_def.cl_meta Meta.NativeGen in + let class_name = (snd class_def.cl_path) ^ (if nativeGen then "" else "_obj") in + let func_name = "__default_" ^ class_name ^ remap_name in output ( "\t" ^ remap_name ^ " = new " ^ func_name ^ ";\n\n" ); end @@ -6120,7 +6122,7 @@ let generate_class_files baseCtx super_deps constructor_deps class_def inScripta if (List.length dynamic_functions > 0) then begin output_cpp ("void " ^ class_name ^ "::__alloc_dynamic_functions(::hx::Ctx *_hx_ctx," ^ class_name ^ " *_hx_obj) {\n"); List.iter (fun name -> - output_cpp ("\tif (!_hx_obj->" ^ name ^".mPtr) _hx_obj->" ^ name ^ " = new __default_" ^ name ^ "(_hx_obj);\n") + output_cpp ("\tif (!_hx_obj->" ^ name ^".mPtr) _hx_obj->" ^ name ^ " = new __default_" ^ class_name ^ name ^ "(_hx_obj);\n") ) dynamic_functions; (match class_def.cl_super with | Some super -> @@ -6149,7 +6151,7 @@ let generate_class_files baseCtx super_deps constructor_deps class_def inScripta if ( (not (has_class_flag class_def CInterface)) && (not nativeGen) ) then begin output_cpp (class_name ^ "::" ^ class_name ^ "()\n{\n"); List.iter (fun name -> - output_cpp ("\t" ^ name ^ " = new __default_" ^ name ^ "(this);\n") + output_cpp ("\t" ^ name ^ " = new __default_" ^ class_name ^ name ^ "(this);\n") ) dynamic_functions; output_cpp "}\n\n"; From c9c7c59585878b62a53713717ba2470e180e2578 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 28 Apr 2023 19:06:30 +0100 Subject: [PATCH 21/39] Add struct and pointer wrapping back for dynamic run functions --- src/generators/gencpp.ml | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 2320863d9d5..9c0826ada0f 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4525,16 +4525,10 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface (* Function field *) | Some { eexpr = TFunction function_def } -> let return_type_str = (ctx_type_string ctx function_def.tf_type) in - let nargs = string_of_int (List.length function_def.tf_args) in let return_type = (cpp_type_of ctx function_def.tf_type ) in let is_void = return_type = TCppVoid in let ret = if is_void then "(void)" else "return " in - let needsWrapper t = match t with - | TCppStar _ -> true - | TCppInst(t, _) -> has_meta_key t.cl_meta Meta.StructAccess - | _ -> false - in let orig_debug = ctx.ctx_debug_level in let no_debug = has_meta_key field.cf_meta Meta.NoDebug in @@ -4561,7 +4555,36 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let write_closure_trailer captures_obj = output "\t}\n"; - output ( "HX_DYNAMIC_CALL" ^ nargs ^ "(" ^ (if is_void then "" else "return") ^ ", HX_LOCAL_RUN)"); + (* Override the dynamic run functions *) + + let return_string = + if is_void then + "" + else + "return " ^ match return_type with + | TCppStar _ -> + "(::cpp::Pointer)" + | TCppInst (klass, _) when has_meta_key klass.cl_meta Meta.StructAccess -> + "(::cpp::Struct<" ^ return_type_str ^ ">)" + | _ -> "" in + + let arg_callsite_prefix t = + let tcpp = cpp_type_of ctx t in + match tcpp with + | TCppStar (tcpp, is_const) -> + let const_str = if is_const then "Const" else "" in + let ptr_str = tcpp_to_string tcpp in + "::cpp::" ^ const_str ^ "Pointer<" ^ ptr_str ^ ">" + | TCppInst (klass, _) when has_meta_key klass.cl_meta Meta.StructAccess -> + "::cpp::Struct<" ^ (tcpp_to_string tcpp) ^ ">" + | _ -> "" in + + output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ return_string ^ " _hx_run("); + output (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArgs[" ^ (string_of_int i) ^ "])")) function_def.tf_args)); + output "); return null(); }\n"; + + output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); + output ("{" ^ return_string ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArg" ^ (string_of_int i) ^ ")")) function_def.tf_args)) ^ "); return null(); }\n"); if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; From 2225377692af34da0050d275418c584f6cdce542 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Mon, 8 May 2023 21:11:56 +0100 Subject: [PATCH 22/39] it works! commit it before I cock it up --- src/generators/gencpp.ml | 55 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 9c0826ada0f..811ad740cac 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1782,10 +1782,6 @@ let cpp_is_dynamic_type = function let rec cpp_type_of stack ctx haxe_type = - if List.exists (fast_eq haxe_type) stack then - TCppDynamic - else begin - let stack = haxe_type :: stack in (match haxe_type with | TMono r -> (match r.tm_type with None -> TCppDynamic | Some t -> cpp_type_of stack ctx t) @@ -1813,8 +1809,54 @@ let rec cpp_type_of stack ctx haxe_type = TCppDynamic) | TType (type_def,params) -> - cpp_type_from_path stack ctx type_def.t_path params (fun () -> - cpp_type_of stack ctx (apply_typedef type_def params) ) + let expected = (apply_typedef type_def params) in + let rec find t = + Printf.printf "\t%s\n" (s_type_kind t); + if fast_eq expected t then begin + Printf.printf "\tmatch!\n"; + true + end else + match t with + | TMono r -> + (match r.tm_type with + | None -> false + | Some t -> find t) + | TEnum (_,tl) | TInst (_,tl) -> + List.exists find tl + | TAbstract (abs,tl) -> + if (find (Abstract.get_underlying_type ~return_first:true abs tl)) then + true + else + List.exists find tl + | TType (tdef,tl) -> + let applied = apply_typedef tdef tl in + + Printf.printf "\tTType\n"; + Printf.printf "\t\t%s\n" (s_type (print_context()) t); + Printf.printf "\t\t%s\n" (s_type (print_context()) applied); + + find applied + | TFun (tl,r) -> + if (find r) then + true + else begin + List.exists (fun (_,_,targ) -> find targ) tl + end + | TLazy f -> + find (lazy_type f) + | TDynamic (Some t2) -> + find t2 + | _ -> false + in + Printf.printf "searching for %s\n" (s_type_kind expected); + + if find expected then + TCppDynamic + else begin + let stack = (haxe_type :: stack) in + cpp_type_from_path stack ctx type_def.t_path params (fun () -> + cpp_type_of stack ctx (apply_typedef type_def params) ) + end | TFun (args, return) -> let fargs = List.map (fun (_, o, t) -> cpp_tfun_arg_type_of stack ctx o t) args |> List.map tcpp_to_string in @@ -1826,7 +1868,6 @@ let rec cpp_type_of stack ctx haxe_type = | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) ) - end and cpp_type_from_path stack ctx path params default = match path,params with | ([],"Void"),_ -> TCppVoid From 8fd73b142f4a8bb9e730d6e438d6de84c4fe2bd0 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sun, 14 May 2023 18:36:33 +0100 Subject: [PATCH 23/39] this actually works, I think... --- src/generators/gencpp.ml | 53 +++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 811ad740cac..64f0f651256 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1782,6 +1782,10 @@ let cpp_is_dynamic_type = function let rec cpp_type_of stack ctx haxe_type = + if List.exists (fast_eq haxe_type) stack then + TCppDynamic + else + let stack = haxe_type :: stack in (match haxe_type with | TMono r -> (match r.tm_type with None -> TCppDynamic | Some t -> cpp_type_of stack ctx t) @@ -1809,54 +1813,41 @@ let rec cpp_type_of stack ctx haxe_type = TCppDynamic) | TType (type_def,params) -> - let expected = (apply_typedef type_def params) in - let rec find t = - Printf.printf "\t%s\n" (s_type_kind t); - if fast_eq expected t then begin - Printf.printf "\tmatch!\n"; + let rec find s t = + if List.exists (fast_eq t) s then begin true end else + let s = t :: s in match t with | TMono r -> (match r.tm_type with | None -> false - | Some t -> find t) + | Some t -> find s t) | TEnum (_,tl) | TInst (_,tl) -> - List.exists find tl + List.exists (find s) tl | TAbstract (abs,tl) -> - if (find (Abstract.get_underlying_type ~return_first:true abs tl)) then + if not (Meta.has Meta.CoreType abs.a_meta) && (find s (Abstract.get_underlying_type ~return_first:true abs tl)) then true else - List.exists find tl + List.exists (find s) tl | TType (tdef,tl) -> - let applied = apply_typedef tdef tl in - - Printf.printf "\tTType\n"; - Printf.printf "\t\t%s\n" (s_type (print_context()) t); - Printf.printf "\t\t%s\n" (s_type (print_context()) applied); - - find applied + find s (apply_typedef tdef tl) | TFun (tl,r) -> - if (find r) then + if (find s r) then true else begin - List.exists (fun (_,_,targ) -> find targ) tl + List.exists (fun (_,_,targ) -> (find s targ)) tl end | TLazy f -> - find (lazy_type f) + find s (lazy_type f) | TDynamic (Some t2) -> - find t2 + find s t2 | _ -> false - in - Printf.printf "searching for %s\n" (s_type_kind expected); - - if find expected then - TCppDynamic - else begin - let stack = (haxe_type :: stack) in - cpp_type_from_path stack ctx type_def.t_path params (fun () -> - cpp_type_of stack ctx (apply_typedef type_def params) ) - end + in + if find [] haxe_type then + cpp_type_from_path stack ctx type_def.t_path params (fun () -> TCppDynamic) + else + cpp_type_from_path stack ctx type_def.t_path params (fun () -> cpp_type_of stack ctx (apply_typedef type_def params)) | TFun (args, return) -> let fargs = List.map (fun (_, o, t) -> cpp_tfun_arg_type_of stack ctx o t) args |> List.map tcpp_to_string in @@ -1868,7 +1859,7 @@ let rec cpp_type_of stack ctx haxe_type = | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) ) - and cpp_type_from_path stack ctx path params default = + and cpp_type_from_path stack ctx path params default = match path,params with | ([],"Void"),_ -> TCppVoid | ([],"void"),_ -> TCppVoid (* for old code with @:void *) From 8a69c01c0c9f63ab5ffb3f007652e70def18c436 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sun, 14 May 2023 22:17:50 +0100 Subject: [PATCH 24/39] Remove the now un-needed manual __Run implementation --- src/generators/gencpp.ml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 64f0f651256..9e14b48b27a 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4611,9 +4611,6 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface "::cpp::Struct<" ^ (tcpp_to_string tcpp) ^ ">" | _ -> "" in - output ("\t::Dynamic __Run(const Array< ::Dynamic>& inArgs) { " ^ return_string ^ " _hx_run("); - output (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArgs[" ^ (string_of_int i) ^ "])")) function_def.tf_args)); - output "); return null(); }\n"; output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); output ("{" ^ return_string ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArg" ^ (string_of_int i) ^ ")")) function_def.tf_args)) ^ "); return null(); }\n"); From 16d0d2814bc5f7882bc4f27bcd2860d242df9610 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sun, 14 May 2023 22:18:25 +0100 Subject: [PATCH 25/39] Use the HX_LOCAL_RUN macro instead of _hx_run --- src/generators/gencpp.ml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 9e14b48b27a..08ac045eeb4 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4611,9 +4611,8 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface "::cpp::Struct<" ^ (tcpp_to_string tcpp) ^ ">" | _ -> "" in - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); - output ("{" ^ return_string ^ " _hx_run(" ^ (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArg" ^ (string_of_int i) ^ ")")) function_def.tf_args)) ^ "); return null(); }\n"); + output ("{" ^ return_string ^ " HX_LOCAL_RUN(" ^ (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArg" ^ (string_of_int i) ^ ")")) function_def.tf_args)) ^ "); return null(); }\n"); if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; From 44ac0e62f17609128820e0e429a55ffb20d5f92f Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sun, 14 May 2023 22:18:58 +0100 Subject: [PATCH 26/39] Revert now un-needed forgotten about change which broke some tests --- src/generators/gencpp.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 08ac045eeb4..073dfb63109 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -3451,7 +3451,7 @@ let cpp_gen_default_values ctx args prefix = match o with | Some {eexpr = TConst TNull} -> () | Some const -> - let vtype = cpp_type_of ctx const.etype in + let vtype = cpp_type_of ctx tvar.v_type in let not_null = (type_has_meta_key tvar.v_type Meta.NotNull) || (is_cpp_scalar vtype) in let name = cpp_var_name_of tvar in let spacer = if (ctx.ctx_debug_level>0) then " \t" else "" in From 886e07f6338d58f810d9786da093449d7acb09c5 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Mon, 15 May 2023 12:20:42 +0100 Subject: [PATCH 27/39] Update closure __Compare to dynamic cast to a type of itself --- src/generators/gencpp.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 073dfb63109..9cd8a16beb5 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4359,7 +4359,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ gen_with_injection (mk_injection prologue "" "") closure.close_expr true; output_i "int __Compare(const ::hx::Object* inRhs) const override {\n"; - output_i ("\treturn dynamic_cast*>(inRhs) ? 0 : -1;\n"); + output_i ("\treturn dynamic_cast(inRhs) ? 0 : -1;\n"); output_i "}\n"; let return = match closure.close_type with TCppVoid -> "(void)" | _ -> "return" in From 2a0c1b24d8827ce2f8403e760abbefde60eeb67d Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Mon, 15 May 2023 12:22:14 +0100 Subject: [PATCH 28/39] Update function closures to compare class pointers if they capture --- src/generators/gencpp.ml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 9cd8a16beb5..5a4510f2df1 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4578,7 +4578,11 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface end; output "\tint __Compare(const ::hx::Object* inRhs) const override {\n"; - output ("\t\treturn dynamic_cast(inRhs) ? 0 : -1;\n"); + output ("\t\tauto casted = dynamic_cast(inRhs);\n"); + output "\t\tif (!casted) return -1;\n"; + if captures_obj then + output "\t\tif (__this != casted->__this) return 1;\n"; + output "\t\treturn 0;"; output "\t}\n"; output ("\t" ^ return_type_str ^ " HX_LOCAL_RUN(" ^ (ctx_callable_args ctx function_def.tf_args prefix) ^ ") override\n"); From 7af8eacc95710b8774a865b1b3faf95da4f10d64 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Tue, 16 May 2023 21:57:26 +0100 Subject: [PATCH 29/39] Do not use Dynamic for variable _dyn callables --- src/generators/gencpp.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 5a4510f2df1..dd006b8ef65 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4865,9 +4865,10 @@ let gen_member_def ctx class_def is_static is_interface field = (* Add a "dyn" function for variable to unify variable/function access *) (match follow field.cf_type with | _ when nativeGen -> () - | TFun (_,_) -> + | TFun (tArgs,tRet) -> + let type_string = "::hx::Callable<" ^ (tcpp_to_string (cpp_type_of ctx tRet)) ^ "(" ^ (ctx_tfun_arg_list ctx false tArgs) ^ ")> " in output (if is_static then "\t\tstatic " else "\t\t"); - output ("Dynamic " ^ remap_name ^ "_dyn() { return " ^ remap_name ^ ";}\n" ) + output (type_string ^ remap_name ^ "_dyn() { return " ^ remap_name ^ ";}\n" ) | _ -> (match field.cf_kind with | Var { v_read = AccCall } when (not is_static) && (is_dynamic_accessor ("get_" ^ field.cf_name) "get" field class_def) -> output ("\t\tDynamic get_" ^ field.cf_name ^ ";\n" ) From e4c463cf1d9f8a67b4c7ce7e10ca32adaacd3cee Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Tue, 16 May 2023 21:57:44 +0100 Subject: [PATCH 30/39] Don't generate __run functions --- src/generators/gencpp.ml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index dd006b8ef65..1c3b1ef769c 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4615,9 +4615,6 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface "::cpp::Struct<" ^ (tcpp_to_string tcpp) ^ ">" | _ -> "" in - output ("\t::Dynamic __run(" ^ (String.concat "," (List.mapi (fun i _ -> ("const ::Dynamic& inArg" ^ (string_of_int i))) function_def.tf_args)) ^ ")"); - output ("{" ^ return_string ^ " HX_LOCAL_RUN(" ^ (String.concat ", " (List.mapi (fun i (tvar, _) -> ((arg_callsite_prefix tvar.v_type) ^ "(inArg" ^ (string_of_int i) ^ ")")) function_def.tf_args)) ^ "); return null(); }\n"); - if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; output "#ifdef HXCPP_VISIT_ALLOCS\n"; From eff2bf63776935a92df7e568346c9e4ecaa81598 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 1 Jun 2023 20:39:04 +0100 Subject: [PATCH 31/39] Remove dead code --- src/generators/gencpp.ml | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index f6f6e30835b..ab69548fe2a 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4590,31 +4590,6 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface in let write_closure_trailer captures_obj = output "\t}\n"; - - (* Override the dynamic run functions *) - - let return_string = - if is_void then - "" - else - "return " ^ match return_type with - | TCppStar _ -> - "(::cpp::Pointer)" - | TCppInst (klass, _) when has_meta_key klass.cl_meta Meta.StructAccess -> - "(::cpp::Struct<" ^ return_type_str ^ ">)" - | _ -> "" in - - let arg_callsite_prefix t = - let tcpp = cpp_type_of ctx t in - match tcpp with - | TCppStar (tcpp, is_const) -> - let const_str = if is_const then "Const" else "" in - let ptr_str = tcpp_to_string tcpp in - "::cpp::" ^ const_str ^ "Pointer<" ^ ptr_str ^ ">" - | TCppInst (klass, _) when has_meta_key klass.cl_meta Meta.StructAccess -> - "::cpp::Struct<" ^ (tcpp_to_string tcpp) ^ ">" - | _ -> "" in - if captures_obj then begin output "\tvoid __Mark(hx::MarkContext* __inCtx) override { HX_MARK_MEMBER(__this); }\n"; output "#ifdef HXCPP_VISIT_ALLOCS\n"; From 750d4cd3ded8bd2c8f061362b42bec53bcadc21d Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 1 Jun 2023 20:40:38 +0100 Subject: [PATCH 32/39] Static cast for callables --- src/generators/gencpp.ml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index ab69548fe2a..a0ec24cd818 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1945,6 +1945,7 @@ let rec cpp_type_of stack ctx haxe_type = | TCppDynamicArray | TCppObjectArray _ | TCppScalarArray _ + | TCppCallable _ -> TCppObjectArray(arrayOf) | _ -> TCppScalarArray(arrayOf) @@ -4033,7 +4034,9 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | TCppDynamicArray | TCppClass | TCppEnum _ - | TCppInst _ -> out (".StaticCast< " ^ (tcpp_to_string valueType ) ^ " >()") + | TCppInst _ + | TCppCallable _ + -> out (".StaticCast< " ^ (tcpp_to_string valueType ) ^ " >()") | _ ->() ) From 11ea49488fb185b9118078af5c63241c38ec7854 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 14 Jul 2023 22:16:41 +0100 Subject: [PATCH 33/39] Special case for templated array map --- src/generators/gencpp.ml | 73 +++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index a0ec24cd818..4aa52c61f03 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1442,7 +1442,7 @@ and tcppvarloc = | VarInternal of tcppexpr * string * string and tcppinst = - | InstPtr + | InstPtr of tcpp | InstObjC | InstStruct @@ -1564,7 +1564,7 @@ let rec s_tcpp = function | CppCall (FuncThis _,_) -> "CppCallThis" | CppCall (FuncInstance (obj,inst,field),_) -> - (match inst with InstObjC -> "CppCallObjCInstance(" | InstPtr-> "CppCallInstance(" | _ -> "CppCallStruct(") ^ + (match inst with InstObjC -> "CppCallObjCInstance(" | InstPtr _ -> "CppCallInstance(" | _ -> "CppCallStruct(") ^ tcpp_to_string obj.cpptype ^ "," ^ field.cf_name ^ ")" | CppCall (FuncInterface _,_) -> "CppCallInterface" | CppCall (FuncStatic (_,objC,_),_) -> if objC then "CppCallStaticObjC" else "CppCallStatic" @@ -2607,7 +2607,7 @@ let retype_expression ctx request_type function_args function_type expression_tr CppNullAccess, TCppDynamic else if retypedObj.cpptype=TCppDynamic && not (has_class_flag clazz CInterface) then begin if is_internal_member member.cf_name then - CppFunction( FuncInstance(retypedObj,InstPtr,member), funcReturn ), exprType + CppFunction( FuncInstance(retypedObj,InstPtr(clazzType),member), funcReturn ), exprType else CppDynamicField(retypedObj, member.cf_name), TCppVariant end else if cpp_is_struct_access retypedObj.cpptype then begin @@ -2661,14 +2661,19 @@ let retype_expression ctx request_type function_args function_type expression_tr | _ -> false in (* Special array return values *) let funcReturn = - if isArrayObj then match member.cf_name with - | "map" -> TCppDynamicArray - | "splice" - | "slice" - | "concat" - | "copy" - | "filter" -> retypedObj.cpptype - | _ -> funcReturn + if isArrayObj then match member.cf_name with + | "map" -> + (match expr.etype with + | TFun (_, ret) -> + cpp_type_of ret + | _ -> + die "map expr type should be TFun" __LOC__) + | "splice" + | "slice" + | "concat" + | "copy" + | "filter" -> retypedObj.cpptype + | _ -> funcReturn else match retypedObj.cpptype, funcReturn with | TCppPointer(_,t), TCppDynamic | TCppRawPointer(_,t), TCppDynamic (* the 'type parameter' will show up as Dynamic *) @@ -2681,7 +2686,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | CppSuper this -> CppFunction( FuncSuper(this, retypedObj.cpptype,member), funcReturn ), exprType | _ -> - CppFunction( FuncInstance(retypedObj,(if is_objc then InstObjC else InstPtr),member), funcReturn ), exprType + CppFunction( FuncInstance(retypedObj,(if is_objc then InstObjC else InstPtr(clazzType)),member), funcReturn ), exprType ) end @@ -2782,13 +2787,13 @@ let retype_expression ctx request_type function_args function_type expression_tr (* Not actually a TCall...*) retypedFunc.cppexpr, retypedFunc.cpptype - | CppFunction( FuncInstance(obj, InstPtr, member), _ ) when not forCppia && return_type=TCppVoid && is_array_splice_call obj member -> + | CppFunction( FuncInstance(obj, InstPtr tcpp, member), _ ) when not forCppia && return_type=TCppVoid && is_array_splice_call obj member -> let retypedArgs = List.map (retype TCppDynamic ) args in - CppCall( FuncInstance(obj, InstPtr, {member with cf_name="removeRange"}), retypedArgs), TCppVoid + CppCall( FuncInstance(obj, InstPtr tcpp, {member with cf_name="removeRange"}), retypedArgs), TCppVoid - | CppFunction( FuncInstance(obj, InstPtr, member), _ ) when is_array_concat_call obj member -> + | CppFunction( FuncInstance(obj, InstPtr tcpp, member), _ ) when is_array_concat_call obj member -> let retypedArgs = List.map (retype obj.cpptype) args in - CppCall( FuncInstance(obj, InstPtr, member), retypedArgs), return_type + CppCall( FuncInstance(obj, InstPtr tcpp, member), retypedArgs), return_type | CppFunction( FuncStatic(obj, false, member), _ ) when member.cf_name = "::hx::AddressOf" -> let arg = retype TCppUnchanged (List.hd args) in @@ -2822,7 +2827,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | _ -> abort "First parameter of template function must be a Class" retypedFunc.cpppos ) - | CppFunction( FuncInstance(obj, InstPtr, member), _ ) when is_map_get_call obj member -> + | CppFunction( FuncInstance(obj, InstPtr tcpp, member), _ ) when is_map_get_call obj member -> let retypedArgs = List.map (retype TCppDynamic ) args in let fname, cppType = match return_type with | TCppVoid | TCppScalar("bool") -> (if forCppia then "getBool" else "get_bool"), return_type @@ -2832,7 +2837,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppString -> (if forCppia then "getString" else "get_string"), return_type | _ -> "get", TCppDynamic in - let func = FuncInstance(obj, InstPtr, {member with cf_name=fname}) in + let func = FuncInstance(obj, InstPtr tcpp, {member with cf_name=fname}) in (* if cpp_can_static_cast cppType return_type then begin let call = mk_cppexpr (CppCall(func,retypedArgs)) cppType in @@ -2842,7 +2847,7 @@ let retype_expression ctx request_type function_args function_type expression_tr CppCall( func, retypedArgs), cppType - | CppFunction( FuncInstance(obj, InstPtr, member), _ ) when forCppia && is_map_set_call obj member -> + | CppFunction( FuncInstance(obj, InstPtr tcpp, member), _ ) when forCppia && is_map_set_call obj member -> let retypedArgs = List.map (retype TCppDynamic ) args in let fname = match retypedArgs with | [_;{cpptype=TCppScalar("bool")}] -> "setBool" @@ -2852,11 +2857,11 @@ let retype_expression ctx request_type function_args function_type expression_tr | [_;{cpptype=TCppString}] -> "setString" | _ -> "set" in - let func = FuncInstance(obj, InstPtr, {member with cf_name=fname}) in + let func = FuncInstance(obj, InstPtr tcpp, {member with cf_name=fname}) in CppCall( func, retypedArgs), cppType - | CppFunction( FuncInstance(obj,InstPtr,member) as func, returnType ) when cpp_can_static_cast returnType cppType -> + | CppFunction( FuncInstance(obj,InstPtr _,member) as func, returnType ) when cpp_can_static_cast returnType cppType -> let retypedArgs = List.map (retype TCppDynamic ) args in let call = mk_cppexpr (CppCall(func,retypedArgs)) returnType in CppCastStatic(call, cppType), cppType @@ -3621,12 +3626,32 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ out "->_hx_getIndex()" | CppNullAccess -> out ("::hx::Throw(" ^ strq "Null access" ^ ")") - | CppFunction(func,_) -> + | CppFunction(func,tcpp) -> (match func with | FuncThis(field,_) -> out ("this->" ^ (cpp_member_name_of field) ^ "_dyn()"); - | FuncInstance(expr,inst,field) -> - gen expr; out ((if expr.cpptype=TCppString || inst=InstStruct then "." else "->") ^ (cpp_member_name_of field) ^ "_dyn()"); + | FuncInstance(f_expr,inst,field) -> + (* array map is a special case as it is implemented as a templated function *) + (* so we need to figure out the target array type of the map function to generate the template params *) + let template_extra = + if (field.cf_name="map") then + match inst with + | InstPtr (TCppObjectArray _) + | InstPtr (TCppScalarArray _) + | InstPtr TCppDynamicArray -> + (match tcpp with + | TCppObjectArray el + | TCppScalarArray el -> + "< " ^ (tcpp_to_string el) ^ " >" + | TCppDynamicArray -> + tcpp_to_string tcpp + | _ -> + die "map return type should be an array" __LOC__) + | _ -> + "" + else + "" in + gen f_expr; out ((if f_expr.cpptype=TCppString || inst=InstStruct then "." else "->") ^ (cpp_member_name_of field) ^ "_dyn" ^ template_extra ^ "()"); | FuncInterface(expr,_,field) -> gen expr; out ("->__Field(" ^ strq field.cf_name ^ ", ::hx::paccDynamic)") From 8cf3a207b0453d1e5deceafbe7967a5da519c3cb Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 15 Jul 2023 11:37:18 +0100 Subject: [PATCH 34/39] Fix wrong return type for array map calls which create a dynamic array --- src/generators/gencpp.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 4aa52c61f03..68c771a0758 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -3644,7 +3644,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | TCppScalarArray el -> "< " ^ (tcpp_to_string el) ^ " >" | TCppDynamicArray -> - tcpp_to_string tcpp + tcpp_to_string TCppDynamic | _ -> die "map return type should be an array" __LOC__) | _ -> From 4b82bd013b728740cfb5796cb612706a5890345e Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Wed, 19 Jul 2023 22:58:42 +0100 Subject: [PATCH 35/39] Have closures be generated inheriting from the new Closure_obj class --- src/generators/gencpp.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 68c771a0758..a06c992aa75 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4361,7 +4361,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ let argsCount = list_num closure.close_args in let signature = cpp_closure_signature ctx closure in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); - out ("::hx::Callable_obj< "); + out ("::hx::Closure_obj< "); out signature; out (">,_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> @@ -4595,7 +4595,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let func_signature = ctx_callable_signature ctx function_def in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in let write_closure_header callable_name captures_obj prefix = - output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); + output ("struct " ^ callable_name ^ " : public ::hx::Closure_obj<" ^ func_signature ^ ">\n"); output "{\n"; if captures_obj then begin From 9c5551a820a8d44c21aaf807335ca112fc93c4b0 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 22 Jul 2023 17:02:15 +0100 Subject: [PATCH 36/39] try letting auto cast rules deal with TCppCallable --- src/generators/gencpp.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index a06c992aa75..4a07dbb8d22 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -3244,7 +3244,6 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppPointer(_,_) | TCppRawPointer(_,_) | TCppStar(_) - | TCppCallable(_) | TCppInst(_) -> CppCast(baseCpp,return_type), return_type | TCppString -> CppCastScalar(baseCpp,"::String"), return_type | TCppCode(t) when baseStr <> (tcpp_to_string t) -> From 849d05198c80709c197daf080f7a381ec190fb78 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Sat, 22 Jul 2023 21:25:20 +0100 Subject: [PATCH 37/39] Deal with an odd edge case surrounding casting and ::cpp::Function --- src/generators/gencpp.ml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 4a07dbb8d22..26d0149b7c3 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -3240,6 +3240,12 @@ let retype_expression ctx request_type function_args function_type expression_tr if baseStr=returnStr then baseCpp.cppexpr, baseCpp.cpptype (* nothing to do *) else (match return_type with + | TCppFunction _ -> + (match baseCpp.cppexpr with + | CppCast (inner, TCppCallable _) -> + inner.cppexpr, inner.cpptype + | _ -> + baseCpp.cppexpr, baseCpp.cpptype (* use autocasting rules *)) | TCppObjC(k) -> CppCastObjC(baseCpp,k), return_type | TCppPointer(_,_) | TCppRawPointer(_,_) From f35ce979eaf2cd3dd09e5c1efe08ab05122c2fea Mon Sep 17 00:00:00 2001 From: Aidan63 Date: Wed, 10 Jan 2024 20:56:00 +0000 Subject: [PATCH 38/39] Don't eagerly stringify the callable and have variants track their expected type --- src/generators/gencpp.ml | 56 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 09e088d2bb4..0cdef76352c 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -1383,7 +1383,7 @@ type tcpp = | TCppFastIterator of tcpp | TCppPointer of string * tcpp | TCppRawPointer of string * tcpp - | TCppCallable of string + | TCppCallable of tcpp list * tcpp | TCppFunction of tcpp list * tcpp * string | TCppObjCBlock of tcpp list * tcpp | TCppRest of tcpp @@ -1398,7 +1398,7 @@ type tcpp = | TCppScalarArray of tcpp | TCppObjC of tclass | TCppNativePointer of tclass - | TCppVariant + | TCppVariant of tcpp option | TCppCode of tcpp | TCppInst of tclass * tcpp list | TCppInterface of tclass @@ -1635,10 +1635,11 @@ and tcpp_to_string_suffix suffix tcpp = match tcpp with | TCppRest _ -> "vaarg_list" | TCppVarArg -> "vararg" | TCppAutoCast -> "::cpp::AutoCast" - | TCppVariant -> "::cpp::Variant" + | TCppVariant Some t -> "::cpp::Variant ( " ^ (tcpp_to_string t) ^ " ) " + | TCppVariant None -> "::cpp::Variant" | TCppEnum(enum) -> " ::" ^ (join_class_path_remap enum.e_path "::") ^ suffix - | TCppCallable signature -> - "::hx::Callable< " ^ signature ^ ">" + | TCppCallable (farg, fret) -> + "::hx::Callable< " ^ tcpp_to_string fret ^ "(" ^ ((List.map tcpp_to_string farg) |> (String.concat ",")) ^ ")>" | TCppScalar(scalar) -> scalar | TCppString -> "::String" | TCppFastIterator it -> "::cpp::FastIterator" ^ suffix ^ "< " ^ (tcpp_to_string it) ^ " >"; @@ -1779,7 +1780,7 @@ let rec cpp_is_native_array_access t = ;; let cpp_is_dynamic_type = function - | TCppDynamic | TCppObject | TCppVariant | TCppGlobal | TCppNull + | TCppDynamic | TCppObject | TCppVariant _ | TCppGlobal | TCppNull | TCppInterface _ -> true | _ -> false @@ -1855,11 +1856,10 @@ let rec cpp_type_of stack ctx haxe_type = cpp_type_from_path stack ctx type_def.t_path params (fun () -> cpp_type_of stack ctx (apply_typedef type_def params)) | TFun (args, return) -> - let fargs = List.map (fun (_, o, t) -> cpp_tfun_arg_type_of stack ctx o t) args |> List.map tcpp_to_string in - let ret = cpp_type_of stack ctx return |> tcpp_to_string in - let signature = ret ^ "(" ^ (String.concat "," fargs) ^ ")" in + let fargs = List.map (fun (_, o, t) -> cpp_tfun_arg_type_of stack ctx o t) args in + let fret = cpp_type_of stack ctx return in - TCppCallable (signature) + TCppCallable (fargs, fret) | TAnon _ -> TCppObject | TDynamic _ -> TCppDynamic | TLazy func -> cpp_type_of stack ctx (lazy_type func) @@ -2131,7 +2131,7 @@ let cpp_variant_type_of t = match t with | TCppScalar "double" | TCppScalar "float" -> TCppScalar("Float") | TCppScalar _ -> TCppScalar("int") - | TCppVariant -> TCppVariant + | TCppVariant o -> TCppVariant o ;; let cpp_cast_variant_type_of t = match t with @@ -2614,7 +2614,7 @@ let retype_expression ctx request_type function_args function_type expression_tr if is_internal_member member.cf_name then CppFunction( FuncInstance(retypedObj,InstPtr(clazzType),member), funcReturn ), exprType else - CppDynamicField(retypedObj, member.cf_name), TCppVariant + CppDynamicField(retypedObj, member.cf_name), TCppVariant (Some (cpp_type_of member.cf_type)) end else if cpp_is_struct_access retypedObj.cpptype then begin match retypedObj.cppexpr with @@ -2647,7 +2647,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppInterface _,_ | TCppDynamic,_ -> - CppDynamicField(retypedObj, member.cf_name), TCppVariant + CppDynamicField(retypedObj, member.cf_name), TCppVariant (Some (cpp_type_of member.cf_type)) | TCppObjC _,_ -> CppVar(VarInstance(retypedObj,member,tcpp_to_string clazzType, ".") ), exprType @@ -2723,7 +2723,7 @@ let retype_expression ctx request_type function_args function_type expression_tr else CppFunction( FuncInternal(obj,fieldName,"->"), cppType), cppType end else - CppDynamicField(obj, field.cf_name), TCppVariant + CppDynamicField(obj, field.cf_name), TCppVariant (Some (cpp_type_of field.cf_type)) | FDynamic fieldName -> let obj = retype TCppDynamic obj in @@ -2750,7 +2750,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | _ -> CppVar( VarInternal(obj,"->",fieldName)), cpp_type_of expr.etype end else - CppDynamicField(obj, fieldName), TCppVariant + CppDynamicField(obj, fieldName), TCppVariant None | FEnum (enum, enum_field) -> CppEnumField(enum, enum_field), TCppEnum(enum) @@ -2777,6 +2777,10 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppObjCBlock(argTypes,retType) -> let retypedArgs = retype_function_args args argTypes in CppCall( FuncExpression(retypedFunc) ,retypedArgs), retType + | TCppVariant Some TCppCallable (fargs, fret) -> + let retypedArgs = List.map (retype TCppUnchanged ) args in + + CppCall (FuncExpression (retype (TCppCallable (fargs, fret)) func), retypedArgs), fret | _ -> let cppType = cpp_type_of expr.etype in @@ -2970,7 +2974,6 @@ let retype_expression ctx request_type function_args function_type expression_tr List.iter ( fun (tvar,_) -> Hashtbl.add !declarations tvar.v_name () ) func.tf_args; let cppExpr = retype TCppVoid (mk_block func.tf_expr) in - let signature = ctx_callable_signature ctx func in let result = { close_expr=cppExpr; close_id= !closureId; close_undeclared= !undeclared; @@ -2989,7 +2992,9 @@ let retype_expression ctx request_type function_args function_type expression_tr uses_this := if !uses_this != None then Some old_this_real else old_uses_this; gc_stack := old_gc_stack; rev_closures := result:: !rev_closures; - CppCallable(result), (TCppCallable signature) + let fargs = List.map (fun (v,o) -> cpp_fun_arg_type_of ctx v.v_type o) func.tf_args in + let fret = cpp_type_of func.tf_type in + CppCallable(result), (TCppCallable (fargs, fret)) | TArray (e1,e2) -> let arrayExpr, elemType = match cpp_is_native_array_access (cpp_type_of e1.etype) with @@ -3092,8 +3097,8 @@ let retype_expression ctx request_type function_args function_type expression_tr in (match op,e1.cpptype,e2.cpptype with (* Variant + Variant = Variant *) - | OpAdd, _, TCppVariant | OpAdd, TCppVariant, _ - -> reference, TCppVariant + | OpAdd, _, TCppVariant o | OpAdd, TCppVariant o, _ + -> reference, TCppVariant o | _,_,_ -> reference, cpp_type_of expr.etype ) @@ -3286,6 +3291,9 @@ let retype_expression ctx request_type function_args function_type expression_tr ) in let cppExpr = mk_cppexpr retypedExpr retypedType in + let isVariant t = match t with + | TCppVariant _ -> true + | _ -> false in (* Autocast rules... *) if return_type=TCppVoid then @@ -3298,7 +3306,7 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppDynamic -> mk_cppexpr (CppCastNative(cppExpr)) TCppVoidStar | _ -> let toDynamic = mk_cppexpr (CppCast(cppExpr, TCppDynamic)) TCppDynamic in mk_cppexpr (CppCastNative(toDynamic)) TCppVoidStar - end else if (cppExpr.cpptype=TCppVariant || cppExpr.cpptype=TCppDynamic || cppExpr.cpptype==TCppObject) then begin + end else if (isVariant cppExpr.cpptype || cppExpr.cpptype=TCppDynamic || cppExpr.cpptype==TCppObject) then begin match return_type with | TCppUnchanged -> cppExpr | TCppInst(t, _) when (has_meta_key t.cl_meta Meta.StructAccess) -> @@ -3328,10 +3336,10 @@ let retype_expression ctx request_type function_args function_type expression_tr | TCppString -> mk_cppexpr (CppCastScalar(cppExpr,"::String")) return_type - | TCppInterface _ when cppExpr.cpptype=TCppVariant + | TCppInterface _ when isVariant cppExpr.cpptype -> mk_cppexpr (CppCastVariant(cppExpr)) return_type - | TCppDynamic when cppExpr.cpptype=TCppVariant + | TCppDynamic when isVariant cppExpr.cpptype -> mk_cppexpr (CppCastVariant(cppExpr)) return_type | TCppStar(t,const) -> @@ -4295,7 +4303,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ | CppExternRef(name,isGlobal) -> if isGlobal then out " ::"; out name | CppDynamicRef(expr,name) -> let objPtr = match expr.cpptype with - | TCppVariant -> "getObject()" + | TCppVariant _ -> "getObject()" | _ -> ".mPtr" in out "::hx::FieldRef(("; gen expr ; out (")" ^ objPtr ^ "," ^ strq name ^ ")") @@ -7234,7 +7242,7 @@ let rec script_cpptype_string cppType = match cppType with | TCppRest _ -> "vaarg_list" | TCppVarArg -> "vararg" | TCppAutoCast -> ".cpp.AutoCast" - | TCppVariant -> ".cpp.Variant" + | TCppVariant _ -> ".cpp.Variant" | TCppEnum(enum) -> (join_class_path enum.e_path ".") | TCppScalar(scalar) -> scalar | TCppString -> "String" From 20e0ff0cf40aa7c37378a12db85eddcc362d4802 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Fri, 30 Aug 2024 21:05:58 +0100 Subject: [PATCH 39/39] back to callables --- src/generators/gencpp.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generators/gencpp.ml b/src/generators/gencpp.ml index 0cdef76352c..30f766042af 100644 --- a/src/generators/gencpp.ml +++ b/src/generators/gencpp.ml @@ -4379,7 +4379,7 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args function_ let argsCount = list_num closure.close_args in let signature = cpp_closure_signature ctx closure in output_i ("HX_BEGIN_LOCAL_FUNC_S" ^ size ^ "("); - out ("::hx::Closure_obj< "); + out ("::hx::Callable_obj< "); out signature; out (">,_hx_Closure_" ^ (string_of_int closure.close_id) ); Hashtbl.iter (fun name var -> @@ -4613,7 +4613,7 @@ let gen_field ctx class_def class_name ptr_name dot_name is_static is_interface let func_signature = ctx_callable_signature ctx function_def in let obj_ptr_class_name = "::hx::ObjectPtr<" ^ class_name ^ ">" in let write_closure_header callable_name captures_obj prefix = - output ("struct " ^ callable_name ^ " : public ::hx::Closure_obj<" ^ func_signature ^ ">\n"); + output ("struct " ^ callable_name ^ " : public ::hx::Callable_obj<" ^ func_signature ^ ">\n"); output "{\n"; if captures_obj then begin