|
@@ -56,29 +56,34 @@ and function_entry = {
|
|
mutable fe_calling : function_entry list;
|
|
mutable fe_calling : function_entry list;
|
|
}
|
|
}
|
|
|
|
|
|
-type context = {
|
|
|
|
|
|
+type global_context = {
|
|
version : int;
|
|
version : int;
|
|
- out : Buffer.t;
|
|
|
|
- mutable tabs : string;
|
|
|
|
|
|
+ hash_mutex : Mutex.t;
|
|
hash_cache : (int, int32) Hashtbl.t;
|
|
hash_cache : (int, int32) Hashtbl.t;
|
|
hash_mem : (int32, bool) Hashtbl.t;
|
|
hash_mem : (int32, bool) Hashtbl.t;
|
|
mutable hash_cache_list : int list;
|
|
mutable hash_cache_list : int list;
|
|
hlcode : code;
|
|
hlcode : code;
|
|
dir : string;
|
|
dir : string;
|
|
- mutable curfile : string;
|
|
|
|
mutable cfiles : string list;
|
|
mutable cfiles : string list;
|
|
ftable : function_entry array;
|
|
ftable : function_entry array;
|
|
htypes : (ttype, string) PMap.t;
|
|
htypes : (ttype, string) PMap.t;
|
|
gnames : string array;
|
|
gnames : string array;
|
|
bytes_names : string array;
|
|
bytes_names : string array;
|
|
|
|
+ mutable type_module : (ttype, code_module) PMap.t;
|
|
|
|
+ gcon : Gctx.t;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type file_context = {
|
|
|
|
+ out : Buffer.t;
|
|
|
|
+ mutable tabs : string;
|
|
|
|
+ dir : string;
|
|
|
|
+ curfile : string;
|
|
mutable defines : string list;
|
|
mutable defines : string list;
|
|
defined_funs : (int, unit) Hashtbl.t;
|
|
defined_funs : (int, unit) Hashtbl.t;
|
|
hdefines : (string, unit) Hashtbl.t;
|
|
hdefines : (string, unit) Hashtbl.t;
|
|
mutable defined_types : (ttype, unit) PMap.t;
|
|
mutable defined_types : (ttype, unit) PMap.t;
|
|
- mutable file_prefix : string;
|
|
|
|
mutable fun_index : int;
|
|
mutable fun_index : int;
|
|
- mutable type_module : (ttype, code_module) PMap.t;
|
|
|
|
- gcon : Gctx.t;
|
|
|
|
|
|
+ file_prefix : string;
|
|
}
|
|
}
|
|
|
|
|
|
let sprintf = Printf.sprintf
|
|
let sprintf = Printf.sprintf
|
|
@@ -216,8 +221,10 @@ let unblock ctx =
|
|
ctx.tabs <- String.sub ctx.tabs 0 (String.length ctx.tabs - 1)
|
|
ctx.tabs <- String.sub ctx.tabs 0 (String.length ctx.tabs - 1)
|
|
|
|
|
|
let hash ctx sid =
|
|
let hash ctx sid =
|
|
|
|
+ Mutex.protect ctx.hash_mutex (fun () ->
|
|
try
|
|
try
|
|
- Hashtbl.find ctx.hash_cache sid
|
|
|
|
|
|
+ let h = Hashtbl.find ctx.hash_cache sid in
|
|
|
|
+ h
|
|
with Not_found ->
|
|
with Not_found ->
|
|
let rec loop h =
|
|
let rec loop h =
|
|
if Hashtbl.mem ctx.hash_mem h then loop (Int32.add h Int32.one) else h
|
|
if Hashtbl.mem ctx.hash_mem h then loop (Int32.add h Int32.one) else h
|
|
@@ -227,6 +234,7 @@ let hash ctx sid =
|
|
Hashtbl.add ctx.hash_mem h true;
|
|
Hashtbl.add ctx.hash_mem h true;
|
|
ctx.hash_cache_list <- sid :: ctx.hash_cache_list;
|
|
ctx.hash_cache_list <- sid :: ctx.hash_cache_list;
|
|
h
|
|
h
|
|
|
|
+ )
|
|
|
|
|
|
let type_name ctx t =
|
|
let type_name ctx t =
|
|
try PMap.find t ctx.htypes with Not_found -> Globals.die (tstr t) __LOC__
|
|
try PMap.find t ctx.htypes with Not_found -> Globals.die (tstr t) __LOC__
|
|
@@ -237,38 +245,38 @@ let define ctx s =
|
|
Hashtbl.add ctx.hdefines s ();
|
|
Hashtbl.add ctx.hdefines s ();
|
|
end
|
|
end
|
|
|
|
|
|
-let rec define_type ctx t =
|
|
|
|
|
|
+let rec define_type gctx ctx t =
|
|
match t with
|
|
match t with
|
|
| HVoid | HUI8 | HUI16 | HI32 | HI64 | HF32 | HF64 | HBool | HBytes | HDyn | HArray _ | HType | HDynObj | HNull _ | HRef _ | HGUID -> ()
|
|
| HVoid | HUI8 | HUI16 | HI32 | HI64 | HF32 | HF64 | HBool | HBytes | HDyn | HArray _ | HType | HDynObj | HNull _ | HRef _ | HGUID -> ()
|
|
| HAbstract _ ->
|
|
| HAbstract _ ->
|
|
define ctx "#include <hl/natives.h>";
|
|
define ctx "#include <hl/natives.h>";
|
|
| HFun (args,ret) | HMethod (args,ret) ->
|
|
| HFun (args,ret) | HMethod (args,ret) ->
|
|
- List.iter (define_type ctx) args;
|
|
|
|
- define_type ctx ret
|
|
|
|
|
|
+ List.iter (define_type gctx ctx) args;
|
|
|
|
+ define_type gctx ctx ret
|
|
| HEnum _ | HObj _ | HStruct _ when not (PMap.exists t ctx.defined_types) ->
|
|
| HEnum _ | HObj _ | HStruct _ when not (PMap.exists t ctx.defined_types) ->
|
|
ctx.defined_types <- PMap.add t () ctx.defined_types;
|
|
ctx.defined_types <- PMap.add t () ctx.defined_types;
|
|
- define ctx (sprintf "#include <%s.h>" (try PMap.find t ctx.type_module with Not_found -> Globals.die "" __LOC__).m_name)
|
|
|
|
|
|
+ define ctx (sprintf "#include <%s.h>" (try PMap.find t gctx.type_module with Not_found -> Globals.die "" __LOC__).m_name)
|
|
| HVirtual vp when not (PMap.exists t ctx.defined_types) ->
|
|
| HVirtual vp when not (PMap.exists t ctx.defined_types) ->
|
|
ctx.defined_types <- PMap.add t () ctx.defined_types;
|
|
ctx.defined_types <- PMap.add t () ctx.defined_types;
|
|
- Array.iter (fun (_,_,t) -> define_type ctx t) vp.vfields
|
|
|
|
|
|
+ Array.iter (fun (_,_,t) -> define_type gctx ctx t) vp.vfields
|
|
| HPacked t ->
|
|
| HPacked t ->
|
|
- define_type ctx t
|
|
|
|
|
|
+ define_type gctx ctx t
|
|
| HEnum _ | HObj _ | HStruct _ | HVirtual _ ->
|
|
| HEnum _ | HObj _ | HStruct _ | HVirtual _ ->
|
|
()
|
|
()
|
|
|
|
|
|
-let type_value ctx t =
|
|
|
|
- let n = type_name ctx t in
|
|
|
|
|
|
+let type_value gctx ctx t =
|
|
|
|
+ let n = type_name gctx t in
|
|
define ctx (sprintf "extern hl_type %s;" n);
|
|
define ctx (sprintf "extern hl_type %s;" n);
|
|
"&" ^ n
|
|
"&" ^ n
|
|
|
|
|
|
-let enum_constr_type ctx e i =
|
|
|
|
- define_type ctx (HEnum e);
|
|
|
|
|
|
+let enum_constr_type gctx ctx e i =
|
|
|
|
+ define_type gctx ctx (HEnum e);
|
|
let cname,_, tl = e.efields.(i) in
|
|
let cname,_, tl = e.efields.(i) in
|
|
if Array.length tl = 0 then
|
|
if Array.length tl = 0 then
|
|
"venum"
|
|
"venum"
|
|
else
|
|
else
|
|
let name = if e.eid = 0 then
|
|
let name = if e.eid = 0 then
|
|
- let name = (try PMap.find (HEnum e) ctx.htypes with Not_found -> Globals.die "" __LOC__) in
|
|
|
|
|
|
+ let name = (try PMap.find (HEnum e) gctx.htypes with Not_found -> Globals.die "" __LOC__) in
|
|
"Enum" ^ name
|
|
"Enum" ^ name
|
|
else
|
|
else
|
|
String.concat "_" (ExtString.String.nsplit e.ename ".")
|
|
String.concat "_" (ExtString.String.nsplit e.ename ".")
|
|
@@ -284,12 +292,12 @@ let output ctx str =
|
|
let output_char ctx c =
|
|
let output_char ctx c =
|
|
Buffer.add_char ctx.out c
|
|
Buffer.add_char ctx.out c
|
|
|
|
|
|
-let line ctx str =
|
|
|
|
|
|
+let linec ctx str =
|
|
output ctx ctx.tabs;
|
|
output ctx ctx.tabs;
|
|
output ctx str;
|
|
output ctx str;
|
|
output_char ctx '\n'
|
|
output_char ctx '\n'
|
|
|
|
|
|
-let expr ctx str =
|
|
|
|
|
|
+let exprc ctx str =
|
|
output ctx ctx.tabs;
|
|
output ctx ctx.tabs;
|
|
output ctx str;
|
|
output ctx str;
|
|
output ctx ";\n"
|
|
output ctx ";\n"
|
|
@@ -301,6 +309,11 @@ let obj_field fid name =
|
|
|
|
|
|
let bom = "\xEF\xBB\xBF"
|
|
let bom = "\xEF\xBB\xBF"
|
|
|
|
|
|
|
|
+let save_cfile gctx file =
|
|
|
|
+ if String.sub file (String.length file - 2) 2 = ".c" then begin
|
|
|
|
+ gctx.cfiles <- file :: gctx.cfiles;
|
|
|
|
+ end
|
|
|
|
+
|
|
let close_file ctx =
|
|
let close_file ctx =
|
|
let out = Buffer.contents ctx.out in
|
|
let out = Buffer.contents ctx.out in
|
|
let defines = List.rev ctx.defines in
|
|
let defines = List.rev ctx.defines in
|
|
@@ -312,23 +325,20 @@ let close_file ctx =
|
|
Hashtbl.clear ctx.defined_funs;
|
|
Hashtbl.clear ctx.defined_funs;
|
|
Buffer.reset ctx.out;
|
|
Buffer.reset ctx.out;
|
|
let fpath = ctx.dir ^ "/" ^ ctx.curfile in
|
|
let fpath = ctx.dir ^ "/" ^ ctx.curfile in
|
|
- if String.sub ctx.curfile (String.length ctx.curfile - 2) 2 = ".c" then ctx.cfiles <- ctx.curfile :: ctx.cfiles;
|
|
|
|
- ctx.curfile <- "";
|
|
|
|
let fcontent = (try Std.input_file ~bin:true fpath with _ -> "") in
|
|
let fcontent = (try Std.input_file ~bin:true fpath with _ -> "") in
|
|
if fcontent <> str then begin
|
|
if fcontent <> str then begin
|
|
- Path.mkdir_recursive "" (ExtString.String.nsplit (Filename.dirname fpath) "/");
|
|
|
|
let ch = open_out_bin fpath in
|
|
let ch = open_out_bin fpath in
|
|
output_string ch str;
|
|
output_string ch str;
|
|
close_out ch;
|
|
close_out ch;
|
|
end
|
|
end
|
|
|
|
|
|
-let define_global ctx g =
|
|
|
|
- let t = ctx.hlcode.globals.(g) in
|
|
|
|
- define_type ctx t;
|
|
|
|
- define ctx (sprintf "extern %s;" (var_type ctx.gnames.(g) t))
|
|
|
|
|
|
+let define_global gctx ctx g =
|
|
|
|
+ let t = gctx.hlcode.globals.(g) in
|
|
|
|
+ define_type gctx ctx t;
|
|
|
|
+ define ctx (sprintf "extern %s;" (var_type gctx.gnames.(g) t))
|
|
|
|
|
|
-let define_function ctx fid =
|
|
|
|
- let ft = ctx.ftable.(fid) in
|
|
|
|
|
|
+let define_function gctx ctx fid =
|
|
|
|
+ let ft = gctx.ftable.(fid) in
|
|
let fid = if ft.fe_decl = None then -1 else fid in
|
|
let fid = if ft.fe_decl = None then -1 else fid in
|
|
if not (Hashtbl.mem ctx.defined_funs fid) then begin
|
|
if not (Hashtbl.mem ctx.defined_funs fid) then begin
|
|
Hashtbl.add ctx.defined_funs fid ();
|
|
Hashtbl.add ctx.defined_funs fid ();
|
|
@@ -336,7 +346,7 @@ let define_function ctx fid =
|
|
| None ->
|
|
| None ->
|
|
define ctx "#include <hl/natives.h>"
|
|
define ctx "#include <hl/natives.h>"
|
|
| Some f ->
|
|
| Some f ->
|
|
- define_type ctx f.ftype;
|
|
|
|
|
|
+ define_type gctx ctx f.ftype;
|
|
ctx.defines <- sprintf "%s %s(%s);" (ctype ft.fe_ret) ft.fe_name (args_repr ft.fe_args) :: ctx.defines);
|
|
ctx.defines <- sprintf "%s %s(%s);" (ctype ft.fe_ret) ft.fe_name (args_repr ft.fe_args) :: ctx.defines);
|
|
end;
|
|
end;
|
|
ft.fe_name
|
|
ft.fe_name
|
|
@@ -344,18 +354,31 @@ let define_function ctx fid =
|
|
let short_digest str =
|
|
let short_digest str =
|
|
String.sub (Digest.to_hex (Digest.string str)) 0 7
|
|
String.sub (Digest.to_hex (Digest.string str)) 0 7
|
|
|
|
|
|
-let open_file ctx file =
|
|
|
|
- if ctx.curfile <> "" then close_file ctx;
|
|
|
|
|
|
+let create_file_context dir file =
|
|
|
|
+ let ctx = {
|
|
|
|
+ out = Buffer.create 1024;
|
|
|
|
+ tabs = "";
|
|
|
|
+ dir = dir;
|
|
|
|
+ curfile = file;
|
|
|
|
+ defines = [];
|
|
|
|
+ hdefines = Hashtbl.create 0;
|
|
|
|
+ defined_funs = Hashtbl.create 0;
|
|
|
|
+ defined_types = PMap.empty;
|
|
|
|
+ fun_index = 0;
|
|
|
|
+ file_prefix = (short_digest file) ^ "_";
|
|
|
|
+ } in
|
|
|
|
+ ctx
|
|
|
|
+
|
|
|
|
+let open_file (gctx:global_context) file =
|
|
|
|
+ let ctx = create_file_context gctx.dir file in
|
|
if file <> "hlc.json" then
|
|
if file <> "hlc.json" then
|
|
- Gctx.map_source_header ctx.gcon.defines (fun s -> define ctx (sprintf "// %s" s));
|
|
|
|
- ctx.curfile <- file;
|
|
|
|
- ctx.fun_index <- 0;
|
|
|
|
- ctx.file_prefix <- (short_digest file) ^ "_"
|
|
|
|
|
|
+ Gctx.map_source_header gctx.gcon.defines (fun s -> define ctx (sprintf "// %s" s));
|
|
|
|
+ ctx
|
|
|
|
|
|
let string_data_limit = 64
|
|
let string_data_limit = 64
|
|
|
|
|
|
-let string ctx sid =
|
|
|
|
- let s = ctx.hlcode.strings.(sid) in
|
|
|
|
|
|
+let string gctx ctx sid =
|
|
|
|
+ let s = gctx.hlcode.strings.(sid) in
|
|
if String.length s < string_data_limit then
|
|
if String.length s < string_data_limit then
|
|
sprintf "USTR(\"%s\")" (StringHelper.s_escape s)
|
|
sprintf "USTR(\"%s\")" (StringHelper.s_escape s)
|
|
else begin
|
|
else begin
|
|
@@ -364,8 +387,8 @@ let string ctx sid =
|
|
sprintf "string$%s" id
|
|
sprintf "string$%s" id
|
|
end
|
|
end
|
|
|
|
|
|
-let generate_reflection ctx =
|
|
|
|
- let line = line ctx and expr = expr ctx in
|
|
|
|
|
|
+let generate_reflection gctx ctx =
|
|
|
|
+ let line = linec ctx and expr = exprc ctx in
|
|
let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in
|
|
let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in
|
|
|
|
|
|
let funByArgs = Hashtbl.create 0 in
|
|
let funByArgs = Hashtbl.create 0 in
|
|
@@ -400,8 +423,8 @@ let generate_reflection ctx =
|
|
| _ -> ())
|
|
| _ -> ())
|
|
| _ -> ()
|
|
| _ -> ()
|
|
) f.code
|
|
) f.code
|
|
- ) ctx.hlcode.functions;
|
|
|
|
- Array.iter (fun f -> add_fun f.fe_args f.fe_ret) ctx.ftable;
|
|
|
|
|
|
+ ) gctx.hlcode.functions;
|
|
|
|
+ Array.iter (fun f -> add_fun f.fe_args f.fe_ret) gctx.ftable;
|
|
let argsCounts = List.sort compare (Hashtbl.fold (fun i _ acc -> i :: acc) funByArgs []) in
|
|
let argsCounts = List.sort compare (Hashtbl.fold (fun i _ acc -> i :: acc) funByArgs []) in
|
|
sexpr "static int TKIND[] = {%s}" (String.concat "," (List.map (fun t -> string_of_int (type_kind_id (type_kind t))) core_types));
|
|
sexpr "static int TKIND[] = {%s}" (String.concat "," (List.map (fun t -> string_of_int (type_kind_id (type_kind t))) core_types));
|
|
line "";
|
|
line "";
|
|
@@ -519,13 +542,13 @@ let generate_reflection ctx =
|
|
line "}";
|
|
line "}";
|
|
line ""
|
|
line ""
|
|
|
|
|
|
-let generate_function ctx f =
|
|
|
|
- let line = line ctx and expr = expr ctx in
|
|
|
|
|
|
+let generate_function gctx ctx f =
|
|
|
|
+ let line = linec ctx and expr = exprc ctx in
|
|
let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in
|
|
let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in
|
|
let define fmt = Printf.ksprintf (define ctx) fmt in
|
|
let define fmt = Printf.ksprintf (define ctx) fmt in
|
|
let block() = block ctx and unblock() = unblock ctx in
|
|
let block() = block ctx and unblock() = unblock ctx in
|
|
- let type_value = type_value ctx in
|
|
|
|
- let code = ctx.hlcode in
|
|
|
|
|
|
+ let type_value = type_value gctx in
|
|
|
|
+ let code = gctx.hlcode in
|
|
|
|
|
|
let rid = ref (-1) in
|
|
let rid = ref (-1) in
|
|
let cl_id = ref 0 in
|
|
let cl_id = ref 0 in
|
|
@@ -534,12 +557,12 @@ let generate_function ctx f =
|
|
let label p = sprintf "label$%s%d_%d" ctx.file_prefix ctx.fun_index p in
|
|
let label p = sprintf "label$%s%d_%d" ctx.file_prefix ctx.fun_index p in
|
|
ctx.fun_index <- ctx.fun_index + 1;
|
|
ctx.fun_index <- ctx.fun_index + 1;
|
|
Hashtbl.add ctx.defined_funs f.findex ();
|
|
Hashtbl.add ctx.defined_funs f.findex ();
|
|
- Array.iter (define_type ctx) f.regs;
|
|
|
|
- define_type ctx f.ftype;
|
|
|
|
|
|
+ Array.iter (define_type gctx ctx) f.regs;
|
|
|
|
+ define_type gctx ctx f.ftype;
|
|
|
|
|
|
let rtype r = f.regs.(r) in
|
|
let rtype r = f.regs.(r) in
|
|
|
|
|
|
- let funname fid = define_function ctx fid in
|
|
|
|
|
|
+ let funname fid = define_function gctx ctx fid in
|
|
|
|
|
|
let rcast r t =
|
|
let rcast r t =
|
|
let rt = (rtype r) in
|
|
let rt = (rtype r) in
|
|
@@ -567,7 +590,7 @@ let generate_function ctx f =
|
|
in
|
|
in
|
|
|
|
|
|
let ocall r fid args =
|
|
let ocall r fid args =
|
|
- let ft = ctx.ftable.(fid) in
|
|
|
|
|
|
+ let ft = gctx.ftable.(fid) in
|
|
let rstr = rassign r ft.fe_ret in
|
|
let rstr = rassign r ft.fe_ret in
|
|
sexpr "%s%s(%s)" rstr (funname fid) (String.concat "," (List.map2 rcast args ft.fe_args))
|
|
sexpr "%s%s(%s)" rstr (funname fid) (String.concat "," (List.map2 rcast args ft.fe_args))
|
|
in
|
|
in
|
|
@@ -582,7 +605,7 @@ let generate_function ctx f =
|
|
in
|
|
in
|
|
|
|
|
|
let type_value_opt t =
|
|
let type_value_opt t =
|
|
- match t with HF32 | HF64 | HI64 -> "" | _ -> "," ^ type_value t
|
|
|
|
|
|
+ match t with HF32 | HF64 | HI64 -> "" | _ -> "," ^ type_value ctx t
|
|
in
|
|
in
|
|
|
|
|
|
let dyn_call r f pl =
|
|
let dyn_call r f pl =
|
|
@@ -596,7 +619,7 @@ let generate_function ctx f =
|
|
if is_dynamic t then
|
|
if is_dynamic t then
|
|
sprintf "(vdynamic*)%s" (reg p)
|
|
sprintf "(vdynamic*)%s" (reg p)
|
|
else
|
|
else
|
|
- sprintf "hl_make_dyn(&%s,%s)" (reg p) (type_value t)
|
|
|
|
|
|
+ sprintf "hl_make_dyn(&%s,%s)" (reg p) (type_value ctx t)
|
|
) pl));
|
|
) pl));
|
|
let rt = rtype r in
|
|
let rt = rtype r in
|
|
let ret = if rt = HVoid then "" else if is_dynamic rt then sprintf "%s = (%s)" (reg r) (ctype rt) else "vdynamic *ret = " in
|
|
let ret = if rt = HVoid then "" else if is_dynamic rt then sprintf "%s = (%s)" (reg r) (ctype rt) else "vdynamic *ret = " in
|
|
@@ -629,7 +652,7 @@ let generate_function ctx f =
|
|
let rt = rtype r in
|
|
let rt = rtype r in
|
|
let ret = if rt = HVoid then "" else if is_ptr rt then sprintf "%s = (%s)" (reg r) (ctype rt) else begin sexpr "vdynamic ret"; ""; end in
|
|
let ret = if rt = HVoid then "" else if is_ptr rt then sprintf "%s = (%s)" (reg r) (ctype rt) else begin sexpr "vdynamic ret"; ""; end in
|
|
let fname, fid, ft = vp.vfields.(fid) in
|
|
let fname, fid, ft = vp.vfields.(fid) in
|
|
- sexpr "%shl_dyn_call_obj(%s->value,%s,%ld/*%s*/,%s,%s)" ret (reg o) (type_value ft) (hash ctx fid) fname (if args = [] then "NULL" else "args") (if is_ptr rt || rt == HVoid then "NULL" else "&ret");
|
|
|
|
|
|
+ sexpr "%shl_dyn_call_obj(%s->value,%s,%ld/*%s*/,%s,%s)" ret (reg o) (type_value ctx ft) (hash gctx fid) fname (if args = [] then "NULL" else "args") (if is_ptr rt || rt == HVoid then "NULL" else "&ret");
|
|
if rt <> HVoid && not (is_ptr rt) then sexpr "%s = (%s)ret.v.%s" (reg r) (ctype rt) (dyn_prefix rt);
|
|
if rt <> HVoid && not (is_ptr rt) then sexpr "%s = (%s)ret.v.%s" (reg r) (ctype rt) (dyn_prefix rt);
|
|
unblock();
|
|
unblock();
|
|
sline "}"
|
|
sline "}"
|
|
@@ -644,7 +667,7 @@ let generate_function ctx f =
|
|
sexpr "%s->%s = %s" (reg obj) (obj_field fid name) (rcast v t)
|
|
sexpr "%s->%s = %s" (reg obj) (obj_field fid name) (rcast v t)
|
|
| HVirtual vp ->
|
|
| HVirtual vp ->
|
|
let name, nid, t = vp.vfields.(fid) in
|
|
let name, nid, t = vp.vfields.(fid) in
|
|
- let dset = sprintf "hl_dyn_set%s(%s->value,%ld/*%s*/%s,%s)" (dyn_prefix t) (reg obj) (hash ctx nid) name (type_value_opt (rtype v)) (reg v) in
|
|
|
|
|
|
+ let dset = sprintf "hl_dyn_set%s(%s->value,%ld/*%s*/%s,%s)" (dyn_prefix t) (reg obj) (hash gctx nid) name (type_value_opt (rtype v)) (reg v) in
|
|
sexpr "if( hl_vfields(%s)[%d] ) *(%s*)(hl_vfields(%s)[%d]) = (%s)%s; else %s" (reg obj) fid (ctype t) (reg obj) fid (ctype t) (reg v) dset
|
|
sexpr "if( hl_vfields(%s)[%d] ) *(%s*)(hl_vfields(%s)[%d]) = (%s)%s; else %s" (reg obj) fid (ctype t) (reg obj) fid (ctype t) (reg v) dset
|
|
| _ ->
|
|
| _ ->
|
|
Globals.die "" __LOC__
|
|
Globals.die "" __LOC__
|
|
@@ -657,7 +680,7 @@ let generate_function ctx f =
|
|
sexpr "%s%s->%s" (rassign r t) (reg obj) (obj_field fid name)
|
|
sexpr "%s%s->%s" (rassign r t) (reg obj) (obj_field fid name)
|
|
| HVirtual v ->
|
|
| HVirtual v ->
|
|
let name, nid, t = v.vfields.(fid) in
|
|
let name, nid, t = v.vfields.(fid) in
|
|
- let dget = sprintf "(%s)hl_dyn_get%s(%s->value,%ld/*%s*/%s)" (ctype t) (dyn_prefix t) (reg obj) (hash ctx nid) name (type_value_opt t) in
|
|
|
|
|
|
+ let dget = sprintf "(%s)hl_dyn_get%s(%s->value,%ld/*%s*/%s)" (ctype t) (dyn_prefix t) (reg obj) (hash gctx nid) name (type_value_opt t) in
|
|
sexpr "%shl_vfields(%s)[%d] ? (*(%s*)(hl_vfields(%s)[%d])) : %s" (rassign r t) (reg obj) fid (ctype t) (reg obj) fid dget
|
|
sexpr "%shl_vfields(%s)[%d] ? (*(%s*)(hl_vfields(%s)[%d])) : %s" (rassign r t) (reg obj) fid (ctype t) (reg obj) fid dget
|
|
| _ ->
|
|
| _ ->
|
|
Globals.die "" __LOC__
|
|
Globals.die "" __LOC__
|
|
@@ -698,8 +721,8 @@ let generate_function ctx f =
|
|
| OEndTrap true ->
|
|
| OEndTrap true ->
|
|
decr trap_depth
|
|
decr trap_depth
|
|
| OStaticClosure (_, fid) ->
|
|
| OStaticClosure (_, fid) ->
|
|
- let ft = ctx.ftable.(fid) in
|
|
|
|
- sexpr "static vclosure cl$%d = { %s, %s, 0 }" (!cl_id) (type_value (HFun (ft.fe_args,ft.fe_ret))) (funname fid);
|
|
|
|
|
|
+ let ft = gctx.ftable.(fid) in
|
|
|
|
+ sexpr "static vclosure cl$%d = { %s, %s, 0 }" (!cl_id) (type_value ctx (HFun (ft.fe_args,ft.fe_ret))) (funname fid);
|
|
incr cl_id;
|
|
incr cl_id;
|
|
| _ ->
|
|
| _ ->
|
|
()
|
|
()
|
|
@@ -819,10 +842,10 @@ let generate_function ctx f =
|
|
| OBool (r,b) ->
|
|
| OBool (r,b) ->
|
|
sexpr "%s = %s" (reg r) (if b then "true" else "false")
|
|
sexpr "%s = %s" (reg r) (if b then "true" else "false")
|
|
| OBytes (r,idx) ->
|
|
| OBytes (r,idx) ->
|
|
- define "extern vbyte %s[];" ctx.bytes_names.(idx);
|
|
|
|
- sexpr "%s = %s" (reg r) ctx.bytes_names.(idx)
|
|
|
|
|
|
+ define "extern vbyte %s[];" gctx.bytes_names.(idx);
|
|
|
|
+ sexpr "%s = %s" (reg r) gctx.bytes_names.(idx)
|
|
| OString (r,idx) ->
|
|
| OString (r,idx) ->
|
|
- sexpr "%s = (vbyte*)%s" (reg r) (string ctx idx)
|
|
|
|
|
|
+ sexpr "%s = (vbyte*)%s" (reg r) (string gctx ctx idx)
|
|
| ONull r ->
|
|
| ONull r ->
|
|
sexpr "%s = NULL" (reg r)
|
|
sexpr "%s = NULL" (reg r)
|
|
| OAdd (r,a,b) ->
|
|
| OAdd (r,a,b) ->
|
|
@@ -903,22 +926,22 @@ let generate_function ctx f =
|
|
sexpr "%s = &cl$%d" (reg r) (!cl_id);
|
|
sexpr "%s = &cl$%d" (reg r) (!cl_id);
|
|
incr cl_id
|
|
incr cl_id
|
|
| OInstanceClosure (r,fid,ptr) ->
|
|
| OInstanceClosure (r,fid,ptr) ->
|
|
- let ft = ctx.ftable.(fid) in
|
|
|
|
- sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value (HFun (ft.fe_args,ft.fe_ret))) (funname fid) (reg ptr)
|
|
|
|
|
|
+ let ft = gctx.ftable.(fid) in
|
|
|
|
+ sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value ctx (HFun (ft.fe_args,ft.fe_ret))) (funname fid) (reg ptr)
|
|
| OVirtualClosure (r,o,m) ->
|
|
| OVirtualClosure (r,o,m) ->
|
|
(match rtype o with
|
|
(match rtype o with
|
|
| HObj p ->
|
|
| HObj p ->
|
|
- let ft = ctx.ftable.(p.pvirtuals.(m)) in
|
|
|
|
|
|
+ let ft = gctx.ftable.(p.pvirtuals.(m)) in
|
|
let s = sprintf "%s->$type->vobj_proto[%d]" (reg o) m in
|
|
let s = sprintf "%s->$type->vobj_proto[%d]" (reg o) m in
|
|
- sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value (HFun(ft.fe_args,ft.fe_ret))) s (reg o)
|
|
|
|
|
|
+ sexpr "%s = hl_alloc_closure_ptr(%s,%s,%s)" (reg r) (type_value ctx (HFun(ft.fe_args,ft.fe_ret))) s (reg o)
|
|
| _ ->
|
|
| _ ->
|
|
todo())
|
|
todo())
|
|
| OGetGlobal (r,g) ->
|
|
| OGetGlobal (r,g) ->
|
|
- define_global ctx g;
|
|
|
|
- sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) ctx.gnames.(g)
|
|
|
|
|
|
+ define_global gctx ctx g;
|
|
|
|
+ sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) gctx.gnames.(g)
|
|
| OSetGlobal (g,r) ->
|
|
| OSetGlobal (g,r) ->
|
|
- define_global ctx g;
|
|
|
|
- sexpr "%s = (%s)%s" ctx.gnames.(g) (ctype code.globals.(g)) (reg r)
|
|
|
|
|
|
+ define_global gctx ctx g;
|
|
|
|
+ sexpr "%s = (%s)%s" gctx.gnames.(g) (ctype code.globals.(g)) (reg r)
|
|
| ORet r ->
|
|
| ORet r ->
|
|
if rtype r = HVoid then expr "return" else sexpr "return %s" (rcast r fret)
|
|
if rtype r = HVoid then expr "return" else sexpr "return %s" (rcast r fret)
|
|
| OJTrue (r,d) | OJNotNull (r,d) ->
|
|
| OJTrue (r,d) | OJNotNull (r,d) ->
|
|
@@ -956,7 +979,7 @@ let generate_function ctx f =
|
|
sline "if( %s == NULL ) %s = NULL; else {" (reg v) (reg r);
|
|
sline "if( %s == NULL ) %s = NULL; else {" (reg v) (reg r);
|
|
block();
|
|
block();
|
|
end;
|
|
end;
|
|
- sexpr "%s = hl_alloc_dynamic(%s)" (reg r) (type_value (rtype v));
|
|
|
|
|
|
+ sexpr "%s = hl_alloc_dynamic(%s)" (reg r) (type_value ctx (rtype v));
|
|
(match rtype v with
|
|
(match rtype v with
|
|
| HUI8 | HUI16 | HI32 | HBool ->
|
|
| HUI8 | HUI16 | HI32 | HBool ->
|
|
sexpr "%s->v.i = %s" (reg r) (reg v)
|
|
sexpr "%s->v.i = %s" (reg r) (reg v)
|
|
@@ -980,9 +1003,9 @@ let generate_function ctx f =
|
|
sexpr "%s = (int)%s" (reg r) (reg v)
|
|
sexpr "%s = (int)%s" (reg r) (reg v)
|
|
| ONew r ->
|
|
| ONew r ->
|
|
(match rtype r with
|
|
(match rtype r with
|
|
- | HObj o | HStruct o -> sexpr "%s = (%s)hl_alloc_obj(%s)" (reg r) (tname o.pname) (type_value (rtype r))
|
|
|
|
|
|
+ | HObj o | HStruct o -> sexpr "%s = (%s)hl_alloc_obj(%s)" (reg r) (tname o.pname) (type_value ctx (rtype r))
|
|
| HDynObj -> sexpr "%s = hl_alloc_dynobj()" (reg r)
|
|
| HDynObj -> sexpr "%s = hl_alloc_dynobj()" (reg r)
|
|
- | HVirtual _ as t -> sexpr "%s = hl_alloc_virtual(%s)" (reg r) (type_value t)
|
|
|
|
|
|
+ | HVirtual _ as t -> sexpr "%s = hl_alloc_virtual(%s)" (reg r) (type_value ctx t)
|
|
| _ -> Globals.die "" __LOC__)
|
|
| _ -> Globals.die "" __LOC__)
|
|
| OField (r,obj,fid) ->
|
|
| OField (r,obj,fid) ->
|
|
get_field r obj fid
|
|
get_field r obj fid
|
|
@@ -1030,13 +1053,13 @@ let generate_function ctx f =
|
|
if tsrc = HNull t then
|
|
if tsrc = HNull t then
|
|
sexpr "%s = %s ? %s%s : 0" (reg r) (reg v) (reg v) (dyn_value_field t)
|
|
sexpr "%s = %s ? %s%s : 0" (reg r) (reg v) (reg v) (dyn_value_field t)
|
|
else
|
|
else
|
|
- sexpr "%s = (%s)hl_dyn_cast%s(&%s,%s%s)" (reg r) (ctype t) (dyn_prefix t) (reg v) (type_value (rtype v)) (type_value_opt t)
|
|
|
|
|
|
+ sexpr "%s = (%s)hl_dyn_cast%s(&%s,%s%s)" (reg r) (ctype t) (dyn_prefix t) (reg v) (type_value ctx (rtype v)) (type_value_opt t)
|
|
| OUnsafeCast (r,v) ->
|
|
| OUnsafeCast (r,v) ->
|
|
sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) (reg v)
|
|
sexpr "%s = (%s)%s" (reg r) (ctype (rtype r)) (reg v)
|
|
| OArraySize (r,a) ->
|
|
| OArraySize (r,a) ->
|
|
sexpr "%s = %s->size" (reg r) (reg a)
|
|
sexpr "%s = %s->size" (reg r) (reg a)
|
|
| OType (r,t) ->
|
|
| OType (r,t) ->
|
|
- sexpr "%s = %s" (reg r) (type_value t)
|
|
|
|
|
|
+ sexpr "%s = %s" (reg r) (type_value ctx t)
|
|
| OGetType (r,v) ->
|
|
| OGetType (r,v) ->
|
|
sexpr "%s = %s ? ((vdynamic*)%s)->t : &hlt_void" (reg r) (reg v) (reg v)
|
|
sexpr "%s = %s ? ((vdynamic*)%s)->t : &hlt_void" (reg r) (reg v) (reg v)
|
|
| OGetTID (r,v) ->
|
|
| OGetTID (r,v) ->
|
|
@@ -1048,36 +1071,36 @@ let generate_function ctx f =
|
|
| OSetref (r,v) ->
|
|
| OSetref (r,v) ->
|
|
sexpr "*%s = %s" (reg r) (reg v)
|
|
sexpr "*%s = %s" (reg r) (reg v)
|
|
| OToVirtual (r,v) ->
|
|
| OToVirtual (r,v) ->
|
|
- sexpr "%s = hl_to_virtual(%s,(vdynamic*)%s)" (reg r) (type_value (rtype r)) (reg v)
|
|
|
|
|
|
+ sexpr "%s = hl_to_virtual(%s,(vdynamic*)%s)" (reg r) (type_value ctx (rtype r)) (reg v)
|
|
| ODynGet (r,o,sid) ->
|
|
| ODynGet (r,o,sid) ->
|
|
let t = rtype r in
|
|
let t = rtype r in
|
|
- let h = hash ctx sid in
|
|
|
|
|
|
+ let h = hash gctx sid in
|
|
sexpr "%s = (%s)hl_dyn_get%s((vdynamic*)%s,%ld/*%s*/%s)" (reg r) (ctype t) (dyn_prefix t) (reg o) h code.strings.(sid) (type_value_opt t)
|
|
sexpr "%s = (%s)hl_dyn_get%s((vdynamic*)%s,%ld/*%s*/%s)" (reg r) (ctype t) (dyn_prefix t) (reg o) h code.strings.(sid) (type_value_opt t)
|
|
| ODynSet (o,sid,v) ->
|
|
| ODynSet (o,sid,v) ->
|
|
- let h = hash ctx sid in
|
|
|
|
|
|
+ let h = hash gctx sid in
|
|
sexpr "hl_dyn_set%s((vdynamic*)%s,%ld/*%s*/%s,%s)" (dyn_prefix (rtype v)) (reg o) h code.strings.(sid) (type_value_opt (rtype v)) (reg v)
|
|
sexpr "hl_dyn_set%s((vdynamic*)%s,%ld/*%s*/%s,%s)" (dyn_prefix (rtype v)) (reg o) h code.strings.(sid) (type_value_opt (rtype v)) (reg v)
|
|
| OMakeEnum (r,cid,rl) ->
|
|
| OMakeEnum (r,cid,rl) ->
|
|
- let e, et = (match rtype r with HEnum e -> e, enum_constr_type ctx e cid | _ -> Globals.die "" __LOC__) in
|
|
|
|
|
|
+ let e, et = (match rtype r with HEnum e -> e, enum_constr_type gctx ctx e cid | _ -> Globals.die "" __LOC__) in
|
|
let need_tmp = List.mem r rl in
|
|
let need_tmp = List.mem r rl in
|
|
let tmp = if not need_tmp then reg r else begin
|
|
let tmp = if not need_tmp then reg r else begin
|
|
sexpr "{ venum *tmp";
|
|
sexpr "{ venum *tmp";
|
|
"tmp"
|
|
"tmp"
|
|
end in
|
|
end in
|
|
- sexpr "%s = hl_alloc_enum(%s,%d)" tmp (type_value (rtype r)) cid;
|
|
|
|
|
|
+ sexpr "%s = hl_alloc_enum(%s,%d)" tmp (type_value ctx (rtype r)) cid;
|
|
let _,_,tl = e.efields.(cid) in
|
|
let _,_,tl = e.efields.(cid) in
|
|
list_iteri (fun i v ->
|
|
list_iteri (fun i v ->
|
|
sexpr "((%s*)%s)->p%d = %s" et tmp i (rcast v tl.(i))
|
|
sexpr "((%s*)%s)->p%d = %s" et tmp i (rcast v tl.(i))
|
|
) rl;
|
|
) rl;
|
|
if need_tmp then sexpr "%s = tmp; }" (reg r)
|
|
if need_tmp then sexpr "%s = tmp; }" (reg r)
|
|
| OEnumAlloc (r,cid) ->
|
|
| OEnumAlloc (r,cid) ->
|
|
- sexpr "%s = hl_alloc_enum(%s,%d)" (reg r) (type_value (rtype r)) cid
|
|
|
|
|
|
+ sexpr "%s = hl_alloc_enum(%s,%d)" (reg r) (type_value ctx (rtype r)) cid
|
|
| OEnumIndex (r,v) ->
|
|
| OEnumIndex (r,v) ->
|
|
sexpr "%s = HL__ENUM_INDEX__(%s)" (reg r) (reg v)
|
|
sexpr "%s = HL__ENUM_INDEX__(%s)" (reg r) (reg v)
|
|
| OEnumField (r,e,cid,pid) ->
|
|
| OEnumField (r,e,cid,pid) ->
|
|
- let tname,(_,_,tl) = (match rtype e with HEnum e -> enum_constr_type ctx e cid, e.efields.(cid) | _ -> Globals.die "" __LOC__) in
|
|
|
|
|
|
+ let tname,(_,_,tl) = (match rtype e with HEnum e -> enum_constr_type gctx ctx e cid, e.efields.(cid) | _ -> Globals.die "" __LOC__) in
|
|
sexpr "%s((%s*)%s)->p%d" (rassign r tl.(pid)) tname (reg e) pid
|
|
sexpr "%s((%s*)%s)->p%d" (rassign r tl.(pid)) tname (reg e) pid
|
|
| OSetEnumField (e,pid,r) ->
|
|
| OSetEnumField (e,pid,r) ->
|
|
- let tname, (_,_,tl) = (match rtype e with HEnum e -> enum_constr_type ctx e 0, e.efields.(0) | _ -> Globals.die "" __LOC__) in
|
|
|
|
|
|
+ let tname, (_,_,tl) = (match rtype e with HEnum e -> enum_constr_type gctx ctx e 0, e.efields.(0) | _ -> Globals.die "" __LOC__) in
|
|
sexpr "((%s*)%s)->p%d = (%s)%s" tname (reg e) pid (ctype tl.(pid)) (reg r)
|
|
sexpr "((%s*)%s)->p%d = (%s)%s" tname (reg e) pid (ctype tl.(pid)) (reg r)
|
|
| OSwitch (r,idx,eend) ->
|
|
| OSwitch (r,idx,eend) ->
|
|
sline "switch(%s) {" (reg r);
|
|
sline "switch(%s) {" (reg r);
|
|
@@ -1397,9 +1420,9 @@ let make_modules ctx all_types =
|
|
) (List.rev !all_contexts);
|
|
) (List.rev !all_contexts);
|
|
!all_modules
|
|
!all_modules
|
|
|
|
|
|
-let generate_module_types ctx m =
|
|
|
|
|
|
+let generate_module_types gctx ctx m =
|
|
let def_name = "INC_" ^ String.concat "__" (ExtString.String.nsplit m.m_name "/") in
|
|
let def_name = "INC_" ^ String.concat "__" (ExtString.String.nsplit m.m_name "/") in
|
|
- let line = line ctx and expr = expr ctx and sexpr fmt = Printf.ksprintf (expr ctx) fmt in
|
|
|
|
|
|
+ let line = linec ctx and expr = exprc ctx and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
let type_name t =
|
|
let type_name t =
|
|
match t with
|
|
match t with
|
|
| HObj o | HStruct o -> o.pname
|
|
| HObj o | HStruct o -> o.pname
|
|
@@ -1430,7 +1453,7 @@ let generate_module_types ctx m =
|
|
| None ->
|
|
| None ->
|
|
if not (is_struct t) then expr ("hl_type *$type");
|
|
if not (is_struct t) then expr ("hl_type *$type");
|
|
| Some c ->
|
|
| Some c ->
|
|
- define_type ctx (if is_struct t then HStruct c else HObj c);
|
|
|
|
|
|
+ define_type gctx ctx (if is_struct t then HStruct c else HObj c);
|
|
loop c);
|
|
loop c);
|
|
Array.iteri (fun i (n,_,t) ->
|
|
Array.iteri (fun i (n,_,t) ->
|
|
let rec abs_index p v =
|
|
let rec abs_index p v =
|
|
@@ -1438,7 +1461,7 @@ let generate_module_types ctx m =
|
|
| None -> v
|
|
| None -> v
|
|
| Some o -> abs_index o.psuper (Array.length o.pfields + v)
|
|
| Some o -> abs_index o.psuper (Array.length o.pfields + v)
|
|
in
|
|
in
|
|
- define_type ctx t;
|
|
|
|
|
|
+ define_type gctx ctx t;
|
|
expr (var_type (if n = "" then unamed_field (abs_index o.psuper i) else n) t)
|
|
expr (var_type (if n = "" then unamed_field (abs_index o.psuper i) else n) t)
|
|
) o.pfields;
|
|
) o.pfields;
|
|
in
|
|
in
|
|
@@ -1452,11 +1475,11 @@ let generate_module_types ctx m =
|
|
block ctx;
|
|
block ctx;
|
|
line "HL__ENUM_CONSTRUCT__";
|
|
line "HL__ENUM_CONSTRUCT__";
|
|
Array.iteri (fun i t ->
|
|
Array.iteri (fun i t ->
|
|
- define_type ctx t;
|
|
|
|
|
|
+ define_type gctx ctx t;
|
|
expr (var_type ("p" ^ string_of_int i) t)
|
|
expr (var_type ("p" ^ string_of_int i) t)
|
|
) pl;
|
|
) pl;
|
|
unblock ctx;
|
|
unblock ctx;
|
|
- sexpr "} %s" (enum_constr_type ctx e i);
|
|
|
|
|
|
+ sexpr "} %s" (enum_constr_type gctx ctx e i);
|
|
end;
|
|
end;
|
|
) e.efields
|
|
) e.efields
|
|
| _ ->
|
|
| _ ->
|
|
@@ -1465,43 +1488,36 @@ let generate_module_types ctx m =
|
|
line "#endif";
|
|
line "#endif";
|
|
line ""
|
|
line ""
|
|
|
|
|
|
-let write_c com file (code:code) gnames =
|
|
|
|
|
|
+let write_c com file (code:code) gnames num_domains =
|
|
|
|
|
|
let all_types, htypes = gather_types code in
|
|
let all_types, htypes = gather_types code in
|
|
let types_ids = make_types_idents htypes in
|
|
let types_ids = make_types_idents htypes in
|
|
let gnames = make_global_names code gnames in
|
|
let gnames = make_global_names code gnames in
|
|
let bnames = Array.map (fun b -> "bytes$" ^ short_digest (Digest.to_hex (Digest.bytes b))) code.bytes in
|
|
let bnames = Array.map (fun b -> "bytes$" ^ short_digest (Digest.to_hex (Digest.bytes b))) code.bytes in
|
|
-
|
|
|
|
- let ctx = {
|
|
|
|
|
|
+ let gctx = {
|
|
version = com.Gctx.version.version;
|
|
version = com.Gctx.version.version;
|
|
- out = Buffer.create 1024;
|
|
|
|
- tabs = "";
|
|
|
|
hlcode = code;
|
|
hlcode = code;
|
|
|
|
+ hash_mutex = Mutex.create();
|
|
hash_cache = Hashtbl.create 0;
|
|
hash_cache = Hashtbl.create 0;
|
|
hash_mem = Hashtbl.create 0;
|
|
hash_mem = Hashtbl.create 0;
|
|
hash_cache_list = [];
|
|
hash_cache_list = [];
|
|
dir = (match Filename.dirname file with "" -> "." | dir -> String.concat "/" (ExtString.String.nsplit dir "\\"));
|
|
dir = (match Filename.dirname file with "" -> "." | dir -> String.concat "/" (ExtString.String.nsplit dir "\\"));
|
|
- curfile = "";
|
|
|
|
cfiles = [];
|
|
cfiles = [];
|
|
ftable = make_function_table code;
|
|
ftable = make_function_table code;
|
|
htypes = types_ids;
|
|
htypes = types_ids;
|
|
gnames = gnames;
|
|
gnames = gnames;
|
|
bytes_names = bnames;
|
|
bytes_names = bnames;
|
|
- defines = [];
|
|
|
|
- hdefines = Hashtbl.create 0;
|
|
|
|
- defined_funs = Hashtbl.create 0;
|
|
|
|
- defined_types = PMap.empty;
|
|
|
|
- file_prefix = "";
|
|
|
|
- fun_index = 0;
|
|
|
|
type_module = PMap.empty;
|
|
type_module = PMap.empty;
|
|
gcon = com;
|
|
gcon = com;
|
|
} in
|
|
} in
|
|
- let modules = make_modules ctx all_types in
|
|
|
|
|
|
+ let modules = make_modules gctx all_types in
|
|
|
|
+ let native_libs = Hashtbl.create 0 in
|
|
|
|
|
|
- let line = line ctx and expr = expr ctx in
|
|
|
|
- let sline fmt = Printf.ksprintf line fmt and sexpr fmt = Printf.ksprintf expr fmt in
|
|
|
|
|
|
+ Path.mkdir_recursive "" (ExtString.String.nsplit (gctx.dir ^ "/hl") "/");
|
|
|
|
|
|
- open_file ctx "hl/natives.h";
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/natives.h" in
|
|
|
|
+ let line = linec ctx and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
define ctx "#ifndef HL_NATIVES_H";
|
|
define ctx "#ifndef HL_NATIVES_H";
|
|
define ctx "#define HL_NATIVES_H";
|
|
define ctx "#define HL_NATIVES_H";
|
|
define ctx "// Abstract decls";
|
|
define ctx "// Abstract decls";
|
|
@@ -1515,15 +1531,14 @@ let write_c com file (code:code) gnames =
|
|
List.iter (fun name -> define ctx (sprintf "typedef struct _%s %s;" name name)) abstracts;
|
|
List.iter (fun name -> define ctx (sprintf "typedef struct _%s %s;" name name)) abstracts;
|
|
define ctx "";
|
|
define ctx "";
|
|
line "// Natives functions";
|
|
line "// Natives functions";
|
|
- let native_libs = Hashtbl.create 0 in
|
|
|
|
let sorted_natives = Array.copy code.natives in
|
|
let sorted_natives = Array.copy code.natives in
|
|
Array.sort (fun n1 n2 -> let mk (lib,name,_,_) = code.strings.(lib), code.strings.(name) in compare (mk n1) (mk n2)) sorted_natives;
|
|
Array.sort (fun n1 n2 -> let mk (lib,name,_,_) = code.strings.(lib), code.strings.(name) in compare (mk n1) (mk n2)) sorted_natives;
|
|
Array.iter (fun (lib,_,_,idx) ->
|
|
Array.iter (fun (lib,_,_,idx) ->
|
|
let name = code.strings.(lib) in
|
|
let name = code.strings.(lib) in
|
|
let name = if name.[0] = '?' then String.sub name 1 (String.length name - 1) else name in
|
|
let name = if name.[0] = '?' then String.sub name 1 (String.length name - 1) else name in
|
|
Hashtbl.replace native_libs name ();
|
|
Hashtbl.replace native_libs name ();
|
|
- let ft = ctx.ftable.(idx) in
|
|
|
|
- define_type ctx (HFun (ft.fe_args,ft.fe_ret));
|
|
|
|
|
|
+ let ft = gctx.ftable.(idx) in
|
|
|
|
+ define_type gctx ctx (HFun (ft.fe_args,ft.fe_ret));
|
|
match ft.fe_name with
|
|
match ft.fe_name with
|
|
| "hl_tls_get_w" ->
|
|
| "hl_tls_get_w" ->
|
|
define ctx "#define hl_tls_get_w(tls) ((vdynamic*)hl_tls_get(tls))";
|
|
define ctx "#define hl_tls_get_w(tls) ((vdynamic*)hl_tls_get(tls))";
|
|
@@ -1534,14 +1549,18 @@ let write_c com file (code:code) gnames =
|
|
) sorted_natives;
|
|
) sorted_natives;
|
|
line "#endif";
|
|
line "#endif";
|
|
line "";
|
|
line "";
|
|
|
|
+ close_file ctx;
|
|
|
|
+ );
|
|
|
|
|
|
- open_file ctx "hl/globals.c";
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/globals.c" in
|
|
|
|
+ let line = linec ctx and expr = exprc ctx and sline fmt = Printf.ksprintf (linec ctx) fmt and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
line "// Globals";
|
|
line "// Globals";
|
|
Array.iteri (fun i t ->
|
|
Array.iteri (fun i t ->
|
|
let name = gnames.(i) in
|
|
let name = gnames.(i) in
|
|
- define_type ctx t;
|
|
|
|
|
|
+ define_type gctx ctx t;
|
|
sexpr "%s = 0" (var_type name t)
|
|
sexpr "%s = 0" (var_type name t)
|
|
) code.globals;
|
|
) code.globals;
|
|
Array.iter (fun (g,fields) ->
|
|
Array.iter (fun (g,fields) ->
|
|
@@ -1552,14 +1571,14 @@ let write_c com file (code:code) gnames =
|
|
| HI32 ->
|
|
| HI32 ->
|
|
Int32.to_string code.ints.(idx)
|
|
Int32.to_string code.ints.(idx)
|
|
| HBytes ->
|
|
| HBytes ->
|
|
- "(vbyte*)" ^ string ctx idx
|
|
|
|
|
|
+ "(vbyte*)" ^ string gctx ctx idx
|
|
| _ ->
|
|
| _ ->
|
|
Globals.die "" __LOC__
|
|
Globals.die "" __LOC__
|
|
in
|
|
in
|
|
let fields = match t with
|
|
let fields = match t with
|
|
| HObj o | HStruct o ->
|
|
| HObj o | HStruct o ->
|
|
let fields = List.map2 field_value (List.map (fun (_,_,t) -> t) (Array.to_list o.pfields)) (Array.to_list fields) in
|
|
let fields = List.map2 field_value (List.map (fun (_,_,t) -> t) (Array.to_list o.pfields)) (Array.to_list fields) in
|
|
- if is_struct t then fields else type_value ctx t :: fields
|
|
|
|
|
|
+ if is_struct t then fields else type_value gctx ctx t :: fields
|
|
| _ ->
|
|
| _ ->
|
|
Globals.die "" __LOC__
|
|
Globals.die "" __LOC__
|
|
in
|
|
in
|
|
@@ -1614,40 +1633,45 @@ let write_c com file (code:code) gnames =
|
|
output_bytes (output_string ch) (Bytes.to_string bytes);
|
|
output_bytes (output_string ch) (Bytes.to_string bytes);
|
|
close_out ch;
|
|
close_out ch;
|
|
end;
|
|
end;
|
|
- sline "vbyte %s[] = {" ctx.bytes_names.(i);
|
|
|
|
|
|
+ sline "vbyte %s[] = {" gctx.bytes_names.(i);
|
|
output ctx (Printf.sprintf "#%s include \"%s\"\n" ctx.tabs bytes_file);
|
|
output ctx (Printf.sprintf "#%s include \"%s\"\n" ctx.tabs bytes_file);
|
|
sexpr "}";
|
|
sexpr "}";
|
|
end else begin
|
|
end else begin
|
|
- output ctx (Printf.sprintf "vbyte %s[] = {" ctx.bytes_names.(i));
|
|
|
|
|
|
+ output ctx (Printf.sprintf "vbyte %s[] = {" gctx.bytes_names.(i));
|
|
output_bytes (output ctx) (Bytes.to_string bytes);
|
|
output_bytes (output ctx) (Bytes.to_string bytes);
|
|
sexpr "}";
|
|
sexpr "}";
|
|
end
|
|
end
|
|
) code.bytes;
|
|
) code.bytes;
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/types.c" in
|
|
|
|
+ let line = linec ctx and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
let type_value ctx t = "&" ^ type_name ctx t in (* no auto import *)
|
|
let type_value ctx t = "&" ^ type_name ctx t in (* no auto import *)
|
|
- open_file ctx "hl/types.c";
|
|
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
line "// Types values";
|
|
line "// Types values";
|
|
Array.iteri (fun i t ->
|
|
Array.iteri (fun i t ->
|
|
match t with
|
|
match t with
|
|
| HMethod _ | HFun _ | HVirtual _ ->
|
|
| HMethod _ | HFun _ | HVirtual _ ->
|
|
- sexpr "hl_type %s = { %s } /* %s */" (type_name ctx t) (type_id t) (tstr t);
|
|
|
|
|
|
+ sexpr "hl_type %s = { %s } /* %s */" (type_name gctx t) (type_id t) (tstr t);
|
|
| _ ->
|
|
| _ ->
|
|
- sexpr "hl_type %s = { %s }" (type_name ctx t) (type_id t);
|
|
|
|
|
|
+ sexpr "hl_type %s = { %s }" (type_name gctx t) (type_id t);
|
|
) all_types;
|
|
) all_types;
|
|
|
|
|
|
line "";
|
|
line "";
|
|
line "// Types values data";
|
|
line "// Types values data";
|
|
Array.iter (fun t ->
|
|
Array.iter (fun t ->
|
|
let field_value (_,name_id,t) =
|
|
let field_value (_,name_id,t) =
|
|
- sprintf "{(const uchar*)%s, %s, %ld}" (string ctx name_id) (type_value ctx t) (hash ctx name_id)
|
|
|
|
|
|
+ sprintf "{(const uchar*)%s, %s, %ld}" (string gctx ctx name_id) (type_value gctx t) (hash gctx name_id)
|
|
in
|
|
in
|
|
match t with
|
|
match t with
|
|
| HObj o | HStruct o ->
|
|
| HObj o | HStruct o ->
|
|
- let name = type_name ctx t in
|
|
|
|
|
|
+ let name = type_name gctx t in
|
|
let proto_value p =
|
|
let proto_value p =
|
|
- sprintf "{(const uchar*)%s, %d, %d, %ld}" (string ctx p.fid) p.fmethod (match p.fvirtual with None -> -1 | Some i -> i) (hash ctx p.fid)
|
|
|
|
|
|
+ sprintf "{(const uchar*)%s, %d, %d, %ld}" (string gctx ctx p.fid) p.fmethod (match p.fvirtual with None -> -1 | Some i -> i) (hash gctx p.fid)
|
|
in
|
|
in
|
|
let fields =
|
|
let fields =
|
|
if Array.length o.pfields = 0 then "NULL" else
|
|
if Array.length o.pfields = 0 then "NULL" else
|
|
@@ -1671,29 +1695,29 @@ let write_c com file (code:code) gnames =
|
|
string_of_int (Array.length o.pfields);
|
|
string_of_int (Array.length o.pfields);
|
|
string_of_int (Array.length o.pproto);
|
|
string_of_int (Array.length o.pproto);
|
|
string_of_int (List.length o.pbindings);
|
|
string_of_int (List.length o.pbindings);
|
|
- sprintf "(const uchar*)%s" (string ctx o.pid);
|
|
|
|
- (match o.psuper with None -> "NULL" | Some c -> type_value ctx (match t with HObj _ -> HObj c | _ -> HStruct c));
|
|
|
|
|
|
+ sprintf "(const uchar*)%s" (string gctx ctx o.pid);
|
|
|
|
+ (match o.psuper with None -> "NULL" | Some c -> type_value gctx (match t with HObj _ -> HObj c | _ -> HStruct c));
|
|
fields;
|
|
fields;
|
|
proto;
|
|
proto;
|
|
bindings
|
|
bindings
|
|
] in
|
|
] in
|
|
sexpr "static hl_type_obj obj%s = {%s}" name (String.concat "," ofields);
|
|
sexpr "static hl_type_obj obj%s = {%s}" name (String.concat "," ofields);
|
|
| HEnum e ->
|
|
| HEnum e ->
|
|
- let ename = type_name ctx t in
|
|
|
|
|
|
+ let ename = type_name gctx t in
|
|
let constr_value cid (name,nid,tl) =
|
|
let constr_value cid (name,nid,tl) =
|
|
let tval = if Array.length tl = 0 then "NULL" else
|
|
let tval = if Array.length tl = 0 then "NULL" else
|
|
let name = sprintf "econstruct%s_%d" ename cid in
|
|
let name = sprintf "econstruct%s_%d" ename cid in
|
|
- sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value ctx) (Array.to_list tl)));
|
|
|
|
|
|
+ sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value gctx) (Array.to_list tl)));
|
|
name
|
|
name
|
|
in
|
|
in
|
|
- let size = if Array.length tl = 0 then "0" else sprintf "sizeof(%s)" (enum_constr_type ctx e cid) in
|
|
|
|
|
|
+ let size = if Array.length tl = 0 then "0" else sprintf "sizeof(%s)" (enum_constr_type gctx ctx e cid) in
|
|
let offsets = if Array.length tl = 0 then "NULL" else
|
|
let offsets = if Array.length tl = 0 then "NULL" else
|
|
let name = sprintf "eoffsets%s_%d" ename cid in
|
|
let name = sprintf "eoffsets%s_%d" ename cid in
|
|
sexpr "static int %s[] = {%s}" name (String.concat "," (List.map (fun _ -> "0") (Array.to_list tl)));
|
|
sexpr "static int %s[] = {%s}" name (String.concat "," (List.map (fun _ -> "0") (Array.to_list tl)));
|
|
name
|
|
name
|
|
in
|
|
in
|
|
let has_ptr = List.exists is_gc_ptr (Array.to_list tl) in
|
|
let has_ptr = List.exists is_gc_ptr (Array.to_list tl) in
|
|
- sprintf "{(const uchar*)%s, %d, %s, %s, %s, %s}" (string ctx nid) (Array.length tl) tval size (if has_ptr then "true" else "false") offsets
|
|
|
|
|
|
+ sprintf "{(const uchar*)%s, %d, %s, %s, %s, %s}" (string gctx ctx nid) (Array.length tl) tval size (if has_ptr then "true" else "false") offsets
|
|
in
|
|
in
|
|
let constr_name = if Array.length e.efields = 0 then "NULL" else begin
|
|
let constr_name = if Array.length e.efields = 0 then "NULL" else begin
|
|
let name = sprintf "econstruct%s" ename in
|
|
let name = sprintf "econstruct%s" ename in
|
|
@@ -1701,13 +1725,13 @@ let write_c com file (code:code) gnames =
|
|
name;
|
|
name;
|
|
end in
|
|
end in
|
|
let efields = [
|
|
let efields = [
|
|
- if e.eid = 0 then "NULL" else sprintf "(const uchar*)%s" (string ctx e.eid);
|
|
|
|
|
|
+ if e.eid = 0 then "NULL" else sprintf "(const uchar*)%s" (string gctx ctx e.eid);
|
|
string_of_int (Array.length e.efields);
|
|
string_of_int (Array.length e.efields);
|
|
constr_name
|
|
constr_name
|
|
] in
|
|
] in
|
|
sexpr "static hl_type_enum enum%s = {%s}" ename (String.concat "," efields);
|
|
sexpr "static hl_type_enum enum%s = {%s}" ename (String.concat "," efields);
|
|
| HVirtual v ->
|
|
| HVirtual v ->
|
|
- let vname = type_name ctx t in
|
|
|
|
|
|
+ let vname = type_name gctx t in
|
|
let fields_name =
|
|
let fields_name =
|
|
if Array.length v.vfields = 0 then "NULL" else
|
|
if Array.length v.vfields = 0 then "NULL" else
|
|
let name = sprintf "vfields%s" vname in
|
|
let name = sprintf "vfields%s" vname in
|
|
@@ -1720,13 +1744,13 @@ let write_c com file (code:code) gnames =
|
|
] in
|
|
] in
|
|
sexpr "static hl_type_virtual virt%s = {%s}" vname (String.concat "," vfields);
|
|
sexpr "static hl_type_virtual virt%s = {%s}" vname (String.concat "," vfields);
|
|
| HFun (args,ret) | HMethod(args,ret) ->
|
|
| HFun (args,ret) | HMethod(args,ret) ->
|
|
- let fname = type_name ctx t in
|
|
|
|
|
|
+ let fname = type_name gctx t in
|
|
let aname = if args = [] then "NULL" else
|
|
let aname = if args = [] then "NULL" else
|
|
let name = sprintf "fargs%s" fname in
|
|
let name = sprintf "fargs%s" fname in
|
|
- sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value ctx) args));
|
|
|
|
|
|
+ sexpr "static hl_type *%s[] = {%s}" name (String.concat "," (List.map (type_value gctx) args));
|
|
name
|
|
name
|
|
in
|
|
in
|
|
- sexpr "static hl_type_fun tfun%s = {%s,%s,%d}" fname aname (type_value ctx ret) (List.length args)
|
|
|
|
|
|
+ sexpr "static hl_type_fun tfun%s = {%s,%s,%d}" fname aname (type_value gctx ret) (List.length args)
|
|
| _ ->
|
|
| _ ->
|
|
()
|
|
()
|
|
) all_types;
|
|
) all_types;
|
|
@@ -1740,7 +1764,7 @@ let write_c com file (code:code) gnames =
|
|
sexpr "fdump(&ntypes,4)";
|
|
sexpr "fdump(&ntypes,4)";
|
|
let fcount = ref 0 in
|
|
let fcount = ref 0 in
|
|
Array.iter (fun t ->
|
|
Array.iter (fun t ->
|
|
- sexpr "t = &%s; fdump(&t, sizeof(void*))" (type_name ctx t);
|
|
|
|
|
|
+ sexpr "t = &%s; fdump(&t, sizeof(void*))" (type_name gctx t);
|
|
(match t with
|
|
(match t with
|
|
| HFun _ -> incr fcount
|
|
| HFun _ -> incr fcount
|
|
| _ -> ());
|
|
| _ -> ());
|
|
@@ -1750,7 +1774,7 @@ let write_c com file (code:code) gnames =
|
|
Array.iter (fun t ->
|
|
Array.iter (fun t ->
|
|
match t with
|
|
match t with
|
|
| HFun _ ->
|
|
| HFun _ ->
|
|
- sexpr "t = (hl_type*)&%s.fun->closure_type; fdump(&t, sizeof(void*))" (type_name ctx t);
|
|
|
|
|
|
+ sexpr "t = (hl_type*)&%s.fun->closure_type; fdump(&t, sizeof(void*))" (type_name gctx t);
|
|
| _ -> ()
|
|
| _ -> ()
|
|
) all_types;
|
|
) all_types;
|
|
line "#else";
|
|
line "#else";
|
|
@@ -1765,31 +1789,31 @@ let write_c com file (code:code) gnames =
|
|
Array.iter (fun t ->
|
|
Array.iter (fun t ->
|
|
match t with
|
|
match t with
|
|
| HObj o | HStruct o ->
|
|
| HObj o | HStruct o ->
|
|
- let name = type_name ctx t in
|
|
|
|
|
|
+ let name = type_name gctx t in
|
|
sexpr "obj%s.m = ctx" name;
|
|
sexpr "obj%s.m = ctx" name;
|
|
(match o.pclassglobal with
|
|
(match o.pclassglobal with
|
|
| None -> ()
|
|
| None -> ()
|
|
| Some g ->
|
|
| Some g ->
|
|
- define_global ctx g;
|
|
|
|
|
|
+ define_global gctx ctx g;
|
|
sexpr "obj%s.global_value = (void**)&%s" name gnames.(g));
|
|
sexpr "obj%s.global_value = (void**)&%s" name gnames.(g));
|
|
sexpr "%s.obj = &obj%s" name name
|
|
sexpr "%s.obj = &obj%s" name name
|
|
| HNull r | HRef r | HPacked r ->
|
|
| HNull r | HRef r | HPacked r ->
|
|
- sexpr "%s.tparam = %s" (type_name ctx t) (type_value ctx r)
|
|
|
|
|
|
+ sexpr "%s.tparam = %s" (type_name gctx t) (type_value gctx r)
|
|
| HEnum e ->
|
|
| HEnum e ->
|
|
- let name = type_name ctx t in
|
|
|
|
|
|
+ let name = type_name gctx t in
|
|
sexpr "%s.tenum = &enum%s" name name;
|
|
sexpr "%s.tenum = &enum%s" name name;
|
|
(match e.eglobal with
|
|
(match e.eglobal with
|
|
| None -> ()
|
|
| None -> ()
|
|
| Some g ->
|
|
| Some g ->
|
|
- define_global ctx g;
|
|
|
|
|
|
+ define_global gctx ctx g;
|
|
sexpr "enum%s.global_value = (void**)&%s" name gnames.(g));
|
|
sexpr "enum%s.global_value = (void**)&%s" name gnames.(g));
|
|
sexpr "hl_init_enum(&%s,ctx)" name;
|
|
sexpr "hl_init_enum(&%s,ctx)" name;
|
|
| HVirtual _ ->
|
|
| HVirtual _ ->
|
|
- let name = type_name ctx t in
|
|
|
|
|
|
+ let name = type_name gctx t in
|
|
sexpr "%s.virt = &virt%s" name name;
|
|
sexpr "%s.virt = &virt%s" name name;
|
|
sexpr "hl_init_virtual(&%s,ctx)" name;
|
|
sexpr "hl_init_virtual(&%s,ctx)" name;
|
|
| HFun _ | HMethod _ ->
|
|
| HFun _ | HMethod _ ->
|
|
- let name = type_name ctx t in
|
|
|
|
|
|
+ let name = type_name gctx t in
|
|
sexpr "%s.fun = &tfun%s" name name
|
|
sexpr "%s.fun = &tfun%s" name name
|
|
| _ ->
|
|
| _ ->
|
|
()
|
|
()
|
|
@@ -1797,22 +1821,41 @@ let write_c com file (code:code) gnames =
|
|
sexpr "hl_gc_set_dump_types(dump_types)";
|
|
sexpr "hl_gc_set_dump_types(dump_types)";
|
|
unblock ctx;
|
|
unblock ctx;
|
|
line "}";
|
|
line "}";
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
|
|
- open_file ctx "hl/reflect.c";
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/reflect.c" in
|
|
|
|
+ let line = linec ctx in
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
line "// Reflection helpers";
|
|
line "// Reflection helpers";
|
|
- generate_reflection ctx;
|
|
|
|
-
|
|
|
|
- List.iter (fun m ->
|
|
|
|
|
|
+ generate_reflection gctx ctx;
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ (
|
|
|
|
+ let modules = Array.of_list modules in
|
|
|
|
+ Array.iter (fun m ->
|
|
|
|
+ let path = Filename.dirname m.m_name in
|
|
|
|
+ if not (Sys.file_exists (gctx.dir ^ "/" ^ path)) then
|
|
|
|
+ Path.mkdir_recursive gctx.dir (ExtString.String.nsplit path "/");
|
|
|
|
+ (* add cfiles in deterministic order *)
|
|
|
|
+ if m.m_functions <> [] then save_cfile gctx (m.m_name ^ ".c")
|
|
|
|
+ ) modules;
|
|
|
|
+ Parallel.run_parallel_for num_domains (Array.length modules) (fun idx ->
|
|
|
|
+ let m = modules.(idx) in
|
|
let defined_types = ref PMap.empty in
|
|
let defined_types = ref PMap.empty in
|
|
if m.m_types <> [] then begin
|
|
if m.m_types <> [] then begin
|
|
- open_file ctx (m.m_name ^ ".h");
|
|
|
|
- generate_module_types ctx m;
|
|
|
|
|
|
+ let ctx = open_file gctx (m.m_name ^ ".h") in
|
|
|
|
+ generate_module_types gctx ctx m;
|
|
defined_types := ctx.defined_types;
|
|
defined_types := ctx.defined_types;
|
|
|
|
+ close_file ctx;
|
|
end;
|
|
end;
|
|
if m.m_functions <> [] then begin
|
|
if m.m_functions <> [] then begin
|
|
- open_file ctx (m.m_name ^ ".c");
|
|
|
|
|
|
+ let ctx = open_file gctx (m.m_name ^ ".c") in
|
|
ctx.defined_types <- !defined_types;
|
|
ctx.defined_types <- !defined_types;
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
@@ -1826,47 +1869,61 @@ let write_c com file (code:code) gnames =
|
|
("",0)
|
|
("",0)
|
|
in
|
|
in
|
|
let funcs = List.sort (fun f1 f2 -> compare (file_pos f1) (file_pos f2)) m.m_functions in
|
|
let funcs = List.sort (fun f1 f2 -> compare (file_pos f1) (file_pos f2)) m.m_functions in
|
|
- List.iter (fun fe -> match fe.fe_decl with None -> () | Some f -> generate_function ctx f) funcs;
|
|
|
|
|
|
+ List.iter (fun fe -> match fe.fe_decl with None -> () | Some f -> generate_function gctx ctx f) funcs;
|
|
|
|
+ close_file ctx;
|
|
end;
|
|
end;
|
|
- ) modules;
|
|
|
|
|
|
+ );
|
|
|
|
+ );
|
|
|
|
|
|
- open_file ctx "hl/functions.c";
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/functions.c" in
|
|
|
|
+ let line = linec ctx and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
sexpr "void *hl_functions_ptrs[] = {%s}" (String.concat ",\\\n\t" (List.map (fun f ->
|
|
sexpr "void *hl_functions_ptrs[] = {%s}" (String.concat ",\\\n\t" (List.map (fun f ->
|
|
- let name = define_function ctx f.fe_index in
|
|
|
|
|
|
+ let name = define_function gctx ctx f.fe_index in
|
|
if name = "hl_tls_get_w" then "hl_tls_get" else name
|
|
if name = "hl_tls_get_w" then "hl_tls_get" else name
|
|
- ) (Array.to_list ctx.ftable)));
|
|
|
|
|
|
+ ) (Array.to_list gctx.ftable)));
|
|
let rec loop i =
|
|
let rec loop i =
|
|
- if i = Array.length ctx.ftable then [] else
|
|
|
|
- let ft = ctx.ftable.(i) in
|
|
|
|
- let n = type_name ctx (HFun (ft.fe_args,ft.fe_ret)) in
|
|
|
|
|
|
+ if i = Array.length gctx.ftable then [] else
|
|
|
|
+ let ft = gctx.ftable.(i) in
|
|
|
|
+ let n = type_name gctx (HFun (ft.fe_args,ft.fe_ret)) in
|
|
define ctx (sprintf "extern hl_type %s;" n);
|
|
define ctx (sprintf "extern hl_type %s;" n);
|
|
("&" ^ n) :: loop (i + 1)
|
|
("&" ^ n) :: loop (i + 1)
|
|
in
|
|
in
|
|
sexpr "hl_type *hl_functions_types[] = {%s}" (String.concat ",\\\n\t" (loop 0));
|
|
sexpr "hl_type *hl_functions_types[] = {%s}" (String.concat ",\\\n\t" (loop 0));
|
|
line "";
|
|
line "";
|
|
Array.iter (fun f ->
|
|
Array.iter (fun f ->
|
|
- if f.fe_module = None then (match f.fe_decl with None -> () | Some f -> generate_function ctx f);
|
|
|
|
- ) ctx.ftable;
|
|
|
|
-
|
|
|
|
- open_file ctx "hl/hashes.c";
|
|
|
|
|
|
+ if f.fe_module = None then (match f.fe_decl with None -> () | Some f -> generate_function gctx ctx f);
|
|
|
|
+ ) gctx.ftable;
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hl/hashes.c" in
|
|
|
|
+ let line = linec ctx and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
line "";
|
|
line "";
|
|
line "void hl_init_hashes() {";
|
|
line "void hl_init_hashes() {";
|
|
block ctx;
|
|
block ctx;
|
|
- List.iter (fun i -> sexpr "hl_hash((vbyte*)%s)" (string ctx i)) (List.rev ctx.hash_cache_list);
|
|
|
|
|
|
+ List.iter (fun i -> sexpr "hl_hash((vbyte*)%s)" (string gctx ctx i)) (List.rev gctx.hash_cache_list);
|
|
unblock ctx;
|
|
unblock ctx;
|
|
line "}";
|
|
line "}";
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
|
|
- open_file ctx (Filename.basename file);
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx (Filename.basename file) in
|
|
|
|
+ let line = linec ctx and expr = exprc ctx and sline fmt = Printf.ksprintf (linec ctx) fmt and sexpr fmt = Printf.ksprintf (exprc ctx) fmt in
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#define HLC_BOOT";
|
|
define ctx "#include <hlc.h>";
|
|
define ctx "#include <hlc.h>";
|
|
line "#include <hlc_main.c>";
|
|
line "#include <hlc_main.c>";
|
|
line "";
|
|
line "";
|
|
line "#ifndef HL_MAKE";
|
|
line "#ifndef HL_MAKE";
|
|
- List.iter (sline "# include <%s>") ctx.cfiles;
|
|
|
|
|
|
+ List.iter (sline "# include <%s>") gctx.cfiles;
|
|
line "#endif";
|
|
line "#endif";
|
|
line "";
|
|
line "";
|
|
expr "void hl_init_hashes()";
|
|
expr "void hl_init_hashes()";
|
|
@@ -1885,16 +1942,20 @@ let write_c com file (code:code) gnames =
|
|
expr "hl_init_types(&ctx)";
|
|
expr "hl_init_types(&ctx)";
|
|
expr "hl_init_hashes()";
|
|
expr "hl_init_hashes()";
|
|
expr "hl_init_roots()";
|
|
expr "hl_init_roots()";
|
|
- if code.entrypoint >= 0 then sexpr "%s()" (define_function ctx code.entrypoint);
|
|
|
|
|
|
+ if code.entrypoint >= 0 then sexpr "%s()" (define_function gctx ctx code.entrypoint);
|
|
unblock ctx;
|
|
unblock ctx;
|
|
line "}";
|
|
line "}";
|
|
line "";
|
|
line "";
|
|
|
|
+ close_file ctx;
|
|
|
|
+ save_cfile gctx ctx.curfile;
|
|
|
|
+ );
|
|
|
|
|
|
- open_file ctx "hlc.json";
|
|
|
|
-
|
|
|
|
|
|
+ (
|
|
|
|
+ let ctx = open_file gctx "hlc.json" in
|
|
|
|
+ let line = linec ctx and sline fmt = Printf.ksprintf (linec ctx) fmt in
|
|
line "{";
|
|
line "{";
|
|
block ctx;
|
|
block ctx;
|
|
- sline "\"version\" : %d," ctx.version;
|
|
|
|
|
|
+ sline "\"version\" : %d," gctx.version;
|
|
sline "\"libs\" : [%s]," (String.concat "," (Hashtbl.fold (fun k _ acc -> sprintf "\"%s\"" k :: acc) native_libs []));
|
|
sline "\"libs\" : [%s]," (String.concat "," (Hashtbl.fold (fun k _ acc -> sprintf "\"%s\"" k :: acc) native_libs []));
|
|
let defines = Buffer.create 64 in
|
|
let defines = Buffer.create 64 in
|
|
PMap.iter (fun key value ->
|
|
PMap.iter (fun key value ->
|
|
@@ -1902,8 +1963,8 @@ let write_c com file (code:code) gnames =
|
|
) com.defines.values;
|
|
) com.defines.values;
|
|
Buffer.truncate defines (Buffer.length defines - 1);
|
|
Buffer.truncate defines (Buffer.length defines - 1);
|
|
sline "\"defines\" : {%s\n\t}," (Buffer.contents defines);
|
|
sline "\"defines\" : {%s\n\t}," (Buffer.contents defines);
|
|
- sline "\"files\" : [%s\n\t]" (String.concat "," (List.map (sprintf "\n\t\t\"%s\"") ctx.cfiles));
|
|
|
|
|
|
+ sline "\"files\" : [%s\n\t]" (String.concat "," (List.map (sprintf "\n\t\t\"%s\"") gctx.cfiles));
|
|
unblock ctx;
|
|
unblock ctx;
|
|
line "}";
|
|
line "}";
|
|
-
|
|
|
|
- close_file ctx
|
|
|
|
|
|
+ close_file ctx;
|
|
|
|
+ );
|