Selaa lähdekoodia

separate macro api from interp
use haxe values instead of neko ones for api calls
use $__mk_pos__ and $__delayed_call__ for macro specific builtins

Nicolas Cannasse 8 vuotta sitten
vanhempi
commit
9101843f04

+ 8 - 6
Makefile

@@ -59,7 +59,7 @@ MODULES=json version globals path context/meta syntax/ast display/displayTypes t
 	syntax/parser typing/abstract typing/typecore display/display optimization/optimizerTexpr \
 	optimization/optimizer typing/overloads typing/typeload generators/codegen generators/gencommon generators/genas3 \
 	generators/gencpp generators/genjs generators/genneko generators/genphp generators/genswf9 \
-	generators/genswf generators/genjava generators/gencs generators/genpy macro/interp generators/hlcode generators/hlopt generators/hlinterp generators/hl2c generators/genhl \
+	generators/genswf generators/genjava generators/gencs generators/genpy macro/macroApi macro/interp generators/hlcode generators/hlopt generators/hlinterp generators/hl2c generators/genhl \
 	generators/genlua \
 	optimization/dce optimization/analyzerConfig optimization/analyzerTypes optimization/analyzerTexpr \
 	optimization/analyzerTexprTransformer optimization/analyzer \
@@ -175,7 +175,7 @@ src/generators/genpy.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/global
 
 src/generators/genswf.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/generators/genswf9.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT)
 
-src/generators/hlinterp.$(MODULE_EXT): src/context/common.$(MODULE_EXT) src/generators/hlcode.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/generators/hlopt.$(MODULE_EXT)
+src/generators/hlinterp.$(MODULE_EXT): src/context/common.$(MODULE_EXT) src/generators/hlcode.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/generators/hlopt.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT)
 
 src/generators/hl2c.$(MODULE_EXT): src/generators/hlcode.$(MODULE_EXT)
 
@@ -189,11 +189,13 @@ src/generators/genxml.$(MODULE_EXT): src/globals.$(MODULE_EXT) src/context/meta.
 
 # macro
 
-src/macro/interp.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/generators/genneko.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genswf.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT)
+src/macro/interp.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/generators/genneko.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/generators/genswf.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) libs/ilib/il.$(LIB_EXT) src/macro/macroApi.$(MODULE_EXT)
 
-src/macro/macroContext.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/macro/hlmacro.$(MODULE_EXT)
- 
-src/macro/hlmacro.$(MODULE_EXT): src/generators/hlinterp.$(MODULE_EXT) src/generators/genhl.$(MODULE_EXT)
+src/macro/macroContext.$(MODULE_EXT): src/typing/abstract.$(MODULE_EXT) src/context/meta.$(MODULE_EXT) src/globals.$(MODULE_EXT) src/typing/error.$(MODULE_EXT) src/optimization/optimizerTexpr.$(MODULE_EXT) src/typing/overloads.$(MODULE_EXT) src/path.$(MODULE_EXT) src/typing/typeload.$(MODULE_EXT) src/typing/typecore.$(MODULE_EXT) src/typing/type.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT) src/optimization/optimizer.$(MODULE_EXT) src/syntax/lexer.$(MODULE_EXT) src/macro/interp.$(MODULE_EXT) src/context/common.$(MODULE_EXT) src/generators/codegen.$(MODULE_EXT) src/syntax/ast.$(MODULE_EXT) src/optimization/filters.$(MODULE_EXT) src/generators/genjs.$(MODULE_EXT) src/display/display.$(MODULE_EXT) src/macro/hlmacro.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT)
+
+src/macro/hlmacro.$(MODULE_EXT): src/generators/hlinterp.$(MODULE_EXT) src/generators/genhl.$(MODULE_EXT) src/macro/macroApi.$(MODULE_EXT)
+
+src/macro/macroApi.$(MODULE_EXT): src/generators/genjs.$(MODULE_EXT) src/generators/gencs.$(MODULE_EXT) src/generators/genjava.$(MODULE_EXT) src/syntax/parser.$(MODULE_EXT)
 
 # optimization
 

+ 4 - 0
haxe.hxproj

@@ -412,6 +412,10 @@
     <hidden path="src\macro\hlmacro.cmt" />
     <hidden path="src\macro\hlmacro.cmx" />
     <hidden path="src\macro\hlmacro.o" />
+    <hidden path="src\macro\macroApi.cmi" />
+    <hidden path="src\macro\macroApi.cmt" />
+    <hidden path="src\macro\macroApi.cmx" />
+    <hidden path="src\macro\macroApi.o" />
   </hiddenPaths>
   <!-- Executed before build -->
   <preBuildCommand>make -j4 FD_OUTPUT=1 -f Makefile.win kill haxe</preBuildCommand>

+ 33 - 15
src/generators/genhl.ml

@@ -94,7 +94,7 @@ type context = {
 	mutable anons_cache : (tanon * ttype) list;
 	mutable method_wrappers : ((ttype * ttype), int) PMap.t;
 	mutable rec_cache : (Type.t * ttype option ref) list;
-	mutable captured_cache : (ttype list, ttype) PMap.t;
+	mutable cached_tuples : (ttype list, ttype) PMap.t;
 	array_impl : array_impl;
 	base_class : tclass;
 	base_type : tclass;
@@ -160,6 +160,19 @@ let to_utf8 str p =
 	) u8;
 	u8, !ccount
 
+let tuple_type ctx tl =
+	try
+		PMap.find tl ctx.cached_tuples
+	with Not_found ->
+		let ct = HEnum {
+			eglobal = None;
+			ename = "";
+			eid = 0;
+			efields = [|"",0,Array.of_list tl|];
+		} in
+		ctx.cached_tuples <- PMap.add tl ct ctx.cached_tuples;
+		ct
+
 let type_size_bits = function
 	| HUI8 | HBool -> 0
 	| HUI16 -> 1
@@ -422,6 +435,7 @@ let rec to_type ?tref ctx t =
 			| ["hl"], "UI16" -> HUI16
 			| ["hl"], "UI8" -> HUI8
 			| ["hl"], "NativeArray" -> HArray
+			| ["haxe";"macro"], "Position" -> HAbstract ("macro_pos", alloc_string ctx "macro_pos")
 			| _ -> failwith ("Unknown core type " ^ s_type_path a.a_path))
 		else
 			to_type ?tref ctx (Abstract.get_underlying_type a pl)
@@ -672,6 +686,9 @@ and class_global ?(resolve=true) ctx c =
 let resolve_class_global ctx cpath =
 	lookup ctx.cglobals ("$" ^ cpath) (fun() -> assert false)
 
+let resolve_type ctx path =
+	PMap.find path ctx.cached_types
+
 let alloc_std ctx name args ret =
 	let lib = "std" in
 	(* different from :hlNative to prevent mismatch *)
@@ -1775,6 +1792,19 @@ and eval_expr ctx e =
 			op ctx (ONullCheck re);
 			op ctx (OEnumIndex (r,re));
 			r
+		| "$__mk_pos__", [{ eexpr = TConst (TString file) };min;max] ->
+			(* macros only - generated by reification *)
+			let rt = HAbstract ("macro_pos",alloc_string ctx "macro_pos") in
+			let r = alloc_tmp ctx rt in
+			let rfile = alloc_tmp ctx HBytes in
+			op ctx (OBytes (rfile, alloc_string ctx file));
+			hold ctx rfile;
+			let min = eval_expr ctx min in hold ctx min;
+			let max = eval_expr ctx max in
+			op ctx (OCall3 (r,alloc_std ctx "make_macro_pos" [HBytes;HI32;HI32] rt,rfile,min,max));
+			free ctx rfile;
+			free ctx min;
+			r
 		| _ ->
 			abort ("Unknown native call " ^ v.v_name) e.epos)
 	| TCall (ec,args) ->
@@ -2638,19 +2668,7 @@ and build_capture_vars ctx f =
 		| _ ->
 			Array.iteri (fun i v -> indexes := PMap.add v.v_id i !indexes) cvars;
 			let ctypes = Array.map (fun v -> to_type ctx v.v_type) cvars in
-			let ltypes = Array.to_list ctypes in
-			let ct = (try
-				PMap.find ltypes ctx.captured_cache
-			with Not_found ->
-				let ct = HEnum {
-					eglobal = None;
-					ename = "";
-					eid = 0;
-					efields = [|"",0,ctypes|];
-				} in
-				ctx.captured_cache <- PMap.add ltypes ct ctx.captured_cache;
-				ct
-			) in
+			let ct = tuple_type ctx (Array.to_list ctypes) in
 			ct, true
 	) in
 	{
@@ -3453,7 +3471,7 @@ let create_context com is_macro dump =
 		cfunctions = DynArray.create();
 		overrides = Hashtbl.create 0;
 		cached_types = PMap.empty;
-		captured_cache = PMap.empty;
+		cached_tuples = PMap.empty;
 		cfids = new_lookup();
 		defined_funs = Hashtbl.create 0;
 		array_impl = {

+ 17 - 1
src/generators/hlinterp.ml

@@ -51,6 +51,7 @@ and vabstract =
 	| AHashObject of (value * value) list ref
 	| AReg of regexp
 	| ARandom
+	| APos of Globals.pos
 
 and vfunction =
 	| FFun of fundecl
@@ -105,6 +106,7 @@ type context = {
 	mutable fcall : vfunction -> value list -> value;
 	mutable code : code;
 	mutable on_error : value -> (fundecl * int ref) list -> unit;
+	mutable resolve_macro_api : string -> (value list -> value) option;
 	checked : bool;
 	cached_protos : (int, vproto * ttype array) Hashtbl.t;
 	cached_strings : (int, string) Hashtbl.t;
@@ -617,7 +619,7 @@ let make_stack ctx (f,pos) =
 
 let stack_frame ctx (f,pos) =
 	let file, line = make_stack ctx (f,pos) in
-	Printf.sprintf "%s:%d: Called from fun(%d)@x%x" file line f.findex (!pos - 1)
+	Printf.sprintf "%s:%d: Called from fun@%d @x%X" file line f.findex (!pos - 1)
 
 let rec vstr ctx v t =
 	let vstr = vstr ctx in
@@ -668,6 +670,7 @@ let interp ctx f args =
 		Array.blit ctx.stack 0 nstack 0 ctx.stack_pos;
 		ctx.stack <- nstack;
 	end;
+	if ctx.checked then for i = 0 to Array.length f.regs - 1 do ctx.stack.(i + spos) <- VUndef; done;
 	ctx.stack_pos <- spos + Array.length f.regs;
 
 	let pos = ref 1 in
@@ -1926,8 +1929,17 @@ let load_native ctx lib name t =
 				| None -> to_int (-1)
 				| Some (pos,pend) -> to_int pos)
 			| _ -> assert false)
+		| "make_macro_pos" ->
+			(function
+			| [VBytes file;VInt min;VInt max] ->
+				VAbstract (APos { Globals.pfile = String.sub file 0 (String.length file - 1); pmin = Int32.to_int min; pmax = Int32.to_int max })
+			| _ -> assert false)
 		| _ ->
 			unresolved())
+	| "macro" ->
+		(match ctx.resolve_macro_api name with
+		| None -> unresolved()
+		| Some f -> f)
 	| _ ->
 		unresolved()
 	) in
@@ -1958,6 +1970,7 @@ let create checked =
 		checked = checked;
 		fcall = (fun _ _ -> assert false);
 		on_error = (fun _ _ -> assert false);
+		resolve_macro_api = (fun _ -> None);
 	} in
 	ctx.on_error <- (fun msg stack -> failwith (vstr ctx msg HDyn ^ "\n" ^ String.concat "\n" (List.map (stack_frame ctx) stack)));
 	ctx.fcall <- call_fun ctx;
@@ -1966,6 +1979,9 @@ let create checked =
 let set_error_handler ctx e =
 	ctx.on_error <- e
 
+let set_macro_api ctx f =
+	ctx.resolve_macro_api <- f
+
 let add_code ctx code =
 	(* expand global table *)
 	let globals = Array.map default code.globals in

+ 105 - 1
src/macro/hlmacro.ml

@@ -18,6 +18,8 @@
  *)
 open Globals
 open Type
+open Ast
+open Hlcode
 open Hlinterp
 
 type value = Hlinterp.value
@@ -79,6 +81,7 @@ exception Error of string * Globals.pos list
 
 let debug = true (* TODO !!! set to false for speed++ ! *)
 
+let resolve_macro_api_ref = ref (fun _ _ -> None)
 let get_ctx_ref = ref (fun() -> assert false)
 let get_ctx() : context = (!get_ctx_ref)()
 
@@ -125,6 +128,7 @@ let create com api =
 	} in
 	select ctx;
 	Hlinterp.set_error_handler ctx.interp (error_handler ctx);
+	Hlinterp.set_macro_api ctx.interp ((!resolve_macro_api_ref) ctx);
 	ctx
 
 let init ctx =
@@ -252,10 +256,110 @@ let decode_field (f:value) = assert false
 let decode_ctype (c:value) = assert false
 let decode_type (t:value) = assert false
 
+let enc_enum tag pl = VEnum (tag,Array.of_list pl)
+
+let enc_inst path fields =
+	let ctx = get_ctx() in
+	let t = (match ctx.gen with None -> assert false | Some gen -> try Genhl.resolve_type gen path with Not_found -> assert false) in
+	match t with
+	| HObj o ->
+		let proto, _ = Hlinterp.get_proto ctx.interp o in
+		VObj { oproto = proto; ofields = fields }
+	| _ ->
+		assert false
+
+let enc_string s =
+	enc_inst ([],"String") [|VBytes (caml_to_hl s);VInt (Int32.of_int (String.length s))|]
+
 let enc_string s : value = assert false
 let enc_array ar : value = assert false
 let enc_obj fl : value = assert false
 let encode_type t : value = assert false
-let encode_expr e : value = assert false
+let encode_expr e = assert false
 let encode_texpr e : value = assert false
 let encode_field f : value = assert false
+
+
+let resolve_macro_api ctx name =
+	match name with
+	| "make_expr" ->
+		Some (function
+		| [v;VAbstract (APos p)] ->
+			let error v = failwith ("Unsupported value " ^ vstr ctx.interp v Hlcode.HDyn) in
+			(*
+			let h_enum = hash "__enum__" and h_et = hash "__et__" and h_ct = hash "__ct__" in
+			let h_tag = hash "tag" and h_args = hash "args" in
+			let h_length = hash "length" in
+			let ctx = get_ctx() in
+			let make_path t =
+				let rec loop = function
+					| [] -> assert false
+					| [name] -> (Ast.EConst (Ast.Ident name),p)
+					| name :: l -> (Ast.EField (loop l,name),p)
+				in
+				let t = t_infos t in
+				loop (List.rev (if t.mt_module.m_path = t.mt_path then fst t.mt_path @ [snd t.mt_path] else fst t.mt_module.m_path @ [snd t.mt_module.m_path;snd t.mt_path]))
+			in*)
+			let rec loop = function
+				| VNull -> (Ast.EConst (Ast.Ident "null"),p)
+				| VBool b -> (Ast.EConst (Ast.Ident (if b then "true" else "false")),p)
+				| VInt i -> (Ast.EConst (Ast.Int (Int32.to_string i)),p)
+				| VFloat f ->
+					let std = (Ast.EConst (Ast.Ident "std"), p) in
+					let math = (Ast.EField (std, "Math"), p) in
+					if (f = infinity) then
+						(Ast.EField (math, "POSITIVE_INFINITY"), p)
+					else if (f = neg_infinity) then
+						(Ast.EField (math, "NEGATIVE_INFINITY"), p)
+					else if (f <> f) then
+						(Ast.EField (math, "NaN"), p)
+					else
+						(Ast.EConst (Ast.Float (Common.float_repres f)), p)
+				| VAbstract (APos p) ->
+					(Ast.EObjectDecl (
+						(("fileName",Globals.null_pos) , (Ast.EConst (Ast.String p.Globals.pfile) , p)) ::
+						(("lineNumber",Globals.null_pos) , (Ast.EConst (Ast.Int (string_of_int (Lexer.get_error_line p))),p)) ::
+						(("className",Globals.null_pos) , (Ast.EConst (Ast.String ("")),p)) ::
+						[]
+					), p)
+				| VObj { oproto = { pclass = { pname = "String" } }; ofields = [|VBytes content;VInt _|] } ->
+					(Ast.EConst (Ast.String (hl_to_caml content)),p)
+				| v ->
+					error v
+				(*
+				| VObject o as v ->
+					match o.oproto with
+					| None ->
+						(match get_field_opt o h_ct with
+						| Some (VAbstract (ATDecl t)) ->
+							make_path t
+						| _ ->
+							let fields = List.fold_left (fun acc (fid,v) -> ((field_name ctx fid,Globals.null_pos), loop v) :: acc) [] (Array.to_list o.ofields) in
+							(Ast.EObjectDecl fields, p))
+					| Some proto ->
+						match get_field_opt proto h_enum, get_field_opt o h_a, get_field_opt o h_s, get_field_opt o h_length with
+						| _, Some (VArray a), _, Some (VInt len) ->
+							(Ast.EArrayDecl (List.map loop (Array.to_list (Array.sub a 0 len))),p)
+						| Some (VObject en), _, _, _ ->
+							(match get_field en h_et, get_field o h_tag with
+							| VAbstract (ATDecl t), VString tag ->
+								let e = (Ast.EField (make_path t,tag),p) in
+								(match get_field_opt o h_args with
+								| Some (VArray args) ->
+									let args = List.map loop (Array.to_list args) in
+									(Ast.ECall (e,args),p)
+								| _ -> e)
+							| _ ->
+								error v)
+						| _ ->
+							error v
+					*)
+			in
+			encode_expr (loop v)
+		| _ ->
+			assert false)
+	| _ ->
+		None
+
+;;
+resolve_macro_api_ref := resolve_macro_api

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 81 - 804
src/macro/interp.ml


+ 1772 - 0
src/macro/macroApi.ml

@@ -0,0 +1,1772 @@
+open Ast
+open Type
+open Common
+
+exception Invalid_expr
+exception Abort
+
+(**
+	Our access to the compiler from the macro api
+**)
+
+type 'value compiler_api = {
+	pos : Globals.pos;
+	get_com : unit -> Common.context;
+	get_type : string -> Type.t option;
+	get_module : string -> Type.t list;
+	after_typing : (module_type list -> unit) -> unit;
+	on_generate : (Type.t list -> unit) -> unit;
+	after_generate : (unit -> unit) -> unit;
+	on_type_not_found : (string -> 'value) -> unit;
+	parse_string : string -> Globals.pos -> bool -> Ast.expr;
+	type_expr : Ast.expr -> Type.texpr;
+	resolve_type  : Ast.complex_type -> Globals.pos -> t;
+	type_macro_expr : Ast.expr -> Type.texpr;
+	store_typed_expr : Type.texpr -> Ast.expr;
+	allow_package : string -> unit;
+	type_patch : string -> string -> bool -> string option -> unit;
+	meta_patch : string -> string -> string option -> bool -> unit;
+	set_js_generator : (Genjs.ctx -> unit) -> unit;
+	get_local_type : unit -> t option;
+	get_expected_type : unit -> t option;
+	get_call_arguments : unit -> Ast.expr list option;
+	get_local_method : unit -> string;
+	get_local_imports : unit -> Ast.import list;
+	get_local_using : unit -> tclass list;
+	get_local_vars : unit -> (string, Type.tvar) PMap.t;
+	get_build_fields : unit -> 'value;
+	get_pattern_locals : Ast.expr -> Type.t -> (string,Type.tvar * Globals.pos) PMap.t;
+	define_type : 'value -> unit;
+	define_module : string -> 'value list -> ((string * Globals.pos) list * Ast.import_mode) list -> Ast.type_path list -> unit;
+	module_dependency : string -> string -> bool -> unit;
+	current_module : unit -> module_def;
+	on_reuse : (unit -> bool) -> unit;
+	mutable current_macro_module : unit -> module_def;
+	delayed_macro : int -> (unit -> (unit -> 'value));
+	use_cache : unit -> bool;
+	format_string : string -> Globals.pos -> Ast.expr;
+	cast_or_unify : Type.t -> texpr -> Globals.pos -> Type.texpr;
+	add_global_metadata : string -> string -> (bool * bool * bool) -> unit;
+	add_module_check_policy : string list -> int list -> bool -> int -> unit;
+}
+
+
+type enum_index =
+	| IExpr
+	| IBinop
+	| IUnop
+	| IConst
+	| ITParam
+	| ICType
+	| IField
+	| IType
+	| IFieldKind
+	| IMethodKind
+	| IVarAccess
+	| IAccess
+	| IClassKind
+	| ITypedExpr
+	| ITConstant
+	| IModuleType
+	| IFieldAccess
+	| IAnonStatus
+	| IImportMode
+
+(**
+	Our access to the interpreter from the macro api
+**)
+
+module type InterpApi = sig
+	type value
+
+	val vnull : value
+	val vint : int -> value
+	val vfloat : float -> value
+	val vint32 : int32 -> value
+	val vbool : bool -> value
+
+	val enc_array : value list -> value
+	val enc_string  : string -> value
+	val enc_obj : (string * value) list -> value
+
+	val vfun0 : (unit -> value) -> value
+	val vfun1 : (value -> value) -> value
+	val vfun2 : (value -> value -> value) -> value
+	val vfun3 : (value -> value -> value -> value) -> value
+	val vfun4 : (value -> value -> value -> value -> value) -> value
+	val vfun5 : (value -> value -> value -> value -> value -> value) -> value
+
+	val encode_pos : Globals.pos -> value
+	val encode_enum : enum_index -> Globals.pos option -> int -> value list -> value
+	val encode_tdecl : Type.module_type -> value
+	val encode_string_map : ('a -> value) -> (string, 'a) PMap.t -> value
+	val encode_lazytype : (unit -> Type.t) ref -> (unit -> value) -> value
+	val encode_unsafe : Obj.t -> value
+
+	val field : value -> string -> value
+
+	val dec_bool : value -> bool
+	val dec_int : value -> int
+	val dec_i32 : value -> int32
+	val dec_string : value -> string
+	val dec_array : value -> value list
+
+	val decode_pos : value -> Globals.pos
+	val decode_enum : value -> int * value list
+	val decode_tdecl : value -> Type.module_type
+	val decode_lazytype : value -> (unit -> Type.t) ref
+	val decode_unsafe : value -> Obj.t
+
+	val maybe_decode_pos : value -> Globals.pos
+	val decode_enum_with_pos : value -> (int * value list) * Globals.pos
+
+	val encode_ref : 'a -> ('a -> value) -> (unit -> string) -> value
+	val decode_ref : value -> 'a
+
+	val compiler_error : string -> Globals.pos -> 'a
+	val value_to_expr : value -> Globals.pos -> Ast.expr
+	val value_signature : value -> string
+
+	val encode_bytes : string -> value
+	val decode_bytes : value -> string (* haxe.io.Bytes *)
+
+	val prepare_callback : value -> int -> (value list -> value)
+
+	val value_string : value -> string
+
+end
+
+let enum_name = function
+	| IExpr -> "ExprDef"
+	| IBinop -> "Binop"
+	| IUnop -> "Unop"
+	| IConst -> "Constant"
+	| ITParam -> "TypeParam"
+	| ICType -> "ComplexType"
+	| IField -> "FieldType"
+	| IType -> "Type"
+	| IFieldKind -> "FieldKind"
+	| IMethodKind -> "MethodKind"
+	| IVarAccess -> "VarAccess"
+	| IAccess -> "Access"
+	| IClassKind -> "ClassKind"
+	| ITypedExpr -> "TypedExprDef"
+	| ITConstant -> "TConstant"
+	| IModuleType -> "ModuleType"
+	| IFieldAccess -> "FieldAccess"
+	| IAnonStatus -> "AnonStatus"
+	| IImportMode -> "ImportMode"
+
+let all_enums =
+	let last = IImportMode in
+	let rec loop i =
+		let e : enum_index = Obj.magic i in
+		if e = last then [e] else e :: loop (i + 1)
+	in
+	loop 0
+
+
+let s_type_path = Globals.s_type_path
+
+(* convert float value to haxe expression, handling inf/-inf/nan *)
+let haxe_float f p =
+	let std = (Ast.EConst (Ast.Ident "std"), p) in
+	let math = (Ast.EField (std, "Math"), p) in
+	if (f = infinity) then
+		(Ast.EField (math, "POSITIVE_INFINITY"), p)
+	else if (f = neg_infinity) then
+		(Ast.EField (math, "NEGATIVE_INFINITY"), p)
+	else if (f <> f) then
+		(Ast.EField (math, "NaN"), p)
+	else
+		(Ast.EConst (Ast.Float (float_repres f)), p)
+
+(* ------------------------------------------------------------------------------------------------------------- *)
+(* Our macro api functor *)
+
+module MacroApiImpl(InterpImpl:InterpApi) = struct
+
+open InterpImpl
+
+(*
+	The whole encoding/decoding of compiler values from/to interpreter values based on interpreter api
+*)
+
+let null f = function
+	| None -> vnull
+	| Some v -> f v
+
+let encode_enum ?(pos=None) k tag vl = encode_enum k pos tag vl
+
+let encode_const c =
+	let tag, pl = match c with
+	| Int s -> 0, [enc_string s]
+	| Float s -> 1, [enc_string s]
+	| String s -> 2, [enc_string s]
+	| Ident s -> 3, [enc_string s]
+	| Regexp (s,opt) -> 4, [enc_string s;enc_string opt]
+	in
+	encode_enum IConst tag pl
+
+let rec encode_binop op =
+	let tag, pl = match op with
+	| OpAdd -> 0, []
+	| OpMult -> 1, []
+	| OpDiv -> 2, []
+	| OpSub -> 3, []
+	| OpAssign -> 4, []
+	| OpEq -> 5, []
+	| OpNotEq -> 6, []
+	| OpGt -> 7, []
+	| OpGte -> 8, []
+	| OpLt -> 9, []
+	| OpLte -> 10, []
+	| OpAnd -> 11, []
+	| OpOr -> 12, []
+	| OpXor -> 13, []
+	| OpBoolAnd -> 14, []
+	| OpBoolOr -> 15, []
+	| OpShl -> 16, []
+	| OpShr -> 17, []
+	| OpUShr -> 18, []
+	| OpMod -> 19, []
+	| OpAssignOp op -> 20, [encode_binop op]
+	| OpInterval -> 21, []
+	| OpArrow -> 22, []
+	in
+	encode_enum IBinop tag pl
+
+let encode_unop op =
+	let tag = match op with
+	| Increment -> 0
+	| Decrement -> 1
+	| Not -> 2
+	| Neg -> 3
+	| NegBits -> 4
+	in
+	encode_enum IUnop tag []
+
+let encode_import (path,mode) =
+	let tag,pl = match mode with
+		| INormal -> 0, []
+		| IAsName s -> 1, [enc_string s]
+		| IAll -> 2,[]
+	in
+	let mode = encode_enum IImportMode tag pl in
+	enc_obj [
+		"path", enc_array (List.map (fun (name,p) -> enc_obj [ "pos", encode_pos p; "name", enc_string name]) path);
+		"mode", mode
+	]
+
+let encode_placed_name (s,p) =
+	enc_string s
+
+let rec encode_path (t,_) =
+	let fields = [
+		"pack", enc_array (List.map enc_string t.tpackage);
+		"name", enc_string t.tname;
+		"params", enc_array (List.map encode_tparam t.tparams);
+	] in
+	enc_obj (match t.tsub with
+		| None ->  fields
+		| Some s -> ("sub", enc_string s) :: fields)
+
+and encode_tparam = function
+	| TPType t -> encode_enum ITParam 0 [encode_ctype t]
+	| TPExpr e -> encode_enum ITParam 1 [encode_expr e]
+
+and encode_access a =
+	let tag = match a with
+		| APublic -> 0
+		| APrivate -> 1
+		| AStatic -> 2
+		| AOverride -> 3
+		| ADynamic -> 4
+		| AInline -> 5
+		| AMacro -> 6
+	in
+	encode_enum IAccess tag []
+
+and encode_meta_entry (m,ml,p) =
+	enc_obj [
+		"name", enc_string (Meta.to_string m);
+		"params", enc_array (List.map encode_expr ml);
+		"pos", encode_pos p;
+	]
+
+and encode_meta_content m =
+	enc_array (List.map encode_meta_entry m)
+
+and encode_field (f:class_field) =
+	let tag, pl = match f.cff_kind with
+		| FVar (t,e) -> 0, [null encode_ctype t; null encode_expr e]
+		| FFun f -> 1, [encode_fun f]
+		| FProp (get,set, t, e) -> 2, [encode_placed_name get; encode_placed_name set; null encode_ctype t; null encode_expr e]
+	in
+	enc_obj [
+		"name",encode_placed_name f.cff_name;
+		"name_pos", encode_pos (pos f.cff_name);
+		"doc", null enc_string f.cff_doc;
+		"pos", encode_pos f.cff_pos;
+		"kind", encode_enum IField tag pl;
+		"meta", encode_meta_content f.cff_meta;
+		"access", enc_array (List.map encode_access f.cff_access);
+	]
+
+and encode_ctype t =
+	let tag, pl = match fst t with
+	| CTPath p ->
+		0, [encode_path (p,Globals.null_pos)]
+	| CTFunction (pl,r) ->
+		1, [enc_array (List.map encode_ctype pl);encode_ctype r]
+	| CTAnonymous fl ->
+		2, [enc_array (List.map encode_field fl)]
+	| CTParent t ->
+		3, [encode_ctype t]
+	| CTExtend (tl,fields) ->
+		4, [enc_array (List.map encode_path tl); enc_array (List.map encode_field fields)]
+	| CTOptional t ->
+		5, [encode_ctype t]
+	in
+	encode_enum ~pos:(Some (pos t)) ICType tag pl
+
+and encode_tparam_decl tp =
+	enc_obj [
+		"name", encode_placed_name tp.tp_name;
+		"name_pos", encode_pos (pos tp.tp_name);
+		"params", enc_array (List.map encode_tparam_decl tp.tp_params);
+		"constraints", enc_array (List.map encode_ctype tp.tp_constraints);
+		"meta", encode_meta_content tp.tp_meta;
+	]
+
+and encode_fun f =
+	enc_obj [
+		"params", enc_array (List.map encode_tparam_decl f.f_params);
+		"args", enc_array (List.map (fun (n,opt,m,t,e) ->
+			enc_obj [
+				"name", encode_placed_name n;
+				"name_pos", encode_pos (pos n);
+				"opt", vbool opt;
+				"meta", encode_meta_content m;
+				"type", null encode_ctype t;
+				"value", null encode_expr e;
+			]
+		) f.f_args);
+		"ret", null encode_ctype f.f_type;
+		"expr", null encode_expr f.f_expr
+	]
+
+and encode_expr e =
+	let rec loop (e,p) =
+		let tag, pl = match e with
+			| EConst c ->
+				0, [encode_const c]
+			| EArray (e1,e2) ->
+				1, [loop e1;loop e2]
+			| EBinop (op,e1,e2) ->
+				2, [encode_binop op;loop e1;loop e2]
+			| EField (e,f) ->
+				3, [loop e;enc_string f]
+			| EParenthesis e ->
+				4, [loop e]
+			| EObjectDecl fl ->
+				5, [enc_array (List.map (fun ((f,p),e) -> enc_obj [
+					"field",enc_string f;
+					"name_pos",encode_pos p;
+					"expr",loop e;
+				]) fl)]
+			| EArrayDecl el ->
+				6, [enc_array (List.map loop el)]
+			| ECall (e,el) ->
+				7, [loop e;enc_array (List.map loop el)]
+			| ENew (p,el) ->
+				8, [encode_path p; enc_array (List.map loop el)]
+			| EUnop (op,flag,e) ->
+				9, [encode_unop op; vbool (match flag with Prefix -> false | Postfix -> true); loop e]
+			| EVars vl ->
+				10, [enc_array (List.map (fun (v,t,eo) ->
+					enc_obj [
+						"name",encode_placed_name v;
+						"name_pos",encode_pos (pos v);
+						"type",null encode_ctype t;
+						"expr",null loop eo;
+					]
+				) vl)]
+			| EFunction (name,f) ->
+				11, [null enc_string name; encode_fun f]
+			| EBlock el ->
+				12, [enc_array (List.map loop el)]
+			| EFor (e,eloop) ->
+				13, [loop e;loop eloop]
+			| EIn (e1,e2) ->
+				14, [loop e1;loop e2]
+			| EIf (econd,e,eelse) ->
+				15, [loop econd;loop e;null loop eelse]
+			| EWhile (econd,e,flag) ->
+				16, [loop econd;loop e;vbool (match flag with NormalWhile -> true | DoWhile -> false)]
+			| ESwitch (e,cases,eopt) ->
+				17, [loop e;enc_array (List.map (fun (ecl,eg,e,p) ->
+					enc_obj [
+						"values",enc_array (List.map loop ecl);
+						"guard",null loop eg;
+						"expr",null loop e;
+						"pos",encode_pos p;
+					]
+				) cases);null (fun (e,_) -> encode_null_expr e) eopt]
+			| ETry (e,catches) ->
+				18, [loop e;enc_array (List.map (fun (v,t,e,p) ->
+					enc_obj [
+						"name",encode_placed_name v;
+						"name_pos",encode_pos (pos v);
+						"type",encode_ctype t;
+						"expr",loop e;
+						"pos",encode_pos p
+					]
+				) catches)]
+			| EReturn eo ->
+				19, [null loop eo]
+			| EBreak ->
+				20, []
+			| EContinue ->
+				21, []
+			| EUntyped e ->
+				22, [loop e]
+			| EThrow e ->
+				23, [loop e]
+			| ECast (e,t) ->
+				24, [loop e; null encode_ctype t]
+			| EDisplay (e,flag) ->
+				25, [loop e; vbool flag]
+			| EDisplayNew t ->
+				26, [encode_path t]
+			| ETernary (econd,e1,e2) ->
+				27, [loop econd;loop e1;loop e2]
+			| ECheckType (e,t) ->
+				28, [loop e; encode_ctype t]
+			| EMeta (m,e) ->
+				29, [encode_meta_entry m;loop e]
+		in
+		enc_obj [
+			"pos", encode_pos p;
+			"expr", encode_enum IExpr tag pl;
+		]
+	in
+	loop e
+
+and encode_null_expr e =
+	match e with
+	| None ->
+		enc_obj ["pos", vnull;"expr",vnull]
+	| Some e ->
+		encode_expr e
+
+(* ---------------------------------------------------------------------- *)
+(* EXPR DECODING *)
+
+let opt f v =
+	if v = vnull then None else Some (f v)
+
+let opt_list f v =
+	if v = vnull then [] else f v
+
+let dec_opt_bool v =
+	if v = vnull then false else dec_bool v
+
+let decode_const c =
+	match decode_enum c with
+	| 0, [s] -> Int (dec_string s)
+	| 1, [s] -> Float (dec_string s)
+	| 2, [s] -> String (dec_string s)
+	| 3, [s] -> Ident (dec_string s)
+	| 4, [s;opt] -> Regexp (dec_string s, dec_string opt)
+	| 5, [s] -> Ident (dec_string s) (** deprecated CType, keep until 3.0 release **)
+	| _ -> raise Invalid_expr
+
+let rec decode_op op =
+	match decode_enum op with
+	| 0, [] -> OpAdd
+	| 1, [] -> OpMult
+	| 2, [] -> OpDiv
+	| 3, [] -> OpSub
+	| 4, [] -> OpAssign
+	| 5, [] -> OpEq
+	| 6, [] -> OpNotEq
+	| 7, [] -> OpGt
+	| 8, [] -> OpGte
+	| 9, [] -> OpLt
+	| 10, [] -> OpLte
+	| 11, [] -> OpAnd
+	| 12, [] -> OpOr
+	| 13, [] -> OpXor
+	| 14, [] -> OpBoolAnd
+	| 15, [] -> OpBoolOr
+	| 16, [] -> OpShl
+	| 17, [] -> OpShr
+	| 18, [] -> OpUShr
+	| 19, [] -> OpMod
+	| 20, [op] -> OpAssignOp (decode_op op)
+	| 21, [] -> OpInterval
+	| 22,[] -> OpArrow
+	| _ -> raise Invalid_expr
+
+let decode_unop op =
+	match decode_enum op with
+	| 0, [] -> Increment
+	| 1, [] -> Decrement
+	| 2, [] -> Not
+	| 3, [] -> Neg
+	| 4, [] -> NegBits
+	| _ -> raise Invalid_expr
+
+let decode_import_mode t =
+	match decode_enum t with
+	| 0, [] -> INormal
+	| 1, [alias] -> IAsName (dec_string alias)
+	| 2, [] -> IAll
+	| _ -> raise Invalid_expr
+
+let decode_import t = (List.map (fun o -> ((dec_string (field o "name")), (decode_pos (field o "pos")))) (dec_array (field t "path")), decode_import_mode (field t "mode"))
+
+let decode_placed_name vp v =
+	dec_string v,maybe_decode_pos vp
+
+let dec_opt_array f v =
+	if v = vnull then [] else List.map f (dec_array v)
+
+let rec decode_path t =
+	{
+		tpackage = List.map dec_string (dec_array (field t "pack"));
+		tname = dec_string (field t "name");
+		tparams = dec_opt_array decode_tparam (field t "params");
+		tsub = opt dec_string (field t "sub");
+	},Globals.null_pos
+
+and decode_tparam v =
+	match decode_enum v with
+	| 0,[t] -> TPType (decode_ctype t)
+	| 1,[e] -> TPExpr (decode_expr e)
+	| _ -> raise Invalid_expr
+
+and decode_tparams v =
+	dec_opt_array decode_tparam_decl v
+
+and decode_tparam_decl v =
+	{
+		tp_name = decode_placed_name (field v "name_pos") (field v "name");
+		tp_constraints = dec_opt_array decode_ctype (field v "constraints");
+		tp_params = decode_tparams (field v "params");
+		tp_meta = decode_meta_content (field v "meta");
+	}
+
+and decode_fun v =
+	{
+		f_params = decode_tparams (field v "params");
+		f_args = List.map (fun o ->
+			decode_placed_name (field o "name_pos") (field o "name"),
+			dec_opt_bool (field o "opt"),
+			decode_meta_content (field o "meta"),
+			opt decode_ctype (field o "type"),
+			opt decode_expr (field o "value")
+		) (dec_array (field v "args"));
+		f_type = opt decode_ctype (field v "ret");
+		f_expr = opt decode_expr (field v "expr");
+	}
+
+and decode_access v =
+	match decode_enum v with
+	| 0, [] -> APublic
+	| 1, [] -> APrivate
+	| 2, [] -> AStatic
+	| 3, [] -> AOverride
+	| 4, [] -> ADynamic
+	| 5, [] -> AInline
+	| 6, [] -> AMacro
+	| _ -> raise Invalid_expr
+
+and decode_meta_entry v =
+	Meta.from_string (dec_string (field v "name")), dec_opt_array decode_expr (field v "params"), decode_pos (field v "pos")
+
+and decode_meta_content m = dec_opt_array decode_meta_entry m
+
+and decode_field v =
+	let fkind = match decode_enum (field v "kind") with
+		| 0, [t;e] ->
+			FVar (opt decode_ctype t, opt decode_expr e)
+		| 1, [f] ->
+			FFun (decode_fun f)
+		| 2, [get;set; t; e] ->
+			FProp (decode_placed_name vnull get, decode_placed_name vnull set, opt decode_ctype t, opt decode_expr e)
+		| _ ->
+			raise Invalid_expr
+	in
+	{
+		cff_name = decode_placed_name (field v "name_pos") (field v "name");
+		cff_doc = opt dec_string (field v "doc");
+		cff_pos = decode_pos (field v "pos");
+		cff_kind = fkind;
+		cff_access = List.map decode_access (opt_list dec_array (field v "access"));
+		cff_meta = opt_list decode_meta_content (field v "meta");
+	}
+
+and decode_ctype t =
+	let (i,args),p = decode_enum_with_pos t in
+	(match i,args with
+	| 0, [p] ->
+		CTPath (fst (decode_path p))
+	| 1, [a;r] ->
+		CTFunction (List.map decode_ctype (dec_array a), decode_ctype r)
+	| 2, [fl] ->
+		CTAnonymous (List.map decode_field (dec_array fl))
+	| 3, [t] ->
+		CTParent (decode_ctype t)
+	| 4, [tl;fl] ->
+		CTExtend (List.map decode_path (dec_array tl), List.map decode_field (dec_array fl))
+	| 5, [t] ->
+		CTOptional (decode_ctype t)
+	| _ ->
+		raise Invalid_expr),p
+
+and decode_expr v =
+	let rec loop v =
+		let p = decode_pos (field v "pos") in
+		(decode (field v "expr") p, p)
+	and decode e p =
+		match decode_enum e with
+		| 0, [c] ->
+			EConst (decode_const c)
+		| 1, [e1;e2] ->
+			EArray (loop e1, loop e2)
+		| 2, [op;e1;e2] ->
+			EBinop (decode_op op, loop e1, loop e2)
+		| 3, [e;f] ->
+			EField (loop e, dec_string f)
+		| 4, [e] ->
+			EParenthesis (loop e)
+		| 5, [a] ->
+			EObjectDecl (List.map (fun o ->
+				(decode_placed_name (field o "name_pos") (field o "field")),loop (field o "expr")
+			) (dec_array a))
+		| 6, [a] ->
+			EArrayDecl (List.map loop (dec_array a))
+		| 7, [e;el] ->
+			ECall (loop e,List.map loop (dec_array el))
+		| 8, [t;el] ->
+			ENew (decode_path t,List.map loop (dec_array el))
+		| 9, [op;f;e] ->
+			EUnop (decode_unop op,(if dec_bool f then Postfix else Prefix),loop e)
+		| 10, [vl] ->
+			EVars (List.map (fun v ->
+				((decode_placed_name (field v "name_pos") (field v "name")),opt decode_ctype (field v "type"),opt loop (field v "expr"))
+			) (dec_array vl))
+		| 11, [fname;f] ->
+			EFunction (opt dec_string fname,decode_fun f)
+		| 12, [el] ->
+			EBlock (List.map loop (dec_array el))
+		| 13, [e1;e2] ->
+			EFor (loop e1, loop e2)
+		| 14, [e1;e2] ->
+			EIn (loop e1, loop e2)
+		| 15, [e1;e2;e3] ->
+			EIf (loop e1, loop e2, opt loop e3)
+		| 16, [e1;e2;flag] ->
+			EWhile (loop e1,loop e2,if dec_bool flag then NormalWhile else DoWhile)
+		| 17, [e;cases;eo] ->
+			let cases = List.map (fun c ->
+				(List.map loop (dec_array (field c "values")),opt loop (field c "guard"),opt loop (field c "expr"),maybe_decode_pos (field c "pos"))
+			) (dec_array cases) in
+			ESwitch (loop e,cases,opt (fun v -> (if field v "expr" = vnull then None else Some (decode_expr v)),Globals.null_pos) eo)
+		| 18, [e;catches] ->
+			let catches = List.map (fun c ->
+				((decode_placed_name (field c "name_pos") (field c "name")),(decode_ctype (field c "type")),loop (field c "expr"),maybe_decode_pos (field c "pos"))
+			) (dec_array catches) in
+			ETry (loop e, catches)
+		| 19, [e] ->
+			EReturn (opt loop e)
+		| 20, [] ->
+			EBreak
+		| 21, [] ->
+			EContinue
+		| 22, [e] ->
+			EUntyped (loop e)
+		| 23, [e] ->
+			EThrow (loop e)
+		| 24, [e;t] ->
+			ECast (loop e,opt decode_ctype t)
+		| 25, [e;f] ->
+			EDisplay (loop e,dec_bool f)
+		| 26, [t] ->
+			EDisplayNew (decode_path t)
+		| 27, [e1;e2;e3] ->
+			ETernary (loop e1,loop e2,loop e3)
+		| 28, [e;t] ->
+			ECheckType (loop e, (decode_ctype t))
+		| 29, [m;e] ->
+			EMeta (decode_meta_entry m,loop e)
+		| 30, [e;f] ->
+			EField (loop e, dec_string f) (*** deprecated EType, keep until haxe 3 **)
+		| _ ->
+			raise Invalid_expr
+	in
+	try
+		loop v
+	with Stack_overflow ->
+		raise Invalid_expr
+
+(* ---------------------------------------------------------------------- *)
+(* TYPE ENCODING *)
+
+let encode_pmap_array convert m =
+	let l = ref [] in
+	PMap.iter (fun _ v -> l := !l @ [(convert v)]) m;
+	enc_array !l
+
+let encode_array convert l =
+	enc_array (List.map convert l)
+
+let vopt f v = match v with
+	| None -> vnull
+	| Some v -> f v
+
+let encode_meta m set =
+	let meta = ref m in
+	enc_obj [
+		"get", vfun0 (fun() ->
+			encode_meta_content (!meta)
+		);
+		"add", vfun3 (fun k vl p ->
+			(try
+				let el = List.map decode_expr (dec_array vl) in
+				meta := (Meta.from_string (dec_string k), el, decode_pos p) :: !meta;
+				set (!meta)
+			with Invalid_expr ->
+				failwith "Invalid expression");
+			vnull
+		);
+		"extract", vfun1 (fun k ->
+			let k = Meta.from_string (dec_string k) in
+			encode_array encode_meta_entry (List.filter (fun (m,_,_) -> m = k) (!meta))
+		);
+		"remove", vfun1 (fun k ->
+			let k = Meta.from_string (dec_string k) in
+			meta := List.filter (fun (m,_,_) -> m <> k) (!meta);
+			set (!meta);
+			vnull
+		);
+		"has", vfun1 (fun k ->
+			let k = Meta.from_string (dec_string k) in
+			vbool (List.exists (fun (m,_,_) -> m = k) (!meta));
+		);
+	]
+
+let rec encode_mtype t fields =
+	let i = t_infos t in
+	enc_obj ([
+		"__t", 	encode_tdecl t;
+		"pack", enc_array (List.map enc_string (fst i.mt_path));
+		"name", enc_string (snd i.mt_path);
+		"pos", encode_pos i.mt_pos;
+		"module", enc_string (s_type_path i.mt_module.m_path);
+		"isPrivate", vbool i.mt_private;
+		"meta", encode_meta i.mt_meta (fun m -> i.mt_meta <- m);
+		"doc", null enc_string i.mt_doc;
+		"params", encode_type_params i.mt_params;
+	] @ fields)
+
+and encode_type_params tl =
+	enc_array (List.map (fun (n,t) -> enc_obj ["name",enc_string n;"t",encode_type t]) tl)
+
+and encode_tenum e =
+	encode_mtype (TEnumDecl e) [
+		"isExtern", vbool e.e_extern;
+		"exclude", vfun0 (fun() -> e.e_extern <- true; vnull);
+		"constructs", encode_string_map encode_efield e.e_constrs;
+		"names", enc_array (List.map enc_string e.e_names);
+	]
+
+and encode_tabstract a =
+	encode_mtype (TAbstractDecl a) [
+		"type", encode_type a.a_this;
+		"impl", (match a.a_impl with None -> vnull | Some c -> encode_clref c);
+		"binops", enc_array (List.map (fun (op,cf) -> enc_obj [ "op",encode_binop op; "field",encode_cfield cf]) a.a_ops);
+		"unops", enc_array (List.map (fun (op,postfix,cf) -> enc_obj [ "op",encode_unop op; "isPostfix",vbool (match postfix with Postfix -> true | Prefix -> false); "field",encode_cfield cf]) a.a_unops);
+		"from", enc_array ((List.map (fun t -> enc_obj [ "t",encode_type t; "field",vnull]) a.a_from) @ (List.map (fun (t,cf) -> enc_obj [ "t",encode_type t; "field",encode_cfield cf]) a.a_from_field));
+		"to", enc_array ((List.map (fun t -> enc_obj [ "t",encode_type t; "field",vnull]) a.a_to) @ (List.map (fun (t,cf) -> enc_obj [ "t",encode_type t; "field",encode_cfield cf]) a.a_to_field));
+		"array", enc_array (List.map encode_cfield a.a_array);
+		"resolve", (match a.a_resolve with None -> vnull | Some cf -> encode_cfref cf)
+	]
+
+and encode_efield f =
+	enc_obj [
+		"name", enc_string f.ef_name;
+		"type", encode_type f.ef_type;
+		"pos", encode_pos f.ef_pos;
+		"namePos", encode_pos f.ef_name_pos;
+		"index", vint f.ef_index;
+		"meta", encode_meta f.ef_meta (fun m -> f.ef_meta <- m);
+		"doc", null enc_string f.ef_doc;
+		"params", encode_type_params f.ef_params;
+	]
+
+and encode_cfield f =
+	enc_obj [
+		"name", enc_string f.cf_name;
+		"type", (match f.cf_kind with Method _ -> encode_lazy_type f.cf_type | _ -> encode_type f.cf_type);
+		"isPublic", vbool f.cf_public;
+		"params", encode_type_params f.cf_params;
+		"meta", encode_meta f.cf_meta (fun m -> f.cf_meta <- m);
+		"expr", vfun0 (fun() -> ignore(follow f.cf_type); (match f.cf_expr with None -> vnull | Some e -> encode_texpr e));
+		"kind", encode_field_kind f.cf_kind;
+		"pos", encode_pos f.cf_pos;
+		"namePos",encode_pos f.cf_name_pos;
+		"doc", null enc_string f.cf_doc;
+		"overloads", encode_ref f.cf_overloads (encode_array encode_cfield) (fun() -> "overloads");
+	]
+
+and encode_field_kind k =
+	let tag, pl = (match k with
+		| Type.Var v -> 0, [encode_var_access v.v_read; encode_var_access v.v_write]
+		| Method m -> 1, [encode_method_kind m]
+	) in
+	encode_enum IFieldKind tag pl
+
+and encode_var_access a =
+	let tag, pl = (match a with
+		| AccNormal -> 0, []
+		| AccNo -> 1, []
+		| AccNever -> 2, []
+		| AccResolve -> 3, []
+		| AccCall -> 4, []
+		| AccInline	-> 5, []
+		| AccRequire (s,msg) -> 6, [enc_string s; null enc_string msg]
+	) in
+	encode_enum IVarAccess tag pl
+
+and encode_method_kind m =
+	let tag, pl = (match m with
+		| MethNormal -> 0, []
+		| MethInline -> 1, []
+		| MethDynamic -> 2, []
+		| MethMacro -> 3, []
+	) in
+	encode_enum IMethodKind tag pl
+
+and encode_class_kind k =
+	let tag, pl = (match k with
+		| KNormal -> 0, []
+		| KTypeParameter pl -> 1, [encode_tparams pl]
+		(* KExtension was here *)
+		| KExpr e -> 3, [encode_expr e]
+		| KGeneric -> 4, []
+		| KGenericInstance (cl, params) -> 5, [encode_clref cl; encode_tparams params]
+		| KMacroType -> 6, []
+		| KAbstractImpl a -> 7, [encode_abref a]
+		| KGenericBuild cfl -> 8, []
+	) in
+	encode_enum IClassKind tag pl
+
+and encode_tclass c =
+	ignore(c.cl_build());
+	encode_mtype (TClassDecl c) [
+		"kind", encode_class_kind c.cl_kind;
+		"isExtern", vbool c.cl_extern;
+		"exclude", vfun0 (fun() -> c.cl_extern <- true; c.cl_init <- None; vnull);
+		"isInterface", vbool c.cl_interface;
+		"superClass", (match c.cl_super with
+			| None -> vnull
+			| Some (c,pl) -> enc_obj ["t",encode_clref c;"params",encode_tparams pl]
+		);
+		"interfaces", enc_array (List.map (fun (c,pl) -> enc_obj ["t",encode_clref c;"params",encode_tparams pl]) c.cl_implements);
+		"fields", encode_ref c.cl_ordered_fields (encode_array encode_cfield) (fun() -> "class fields");
+		"statics", encode_ref c.cl_ordered_statics (encode_array encode_cfield) (fun() -> "class fields");
+		"constructor", (match c.cl_constructor with None -> vnull | Some cf -> encode_cfref cf);
+		"init", (match c.cl_init with None -> vnull | Some e -> encode_texpr e);
+		"overrides", (enc_array (List.map encode_cfref c.cl_overrides))
+	]
+
+and encode_ttype t =
+	encode_mtype (TTypeDecl t) [
+		"isExtern", vbool false;
+		"exclude", vfun0 (fun() -> vnull);
+		"type", encode_type t.t_type;
+	]
+
+and encode_tanon a =
+	enc_obj [
+		"fields", encode_pmap_array encode_cfield a.a_fields;
+		"status", encode_anon_status !(a.a_status);
+	]
+
+and encode_anon_status s =
+	let tag, pl = (match s with
+		| Closed -> 0, []
+		| Opened -> 1, []
+		| Type.Const -> 2, []
+		| Extend tl -> 3, [encode_ref tl (fun tl -> enc_array (List.map encode_type tl)) (fun() -> "<extended types>")]
+		| Statics cl -> 4, [encode_clref cl]
+		| EnumStatics en -> 5, [encode_enref en]
+		| AbstractStatics ab -> 6, [encode_abref ab]
+	)
+	in
+	encode_enum IAnonStatus tag pl
+
+and encode_tparams pl =
+	enc_array (List.map encode_type pl)
+
+and encode_clref c =
+	encode_ref c encode_tclass (fun() -> s_type_path c.cl_path)
+
+and encode_enref en =
+	encode_ref en encode_tenum (fun() -> s_type_path en.e_path)
+
+and encode_cfref cf =
+	encode_ref cf encode_cfield (fun() -> cf.cf_name)
+
+and encode_abref ab =
+	encode_ref ab encode_tabstract (fun() -> s_type_path ab.a_path)
+
+and encode_type t =
+	let rec loop = function
+		| TMono r ->
+			(match !r with
+			| None -> 0, [encode_ref r (fun r -> match !r with None -> vnull | Some t -> encode_type t) (fun() -> "<mono>")]
+			| Some t -> loop t)
+		| TEnum (e, pl) ->
+			1 , [encode_ref e encode_tenum (fun() -> s_type_path e.e_path); encode_tparams pl]
+		| TInst (c, pl) ->
+			2 , [encode_clref c; encode_tparams pl]
+		| TType (t,pl) ->
+			3 , [encode_ref t encode_ttype (fun() -> s_type_path t.t_path); encode_tparams pl]
+		| TFun (pl,ret) ->
+			let pl = List.map (fun (n,o,t) ->
+				enc_obj [
+					"name",enc_string n;
+					"opt",vbool o;
+					"t",encode_type t
+				]
+			) pl in
+			4 , [enc_array pl; encode_type ret]
+		| TAnon a ->
+			5, [encode_ref a encode_tanon (fun() -> "<anonymous>")]
+		| TDynamic tsub as t ->
+			if t == t_dynamic then
+				6, [vnull]
+			else
+				6, [encode_type tsub]
+		| TLazy f ->
+			loop (!f())
+		| TAbstract (a, pl) ->
+			8, [encode_abref a; encode_tparams pl]
+	in
+	let tag, pl = loop t in
+	encode_enum IType tag pl
+
+and encode_lazy_type t =
+	let rec loop = function
+		| TMono r ->
+			(match !r with
+			| Some t -> loop t
+			| _ -> encode_type t)
+		| TLazy f ->
+			encode_enum IType 7 [encode_lazytype f (fun() -> encode_type (!f()))]
+		| _ ->
+			encode_type t
+	in
+	loop t
+
+and decode_type t =
+	match decode_enum t with
+	| 0, [r] -> TMono (decode_ref r)
+	| 1, [e; pl] -> TEnum (decode_ref e, List.map decode_type (dec_array pl))
+	| 2, [c; pl] -> TInst (decode_ref c, List.map decode_type (dec_array pl))
+	| 3, [t; pl] -> TType (decode_ref t, List.map decode_type (dec_array pl))
+	| 4, [pl; r] -> TFun (List.map (fun p -> dec_string (field p "name"), dec_bool (field p "opt"), decode_type (field p "t")) (dec_array pl), decode_type r)
+	| 5, [a] -> TAnon (decode_ref a)
+	| 6, [t] -> if t = vnull then t_dynamic else TDynamic (decode_type t)
+	| 7, [f] -> TLazy (decode_lazytype f)
+	| 8, [a; pl] -> TAbstract (decode_ref a, List.map decode_type (dec_array pl))
+	| _ -> raise Invalid_expr
+
+(* ---------------------------------------------------------------------- *)
+(* TEXPR Encoding *)
+
+and encode_tconst c =
+	let tag, pl = match c with
+		| TInt i -> 0,[vint32 i]
+		| TFloat f -> 1,[enc_string f]
+		| TString s -> 2,[enc_string s]
+		| TBool b -> 3,[vbool b]
+		| TNull -> 4,[]
+		| TThis -> 5,[]
+		| TSuper -> 6,[]
+	in
+	encode_enum ITConstant tag pl
+
+and encode_tvar v =
+	let f_extra (pl,e) =
+		enc_obj [
+			"params",encode_type_params pl;
+			"expr",vopt encode_texpr e
+		]
+	in
+	enc_obj [
+		"id", vint v.v_id;
+		"name", enc_string v.v_name;
+		"t", encode_type v.v_type;
+		"capture", vbool v.v_capture;
+		"extra", vopt f_extra v.v_extra;
+		"meta", encode_meta v.v_meta (fun m -> v.v_meta <- m);
+		"$", encode_unsafe (Obj.repr v);
+	]
+
+and encode_module_type mt =
+	let tag,pl = match mt with
+		| TClassDecl c -> 0,[encode_clref c]
+		| TEnumDecl e -> 1,[encode_enref e]
+		| TTypeDecl t -> 2,[encode_ref t encode_ttype (fun () -> s_type_path t.t_path)]
+		| TAbstractDecl a -> 3,[encode_abref a]
+	in
+	encode_enum IModuleType tag pl
+
+and encode_tfunc func =
+	enc_obj [
+		"args",enc_array (List.map (fun (v,c) ->
+			enc_obj [
+				"v",encode_tvar v;
+				"value",match c with None -> vnull | Some c -> encode_tconst c
+			]
+		) func.tf_args);
+		"t",encode_type func.tf_type;
+		"expr",encode_texpr func.tf_expr
+	]
+
+and encode_field_access fa =
+	let encode_instance c tl =
+		enc_obj [
+			"c",encode_clref c;
+			"params",encode_tparams tl
+		]
+	in
+	let tag,pl = match fa with
+		| FInstance(c,tl,cf) -> 0,[encode_clref c;encode_tparams tl;encode_cfref cf]
+		| FStatic(c,cf) -> 1,[encode_clref c;encode_cfref cf]
+		| FAnon(cf) -> 2,[encode_cfref cf]
+		| FDynamic(s) -> 3,[enc_string s]
+		| FClosure(co,cf) -> 4,[(match co with Some (c,tl) -> encode_instance c tl | None -> vnull);encode_cfref cf]
+		| FEnum(en,ef) -> 5,[encode_enref en;encode_efield ef]
+	in
+	encode_enum IFieldAccess tag pl
+
+and encode_texpr e =
+	let rec loop e =
+		let tag, pl = match e.eexpr with
+			| TConst c -> 0,[encode_tconst c]
+			| TLocal v -> 1,[encode_tvar v]
+			| TArray(e1,e2) -> 2,[loop e1; loop e2]
+			| TBinop(op,e1,e2) -> 3,[encode_binop op;loop e1;loop e2]
+			| TField(e1,fa) -> 4,[loop e1;encode_field_access fa]
+			| TTypeExpr mt -> 5,[encode_module_type mt]
+			| TParenthesis e1 -> 6,[loop e1]
+			| TObjectDecl fl -> 7, [enc_array (List.map (fun (f,e) ->
+				enc_obj [
+					"name",enc_string f;
+					"expr",loop e;
+				]) fl)]
+			| TArrayDecl el -> 8,[encode_texpr_list el]
+			| TCall(e1,el) -> 9,[loop e1;encode_texpr_list el]
+			| TNew(c,pl,el) -> 10,[encode_clref c;encode_tparams pl;encode_texpr_list el]
+			| TUnop(op,flag,e1) -> 11,[encode_unop op;vbool (flag = Postfix);loop e1]
+			| TFunction func -> 12,[encode_tfunc func]
+			| TVar (v,eo) -> 13,[encode_tvar v;vopt encode_texpr eo]
+			| TBlock el -> 14,[encode_texpr_list el]
+			| TFor(v,e1,e2) -> 15,[encode_tvar v;loop e1;loop e2]
+			| TIf(eif,ethen,eelse) -> 16,[loop eif;loop ethen;vopt encode_texpr eelse]
+			| TWhile(econd,e1,flag) -> 17,[loop econd;loop e1;vbool (flag = NormalWhile)]
+			| TSwitch(e1,cases,edef) -> 18,[
+				loop e1;
+				enc_array (List.map (fun (el,e) -> enc_obj ["values",encode_texpr_list el;"expr",loop e]) cases);
+				vopt encode_texpr edef
+				]
+			| TTry(e1,catches) -> 19,[
+				loop e1;
+				enc_array (List.map (fun (v,e) ->
+					enc_obj [
+						"v",encode_tvar v;
+						"expr",loop e
+					]) catches
+				)]
+			| TReturn e1 -> 20,[vopt encode_texpr e1]
+			| TBreak -> 21,[]
+			| TContinue -> 22,[]
+			| TThrow e1 -> 23,[loop e1]
+			| TCast(e1,mt) -> 24,[loop e1;match mt with None -> vnull | Some mt -> encode_module_type mt]
+			| TMeta(m,e1) -> 25,[encode_meta_entry m;loop e1]
+			| TEnumParameter(e1,ef,i) -> 26,[loop e1;encode_efield ef;vint i]
+		in
+		enc_obj [
+			"pos", encode_pos e.epos;
+			"expr", encode_enum ITypedExpr tag pl;
+			"t", encode_type e.etype
+		]
+	in
+	loop e
+
+and encode_texpr_list el =
+	enc_array (List.map encode_texpr el)
+
+(* ---------------------------------------------------------------------- *)
+(* TEXPR Decoding *)
+
+let decode_tconst c =
+	match decode_enum c with
+	| 0, [s] -> TInt (dec_i32 s)
+	| 1, [s] -> TFloat (dec_string s)
+	| 2, [s] -> TString (dec_string s)
+	| 3, [s] -> TBool (dec_bool s)
+	| 4, [] -> TNull
+	| 5, [] -> TThis
+	| 6, [] -> TSuper
+	| _ -> raise Invalid_expr
+
+let decode_type_params v =
+	List.map (fun v -> dec_string (field v "name"),decode_type (field v "t")) (dec_array v)
+
+let decode_tvar v =
+	(Obj.obj (decode_unsafe (field v "$")) : tvar)
+
+let decode_var_access v =
+	match decode_enum v with
+	| 0, [] -> AccNormal
+	| 1, [] -> AccNo
+	| 2, [] -> AccNever
+	| 3, [] -> AccResolve
+	| 4, [] -> AccCall
+	| 5, [] -> AccInline
+	| 6, [s1;s2] -> AccRequire(dec_string s1, opt dec_string s2)
+	| _ -> raise Invalid_expr
+
+let decode_method_kind v =
+	match decode_enum v with
+	| 0, [] -> MethNormal
+	| 1, [] -> MethInline
+	| 2, [] -> MethDynamic
+	| 3, [] -> MethMacro
+	| _ -> raise Invalid_expr
+
+let decode_field_kind v =
+	match decode_enum v with
+	| 0, [vr;vw] -> Type.Var({v_read = decode_var_access vr; v_write = decode_var_access vw})
+	| 1, [m] -> Method (decode_method_kind m)
+	| _ -> raise Invalid_expr
+
+let decode_cfield v =
+	{
+		cf_name = dec_string (field v "name");
+		cf_type = decode_type (field v "type");
+		cf_public = dec_bool (field v "isPublic");
+		cf_pos = decode_pos (field v "pos");
+		cf_name_pos = decode_pos (field v "namePos");
+		cf_doc = opt dec_string (field v "doc");
+		cf_meta = []; (* TODO *)
+		cf_kind = decode_field_kind (field v "kind");
+		cf_params = decode_type_params (field v "params");
+		cf_expr = None;
+		cf_expr_unoptimized = None;
+		cf_overloads = decode_ref (field v "overloads");
+	}
+
+let decode_efield v =
+	{
+		ef_name = dec_string (field v "name");
+		ef_type = decode_type (field v "type");
+		ef_pos = decode_pos (field v "pos");
+		ef_name_pos = decode_pos (field v "namePos");
+		ef_index = dec_int (field v "index");
+		ef_meta = []; (* TODO *)
+		ef_doc = opt dec_string (field v "doc");
+		ef_params = decode_type_params (field v "params")
+	}
+
+let decode_field_access v =
+	match decode_enum v with
+	| 0, [c;tl;cf] ->
+		let c = decode_ref c in
+		FInstance(c,List.map decode_type (dec_array tl),decode_ref cf)
+	| 1, [c;cf] -> FStatic(decode_ref c,decode_ref cf)
+	| 2, [cf] -> FAnon(decode_ref cf)
+	| 3, [s] -> FDynamic(dec_string s)
+	| 4, [co;cf] ->
+		let co = if co = vnull then None else Some (decode_ref (field co "c"),List.map decode_type (dec_array (field co "params"))) in
+		FClosure(co,decode_ref cf)
+	| 5, [e;ef] -> FEnum(decode_ref e,decode_efield ef)
+	| _ -> raise Invalid_expr
+
+let decode_module_type v =
+	match decode_enum v with
+	| 0, [c] -> TClassDecl (decode_ref c)
+	| 1, [en] -> TEnumDecl (decode_ref en)
+	| 2, [t] -> TTypeDecl (decode_ref t)
+	| 3, [a] -> TAbstractDecl (decode_ref a)
+	| _ -> raise Invalid_expr
+
+let rec decode_tfunc v =
+	{
+		tf_args = List.map (fun v -> decode_tvar (field v "v"),opt decode_tconst (field v "value")) (dec_array (field v "args"));
+		tf_type = decode_type (field v "t");
+		tf_expr = decode_texpr (field v "expr")
+	}
+
+and decode_texpr v =
+	let rec loop v =
+		mk (decode (field v "expr")) (decode_type (field v "t")) (decode_pos (field v "pos"))
+	and decode e =
+		match decode_enum e with
+		| 0, [c] ->	TConst(decode_tconst c)
+		| 1, [v] -> TLocal(decode_tvar v)
+		| 2, [v1;v2] -> TArray(loop v1,loop v2)
+		| 3, [op;v1;v2] -> TBinop(decode_op op,loop v1,loop v2)
+		| 4, [v1;fa] -> TField(loop v1,decode_field_access fa)
+		| 5, [mt] -> TTypeExpr(decode_module_type mt)
+		| 6, [v1] -> TParenthesis(loop v1)
+		| 7, [v] -> TObjectDecl(List.map (fun v -> dec_string (field v "name"),loop (field v "expr")) (dec_array v))
+		| 8, [vl] -> TArrayDecl(List.map loop (dec_array vl))
+		| 9, [v1;vl] -> TCall(loop v1,List.map loop (dec_array vl))
+		| 10, [c;tl;vl] -> TNew(decode_ref c,List.map decode_type (dec_array tl),List.map loop (dec_array vl))
+		| 11, [op;pf;v1] -> TUnop(decode_unop op,(if dec_bool pf then Postfix else Prefix),loop v1)
+		| 12, [f] -> TFunction(decode_tfunc f)
+		| 13, [v;eo] -> TVar(decode_tvar v,opt loop eo)
+		| 14, [vl] -> TBlock(List.map loop (dec_array vl))
+		| 15, [v;v1;v2] -> TFor(decode_tvar v,loop v1,loop v2)
+		| 16, [vif;vthen;velse] -> TIf(loop vif,loop vthen,opt loop velse)
+		| 17, [vcond;v1;b] -> TWhile(loop vcond,loop v1,if dec_bool b then NormalWhile else DoWhile)
+		| 18, [v1;cl;vdef] -> TSwitch(loop v1,List.map (fun v -> List.map loop (dec_array (field v "values")),loop (field v "expr")) (dec_array cl),opt loop vdef)
+		| 19, [v1;cl] -> TTry(loop v1,List.map (fun v -> decode_tvar (field v "v"),loop (field v "expr")) (dec_array cl))
+		| 20, [vo] -> TReturn(opt loop vo)
+		| 21, [] -> TBreak
+		| 22, [] -> TContinue
+		| 23, [v1] -> TThrow(loop v1)
+		| 24, [v1;mto] -> TCast(loop v1,opt decode_module_type mto)
+		| 25, [m;v1] -> TMeta(decode_meta_entry m,loop v1)
+		| 26, [v1;ef;i] -> TEnumParameter(loop v1,decode_efield ef,dec_int i)
+		| i,el -> Printf.printf "%i %i\n" i (List.length el); raise Invalid_expr
+	in
+	try
+		loop v
+	with Stack_overflow ->
+		raise Invalid_expr
+
+(* ---------------------------------------------------------------------- *)
+(* TYPE DEFINITION *)
+
+let decode_type_def v =
+	let pack = List.map dec_string (dec_array (field v "pack")) in
+	let name = decode_placed_name (field v "name_pos") (field v "name") in
+	let meta = decode_meta_content (field v "meta") in
+	let pos = decode_pos (field v "pos") in
+	let isExtern = dec_opt_bool (field v "isExtern") in
+	let fields = List.map decode_field (dec_array (field v "fields")) in
+	let mk fl dl =
+		{
+			d_name = name;
+			d_doc = None;
+			d_params = decode_tparams (field v "params");
+			d_meta = meta;
+			d_flags = fl;
+			d_data = dl;
+		}
+	in
+	let tdef = (match decode_enum (field v "kind") with
+	| 0, [] ->
+		let conv f =
+			let loop ((n,_),opt,_,t,_) =
+				match t with
+				| None -> raise Invalid_expr
+				| Some t -> n, opt, t
+			in
+			let args, params, t = (match f.cff_kind with
+				| FVar (t,None) -> [], [], t
+				| FFun f -> List.map loop f.f_args, f.f_params, f.f_type
+				| _ -> raise Invalid_expr
+			) in
+			{
+				ec_name = f.cff_name;
+				ec_doc = f.cff_doc;
+				ec_meta = f.cff_meta;
+				ec_pos = f.cff_pos;
+				ec_args = args;
+				ec_params = params;
+				ec_type = t;
+			}
+		in
+		EEnum (mk (if isExtern then [EExtern] else []) (List.map conv fields))
+	| 1, [] ->
+		ETypedef (mk (if isExtern then [EExtern] else []) (CTAnonymous fields,Globals.null_pos))
+	| 2, [ext;impl;interf] ->
+		let flags = if isExtern then [HExtern] else [] in
+		let is_interface = dec_opt_bool interf in
+		let interfaces = (match opt (fun v -> List.map decode_path (dec_array v)) impl with Some l -> l | _ -> [] ) in
+		let flags = (match opt decode_path ext with None -> flags | Some t -> HExtends t :: flags) in
+		let flags = if is_interface then begin
+				let flags = HInterface :: flags in
+				List.map (fun t -> HExtends t) interfaces @ flags
+			end else begin
+				List.map (fun t -> HImplements t) interfaces @ flags
+			end
+		in
+		EClass (mk flags fields)
+	| 3, [t] ->
+		ETypedef (mk (if isExtern then [EExtern] else []) (decode_ctype t))
+	| 4, [tthis;tfrom;tto] ->
+		let flags = match opt dec_array tfrom with None -> [] | Some ta -> List.map (fun t -> AFromType (decode_ctype t)) ta in
+		let flags = match opt dec_array tto with None -> flags | Some ta -> (List.map (fun t -> AToType (decode_ctype t)) ta) @ flags in
+		let flags = match opt decode_ctype tthis with None -> flags | Some t -> (AIsType t) :: flags in
+		EAbstract(mk flags fields)
+	| _ ->
+		raise Invalid_expr
+	) in
+	(* if our package ends with an uppercase letter, then it's the module name *)
+	let pack,name = (match List.rev pack with
+		| last :: l when not (is_lower_ident last) -> List.rev l, last
+		| _ -> pack, fst name
+	) in
+	(pack, name), tdef, pos
+
+(* ---------------------------------------------------------------------- *)
+(* VALUE-TO-CONSTANT *)
+
+let rec make_const e =
+	match e.eexpr with
+	| TConst c ->
+		(match c with
+		| TInt i -> vint32 i
+		| TFloat s -> vfloat (float_of_string s)
+		| TString s -> enc_string s
+		| TBool b -> vbool b
+		| TNull -> vnull
+		| TThis | TSuper -> raise Exit)
+	| TParenthesis e | TMeta(_,e) | TCast(e,None) ->
+		make_const e
+	| TObjectDecl el ->
+		enc_obj (List.map (fun (f,e) -> f, make_const e) el)
+	| TArrayDecl al ->
+		enc_array (List.map make_const al)
+	| _ ->
+		raise Exit
+
+
+(* ------------------------------------------------------------------------- *)
+(* MACRO API *)
+
+(**
+
+	Our macro API implementation. It gets called by the interpreter and
+	accesses the compiler with the compiler_api
+
+**)
+
+let macro_api ccom get_api =
+	[
+		"curpos", vfun0 (fun() ->
+			encode_pos (get_api()).pos
+		);
+		"error", vfun2 (fun msg p ->
+			let msg = dec_string msg in
+			let p = decode_pos p in
+			(ccom()).error msg p;
+			raise Abort
+		);
+		"fatal_error", vfun2 (fun msg p ->
+			let msg = dec_string msg in
+			let p = decode_pos p in
+			raise (Error.Fatal_error (msg,p))
+		);
+		"warning", vfun2 (fun msg p ->
+			let msg = dec_string msg in
+			let p = decode_pos p in
+			(ccom()).warning msg p;
+			vnull
+		);
+		"class_path", vfun0 (fun() ->
+			enc_array (List.map enc_string (ccom()).class_path);
+		);
+		"resolve", vfun1 (fun file ->
+			let file = dec_string file in
+			enc_string (try Common.find_file (ccom()) file with Not_found -> failwith ("File not found '" ^ file ^ "'"))
+		);
+		"define", vfun1 (fun s ->
+			Common.raw_define (ccom()) (dec_string s);
+			vnull
+		);
+		"defined", vfun1 (fun s ->
+			vbool (Common.raw_defined (ccom()) (dec_string s))
+		);
+		"defined_value", vfun1 (fun s ->
+			try enc_string (Common.raw_defined_value (ccom()) (dec_string s)) with Not_found -> vnull
+		);
+		"get_defines", vfun0 (fun() ->
+			encode_string_map enc_string (ccom()).defines
+		);
+		"get_type", vfun1 (fun s ->
+			let tname = dec_string s in
+			match (get_api()).get_type tname with
+			| None -> failwith ("Type not found '" ^ tname ^ "'")
+			| Some t -> encode_type t
+		);
+		"get_module", vfun1 (fun s ->
+			enc_array (List.map encode_type ((get_api()).get_module (dec_string s)))
+		);
+		"after_typing", vfun1 (fun f ->
+			let f = prepare_callback f 1 in
+			(get_api()).after_typing (fun tl -> ignore(f [enc_array (List.map encode_module_type tl)]));
+			vnull
+		);
+		"on_generate", vfun1 (fun f ->
+			let f = prepare_callback f 1 in
+			(get_api()).on_generate (fun tl -> ignore(f [enc_array (List.map encode_type tl)]));
+			vnull
+		);
+		"after_generate", vfun1 (fun f ->
+			let f = prepare_callback f 0 in
+			(get_api()).after_generate (fun () -> ignore(f []));
+			vnull
+		);
+		"on_type_not_found", vfun1 (fun f ->
+			let f = prepare_callback f 1 in
+			(get_api()).on_type_not_found (fun path -> f [enc_string path]);
+			vnull
+		);
+		"parse", vfun3 (fun s p b ->
+			let s = dec_string s in
+			if s = "" then raise Invalid_expr;
+			encode_expr ((get_api()).parse_string s (decode_pos p) (dec_bool b))
+		);
+		"make_expr", vfun2 (fun v p ->
+			encode_expr (value_to_expr v (decode_pos p))
+		);
+		"signature", vfun1 (fun v ->
+			enc_string (Digest.to_hex (value_signature v))
+		);
+		"to_complex", vfun1 (fun v ->
+			try	encode_ctype (TExprToExpr.convert_type' (decode_type v))
+			with Exit -> vnull
+		);
+		"unify", vfun2 (fun t1 t2 ->
+			let e1 = mk (TObjectDecl []) (decode_type t1) Globals.null_pos in
+			try ignore(((get_api()).cast_or_unify) (decode_type t2) e1 Globals.null_pos); vbool true
+			with Error.Error (Error.Unify _,_) -> vbool false
+		);
+		"typeof", vfun1 (fun v ->
+			encode_type ((get_api()).type_expr (decode_expr v)).etype
+		);
+		"type_expr", vfun1 (fun v ->
+			encode_texpr ((get_api()).type_expr (decode_expr v))
+		);
+		"resolve_type", vfun2 (fun t p ->
+			encode_type ((get_api()).resolve_type (fst (decode_ctype t)) (decode_pos p));
+		);
+		"s_type", vfun1 (fun v ->
+			enc_string (Type.s_type (print_context()) (decode_type v))
+		);
+		"s_expr", vfun2 (fun v b ->
+			let f = if dec_opt_bool b then Type.s_expr_pretty false "" false else Type.s_expr_ast true "" in
+			enc_string (f (Type.s_type (print_context())) (decode_texpr v))
+		);
+		"is_fmt_string", vfun1 (fun p ->
+			vbool (Lexer.is_fmt_string (decode_pos p))
+		);
+		"format_string", vfun2 (fun s p ->
+			encode_expr ((get_api()).format_string (dec_string s) (decode_pos p))
+		);
+		"allow_package", vfun1 (fun s ->
+			(get_api()).allow_package (dec_string s);
+			vnull
+		);
+		"type_patch", vfun4 (fun t f s v ->
+			(get_api()).type_patch (dec_string t) (dec_string f) (dec_bool s) (opt dec_string v);
+			vnull
+		);
+		"meta_patch", vfun4 (fun m t f s ->
+			(get_api()).meta_patch (dec_string m) (dec_string t) (opt dec_string f) (dec_bool s);
+			vnull
+		);
+		"add_global_metadata", vfun5 (fun s1 s2 b1 b2 b3 ->
+			(get_api()).add_global_metadata (dec_string s1) (dec_string s2) (dec_bool b1,dec_bool b2,dec_bool b3);
+			vnull
+		);
+		"custom_js", vfun1 (fun f ->
+			let f = prepare_callback f 1 in
+			(get_api()).set_js_generator (fun js_ctx ->
+				let com = ccom() in
+				let api = enc_obj [
+					"outputFile", enc_string com.file;
+					"types", enc_array (List.map (fun t -> encode_type (type_of_module_type t)) com.types);
+					"main", (match com.main with None -> vnull | Some e -> encode_texpr e);
+					"generateValue", vfun1 (fun v ->
+						let e = decode_texpr v in
+						let str = Genjs.gen_single_expr js_ctx e false in
+						enc_string str
+					);
+					"isKeyword", vfun1 (fun v ->
+						vbool (Hashtbl.mem Genjs.kwds (dec_string v))
+					);
+					"hasFeature", vfun1 (fun v ->
+						vbool (Common.has_feature com (dec_string v))
+					);
+					"addFeature", vfun1 (fun v ->
+						Common.add_feature com (dec_string v);
+						vnull
+					);
+					"quoteString", vfun1 (fun v ->
+						enc_string ("\"" ^ Ast.s_escape (dec_string v) ^ "\"")
+					);
+					"buildMetaData", vfun1 (fun t ->
+						match Codegen.build_metadata com (decode_tdecl t) with
+						| None -> vnull
+						| Some e -> encode_texpr e
+					);
+					"generateStatement", vfun1 (fun v ->
+						let e = decode_texpr v in
+						let str = Genjs.gen_single_expr js_ctx e true in
+						enc_string str
+					);
+					"setTypeAccessor", vfun1 (fun callb ->
+						let callb = prepare_callback callb 1 in
+						js_ctx.Genjs.type_accessor <- (fun t ->
+							dec_string (callb [encode_type (type_of_module_type t)])
+						);
+						vnull
+					);
+					"setCurrentClass", vfun1 (fun c ->
+						Genjs.set_current_class js_ctx (match decode_tdecl c with TClassDecl c -> c | _ -> assert false);
+						vnull
+					);
+				] in
+				ignore(f [api]);
+			);
+			vnull
+		);
+		"get_pos_infos", vfun1 (fun p ->
+			let p = decode_pos p in
+			enc_obj ["min",vint p.Globals.pmin;"max",vint p.Globals.pmax;"file",enc_string p.Globals.pfile]
+		);
+		"make_pos", vfun3 (fun min max file ->
+			encode_pos { Globals.pmin = dec_int min; Globals.pmax = dec_int max; Globals.pfile = dec_string file }
+		);
+		"add_resource", vfun2 (fun name data ->
+			let name = dec_string name in
+			let data = decode_bytes data in
+			if name = "" then failwith "Empty resource name";
+			Hashtbl.replace (ccom()).resources name data;
+			let m = if name.[0] = '$' then (get_api()).current_macro_module() else (get_api()).current_module() in
+			m.m_extra.m_binded_res <- PMap.add name data m.m_extra.m_binded_res;
+			vnull
+		);
+		"get_resources", vfun0 (fun() ->
+			encode_string_map encode_bytes (Hashtbl.fold (fun k v acc -> PMap.add k v acc) (ccom()).resources PMap.empty)
+		);
+		"local_module", vfun0 (fun() ->
+			let m = (get_api()).current_module() in
+			enc_string (s_type_path m.m_path);
+		);
+		"local_type", vfun0 (fun() ->
+			match (get_api()).get_local_type() with
+			| None -> vnull
+			| Some t -> encode_type t
+		);
+		"expected_type", vfun0 (fun() ->
+			match (get_api()).get_expected_type() with
+			| None -> vnull
+			| Some t -> encode_type t
+		);
+		"call_arguments", vfun0 (fun() ->
+			match (get_api()).get_call_arguments() with
+			| None -> vnull
+			| Some el -> enc_array (List.map encode_expr el)
+		);
+		"local_method", vfun0 (fun() ->
+			enc_string ((get_api()).get_local_method())
+		);
+		"local_using", vfun0 (fun() ->
+			enc_array (List.map encode_clref ((get_api()).get_local_using()))
+		);
+		"local_imports", vfun0 (fun() ->
+			enc_array (List.map encode_import ((get_api()).get_local_imports()))
+		);
+		"local_vars", vfun1 (fun as_var ->
+			let as_var = dec_opt_bool as_var in
+			let vars = (get_api()).get_local_vars() in
+			encode_string_map (if as_var then encode_tvar else (fun v -> encode_type v.v_type)) vars
+		);
+		"follow_with_abstracts", vfun2 (fun v once ->
+			let t = decode_type v in
+			let follow_once t =
+				match t with
+				| TMono r ->
+					(match !r with
+					| None -> t
+					| Some t -> t)
+				| TAbstract (a,tl) when not (Meta.has Meta.CoreType a.a_meta) ->
+					Abstract.get_underlying_type a tl
+				| TAbstract _ | TEnum _ | TInst _ | TFun _ | TAnon _ | TDynamic _ ->
+					t
+				| TType (t,tl) ->
+					apply_params t.t_params tl t.t_type
+				| TLazy f ->
+					(!f)()
+			in
+			encode_type (if dec_opt_bool once then follow_once t else Abstract.follow_with_abstracts t)
+		);
+		"follow", vfun2 (fun v once ->
+			let t = decode_type v in
+			let follow_once t =
+				match t with
+				| TMono r ->
+					(match !r with
+					| None -> t
+					| Some t -> t)
+				| TAbstract _ | TEnum _ | TInst _ | TFun _ | TAnon _ | TDynamic _ ->
+					t
+				| TType (t,tl) ->
+					apply_params t.t_params tl t.t_type
+				| TLazy f ->
+					(!f)()
+			in
+			encode_type (if dec_opt_bool once then follow_once t else follow t)
+		);
+		"build_fields", vfun0 (fun() ->
+			(get_api()).get_build_fields()
+		);
+		"define_type", vfun1 (fun v ->
+			(get_api()).define_type v;
+			vnull
+		);
+		"define_module", vfun4 (fun path vl ui ul ->
+			(get_api()).define_module (dec_string path) (dec_array vl) (List.map decode_import (dec_array ui)) (List.map fst (List.map decode_path (dec_array ul)));
+			vnull
+		);
+		"add_class_path", vfun1 (fun cp ->
+			let com = ccom() in
+			let cp = dec_string cp in
+			let cp = Path.add_trailing_slash cp in
+			com.class_path <- cp :: com.class_path;
+			(match com.get_macros() with
+			| Some(mcom) ->
+				mcom.class_path <- cp :: com.class_path;
+			| None ->
+				());
+			Hashtbl.clear com.file_lookup_cache;
+			vnull
+		);
+		"add_native_lib", vfun1 (fun file ->
+			let file = dec_string file in
+			let com = ccom() in
+			(match com.platform with
+			| Globals.Flash -> Genswf.add_swf_lib com file false
+			| Globals.Java -> Genjava.add_java_lib com file false
+			| Globals.Cs ->
+				let file, is_std = match ExtString.String.nsplit file "@" with
+					| [file] ->
+						file,false
+					| [file;"std"] ->
+						file,true
+					| _ -> failwith ("unsupported file@`std` format: " ^ file)
+				in
+				Gencs.add_net_lib com file is_std
+			| _ -> failwith "Unsupported platform");
+			vnull
+		);
+		"add_native_arg", vfun1 (fun arg ->
+			let arg = dec_string arg in
+			let com = ccom() in
+			(match com.platform with
+			| Globals.Java | Globals.Cs | Globals.Cpp ->
+				com.c_args <- arg :: com.c_args
+			| _ -> failwith "Unsupported platform");
+			vnull
+		);
+		"module_dependency", vfun2 (fun m file ->
+			(get_api()).module_dependency (dec_string m) (dec_string file) false;
+			vnull
+		);
+		"module_reuse_call", vfun2 (fun m mcall ->
+			(get_api()).module_dependency (dec_string m) (dec_string mcall) true;
+			vnull
+		);
+		"get_typed_expr", vfun1 (fun e ->
+			let e = decode_texpr e in
+			encode_expr (TExprToExpr.convert_expr e)
+		);
+		"store_typed_expr", vfun1 (fun e ->
+			let e = decode_texpr e in
+			encode_expr ((get_api()).store_typed_expr e)
+		);
+		"get_output", vfun0 (fun() ->
+			enc_string (ccom()).file
+		);
+		"set_output", vfun1 (fun s ->
+			(ccom()).file <- dec_string s;
+			vnull
+		);
+		"get_display_pos", vfun0 (fun() ->
+			let p = !Parser.resume_display in
+			if p = Globals.null_pos then
+				vnull
+			else
+				enc_obj ["file",enc_string p.Globals.pfile;"pos",vint p.Globals.pmin]
+		);
+		"pattern_locals", vfun2 (fun e t ->
+			let loc = (get_api()).get_pattern_locals (decode_expr e) (decode_type t) in
+			encode_string_map (fun (v,_) -> encode_type v.v_type) loc
+		);
+		"macro_context_reused", vfun1 (fun c ->
+			let c = prepare_callback c 0 in
+			(get_api()).on_reuse (fun() -> dec_bool (c []));
+			vnull
+		);
+		"apply_params", vfun3 (fun tpl tl t ->
+			let tl = List.map decode_type (dec_array tl) in
+			let tpl = List.map (fun v -> dec_string (field v "name"), decode_type (field v "t")) (dec_array tpl) in
+			let rec map t = match t with
+				| TInst({cl_kind = KTypeParameter _},_) ->
+					begin try
+						(* use non-physical equality check here to make apply_params work *)
+						snd (List.find (fun (_,t2) -> type_iseq t t2) tpl)
+					with Not_found ->
+						Type.map map t
+					end
+				| _ -> Type.map map t
+			in
+			encode_type (apply_params tpl tl (map (decode_type t)))
+		);
+		"include_file", vfun2 (fun file position ->
+			let file = dec_string file in
+			let position = dec_string position in
+			let file = if Sys.file_exists file then
+				file
+			else try Common.find_file (ccom()) file with
+				| Not_found ->
+					failwith ("unable to find file for inclusion: " ^ file)
+			in
+			(ccom()).include_files <- (file, position) :: (ccom()).include_files;
+			vnull
+		);
+		(* Compilation server *)
+		"server_add_module_check_policy", vfun4 (fun filter policy recursive context_options ->
+			let filter = List.map dec_string (dec_array filter) in
+			let policy = List.map dec_int (dec_array policy) in
+			(get_api()).add_module_check_policy filter policy (dec_bool recursive) (dec_int context_options);
+			vnull
+		);
+		"server_invalidate_files", vfun1 (fun a ->
+			let cs = match CompilationServer.get() with Some cs -> cs | None -> failwith "compilation server not running" in
+			List.iter (fun v ->
+				let s = dec_string v in
+				let s = Path.unique_full_path s in
+				CompilationServer.taint_modules cs s;
+				CompilationServer.remove_files cs s;
+			) (dec_array a);
+			vnull
+		);
+	]
+
+
+end

+ 80 - 96
src/macro/macroContext.ml

@@ -25,10 +25,20 @@ open Typecore
 open Error
 open Globals
 
-(*module Interp = Hlmacro*)
+(* module Interp = Hlmacro *)
+
+module InterpImpl = Interp
+module Interp = struct
+	module BuiltApi = MacroApi.MacroApiImpl(InterpImpl)
+	include InterpImpl
+	include BuiltApi
+end
 
 let macro_enable_cache = ref false
 let macro_interp_cache = ref None
+let macro_interp_on_reuse = ref []
+let macro_interp_reused = ref false
+
 let delayed_macro_result = ref ((fun() -> assert false) : unit -> unit -> Interp.value)
 let unify_call_args_ref = ref (fun _ _ _ _ _ _ _-> assert false)
 let unify_call_args a b c d e f g : (texpr list * t) = !unify_call_args_ref a b c d e f g
@@ -99,12 +109,12 @@ let load_macro_ref : (typer -> bool -> path -> string -> pos -> (typer * ((strin
 
 let make_macro_api ctx p =
 	let parse_expr_string s p inl =
-		typing_timer ctx false (fun() -> try Parser.parse_expr_string ctx.com s p error inl with Exit -> raise Interp.Invalid_expr)
+		typing_timer ctx false (fun() -> try Parser.parse_expr_string ctx.com s p error inl with Exit -> raise MacroApi.Invalid_expr)
 	in
 	{
-		Interp.pos = p;
-		Interp.get_com = (fun() -> ctx.com);
-		Interp.get_type = (fun s ->
+		MacroApi.pos = p;
+		MacroApi.get_com = (fun() -> ctx.com);
+		MacroApi.get_type = (fun s ->
 			typing_timer ctx true (fun() ->
 				let path = parse_path s in
 				let tp = match List.rev (fst path) with
@@ -120,38 +130,38 @@ let make_macro_api ctx p =
 					None
 			)
 		);
-		Interp.resolve_type = (fun t p ->
+		MacroApi.resolve_type = (fun t p ->
 			typing_timer ctx true (fun() -> Typeload.load_complex_type ctx false p (t,null_pos))
 		);
-		Interp.get_module = (fun s ->
+		MacroApi.get_module = (fun s ->
 			typing_timer ctx true (fun() ->
 				let path = parse_path s in
 				let m = List.map type_of_module_type (Typeload.load_module ctx path p).m_types in
 				m
 			)
 		);
-		Interp.after_typing = (fun f ->
+		MacroApi.after_typing = (fun f ->
 			Common.add_typing_filter ctx.com (fun tl ->
 				let t = macro_timer ctx ["afterTyping"] in
 				f tl;
 				t()
 			)
 		);
-		Interp.on_generate = (fun f ->
+		MacroApi.on_generate = (fun f ->
 			Common.add_filter ctx.com (fun() ->
 				let t = macro_timer ctx ["onGenerate"] in
 				f (List.map type_of_module_type ctx.com.types);
 				t()
 			)
 		);
-		Interp.after_generate = (fun f ->
+		MacroApi.after_generate = (fun f ->
 			Common.add_final_filter ctx.com (fun() ->
 				let t = macro_timer ctx ["afterGenerate"] in
 				f();
 				t()
 			)
 		);
-		Interp.on_type_not_found = (fun f ->
+		MacroApi.on_type_not_found = (fun f ->
 			ctx.com.load_extern_type <- ctx.com.load_extern_type @ [fun path p ->
 				let td = f (s_type_path path) in
 				if td = Interp.vnull then
@@ -161,11 +171,11 @@ let make_macro_api ctx p =
 					Some (name,(pack,[tdef,p]))
 			];
 		);
-		Interp.parse_string = parse_expr_string;
-		Interp.type_expr = (fun e ->
+		MacroApi.parse_string = parse_expr_string;
+		MacroApi.type_expr = (fun e ->
 			typing_timer ctx true (fun() -> type_expr ctx e Value)
 		);
-		Interp.type_macro_expr = (fun e ->
+		MacroApi.type_macro_expr = (fun e ->
 			let e = typing_timer ctx true (fun() -> type_expr ctx e Value) in
 			let rec loop e = match e.eexpr with
 				| TField(_,FStatic(c,({cf_kind = Method _} as cf))) -> ignore(!load_macro_ref ctx false c.cl_path cf.cf_name e.epos)
@@ -174,15 +184,15 @@ let make_macro_api ctx p =
 			loop e;
 			e
 		);
-		Interp.store_typed_expr = (fun te ->
+		MacroApi.store_typed_expr = (fun te ->
 			let p = te.epos in
 			let id = get_next_stored_typed_expr_id() in
 			ctx.com.stored_typed_exprs <- PMap.add id te ctx.com.stored_typed_exprs;
 			let eid = (EConst (Int (string_of_int id))), p in
 			(EMeta ((Meta.StoredTypedExpr,[],p), eid)), p
 		);
-		Interp.allow_package = (fun v -> Common.allow_package ctx.com v);
-		Interp.type_patch = (fun t f s v ->
+		MacroApi.allow_package = (fun v -> Common.allow_package ctx.com v);
+		MacroApi.type_patch = (fun t f s v ->
 			typing_timer ctx false (fun() ->
 				let v = (match v with None -> None | Some s ->
 					match Parser.parse_string ctx.com ("typedef T = " ^ s) null_pos error false with
@@ -195,7 +205,7 @@ let make_macro_api ctx p =
 				| Some _ -> tp.tp_type <- Option.map fst v
 			);
 		);
-		Interp.meta_patch = (fun m t f s ->
+		MacroApi.meta_patch = (fun m t f s ->
 			let m = (match Parser.parse_string ctx.com (m ^ " typedef T = T") null_pos error false with
 				| _,[ETypedef t,_] -> t.d_meta
 				| _ -> assert false
@@ -203,60 +213,15 @@ let make_macro_api ctx p =
 			let tp = get_type_patch ctx t (match f with None -> None | Some f -> Some (f,s)) in
 			tp.tp_meta <- tp.tp_meta @ m;
 		);
-		Interp.set_js_generator = (fun gen ->
+		MacroApi.set_js_generator = (fun gen ->
 			let js_ctx = Genjs.alloc_ctx ctx.com in
 			ctx.com.js_gen <- Some (fun() ->
-				let jsctx = Interp.enc_obj [
-					"outputFile", Interp.enc_string ctx.com.file;
-					"types", Interp.enc_array (List.map (fun t -> Interp.encode_type (type_of_module_type t)) ctx.com.types);
-					"main", (match ctx.com.main with None -> Interp.vnull | Some e -> Interp.encode_texpr e);
-					"generateValue", Interp.fun1 (fun v ->
-						let e = Interp.decode_texpr v in
-						let str = Genjs.gen_single_expr js_ctx e false in
-						Interp.enc_string str
-					);
-					"isKeyword", Interp.fun1 (fun v ->
-						Interp.vbool (Hashtbl.mem Genjs.kwds (Interp.dec_string v))
-					);
-					"hasFeature", Interp.fun1 (fun v ->
-						Interp.vbool (Common.has_feature ctx.com (Interp.dec_string v))
-					);
-					"addFeature", Interp.fun1 (fun v ->
-						Common.add_feature ctx.com (Interp.dec_string v);
-						Interp.vnull
-					);
-					"quoteString", Interp.fun1 (fun v ->
-						Interp.enc_string ("\"" ^ Ast.s_escape (Interp.dec_string v) ^ "\"")
-					);
-					"buildMetaData", Interp.fun1 (fun t ->
-						match Codegen.build_metadata ctx.com (Interp.decode_tdecl t) with
-						| None -> Interp.vnull
-						| Some e -> Interp.encode_texpr e
-					);
-					"generateStatement", Interp.fun1 (fun v ->
-						let e = Interp.decode_texpr v in
-						let str = Genjs.gen_single_expr js_ctx e true in
-						Interp.enc_string str
-					);
-					"setTypeAccessor", Interp.fun1 (fun callb ->
-						js_ctx.Genjs.type_accessor <- (fun t ->
-							let v = Interp.encode_type (type_of_module_type t) in
-							let ret = Interp.call (Interp.get_ctx()) Interp.vnull callb [v] Nast.null_pos in
-							Interp.dec_string ret
-						);
-						Interp.vnull
-					);
-					"setCurrentClass", Interp.fun1 (fun c ->
-						Genjs.set_current_class js_ctx (match Interp.decode_tdecl c with TClassDecl c -> c | _ -> assert false);
-						Interp.vnull
-					);
-				] in
 				let t = macro_timer ctx ["jsGenerator"] in
-				gen jsctx;
+				gen js_ctx;
 				t()
 			);
 		);
-		Interp.get_local_type = (fun() ->
+		MacroApi.get_local_type = (fun() ->
 			match ctx.g.get_build_infos() with
 			| Some (mt,tl,_) ->
 				Some (match mt with
@@ -270,38 +235,38 @@ let make_macro_api ctx p =
 				else
 					Some (TInst (ctx.curclass,[]))
 		);
-		Interp.get_expected_type = (fun() ->
+		MacroApi.get_expected_type = (fun() ->
 			match ctx.with_type_stack with
 				| (WithType t) :: _ -> Some t
 				| _ -> None
 		);
-		Interp.get_call_arguments = (fun() ->
+		MacroApi.get_call_arguments = (fun() ->
 			match ctx.call_argument_stack with
 				| [] -> None
 				| el :: _ -> Some el
 		);
-		Interp.get_local_method = (fun() ->
+		MacroApi.get_local_method = (fun() ->
 			ctx.curfield.cf_name;
 		);
-		Interp.get_local_using = (fun() ->
+		MacroApi.get_local_using = (fun() ->
 			List.map fst ctx.m.module_using;
 		);
-		Interp.get_local_imports = (fun() ->
+		MacroApi.get_local_imports = (fun() ->
 			ctx.m.module_imports;
 		);
-		Interp.get_local_vars = (fun () ->
+		MacroApi.get_local_vars = (fun () ->
 			ctx.locals;
 		);
-		Interp.get_build_fields = (fun() ->
+		MacroApi.get_build_fields = (fun() ->
 			match ctx.g.get_build_infos() with
 			| None -> Interp.vnull
 			| Some (_,_,fields) -> Interp.enc_array (List.map Interp.encode_field fields)
 		);
-		Interp.get_pattern_locals = (fun e t ->
+		MacroApi.get_pattern_locals = (fun e t ->
 			!get_pattern_locals_ref ctx e t
 		);
-		Interp.define_type = (fun v ->
-			let m, tdef, pos = (try Interp.decode_type_def v with Interp.Invalid_expr -> Interp.exc_string "Invalid type definition") in
+		MacroApi.define_type = (fun v ->
+			let m, tdef, pos = (try Interp.decode_type_def v with MacroApi.Invalid_expr -> Interp.exc_string "Invalid type definition") in
 			let add is_macro ctx =
 				let mnew = Typeload.type_module ctx m ctx.m.curmod.m_extra.m_file [tdef,pos] pos in
 				mnew.m_extra.m_kind <- if is_macro then MMacro else MFake;
@@ -315,9 +280,9 @@ let make_macro_api ctx p =
 			| _ ->
 				()
 		);
-		Interp.define_module = (fun m types imports usings ->
+		MacroApi.define_module = (fun m types imports usings ->
 			let types = List.map (fun v ->
-				let _, tdef, pos = (try Interp.decode_type_def v with Interp.Invalid_expr -> Interp.exc_string "Invalid type definition") in
+				let _, tdef, pos = (try Interp.decode_type_def v with MacroApi.Invalid_expr -> Interp.exc_string "Invalid type definition") in
 				tdef, pos
 			) types in
 			let pos = (match types with [] -> null_pos | (_,p) :: _ -> p) in
@@ -337,18 +302,18 @@ let make_macro_api ctx p =
 				add_dependency mnew ctx.m.curmod;
 			end
 		);
-		Interp.module_dependency = (fun mpath file ismacro ->
+		MacroApi.module_dependency = (fun mpath file ismacro ->
 			let m = typing_timer ctx false (fun() -> Typeload.load_module ctx (parse_path mpath) p) in
 			if ismacro then
 				m.m_extra.m_macro_calls <- file :: List.filter ((<>) file) m.m_extra.m_macro_calls
 			else
 				add_dependency m (create_fake_module ctx file);
 		);
-		Interp.current_module = (fun() ->
+		MacroApi.current_module = (fun() ->
 			ctx.m.curmod
 		);
-		Interp.current_macro_module = (fun () -> assert false);
-		Interp.delayed_macro = (fun i ->
+		MacroApi.current_macro_module = (fun () -> assert false);
+		MacroApi.delayed_macro = (fun i ->
 			let mctx = (match ctx.g.macros with None -> assert false | Some (_,mctx) -> mctx) in
 			let f = (try DynArray.get mctx.g.delayed_macros i with _ -> failwith "Delayed macro retrieve failure") in
 			f();
@@ -356,16 +321,16 @@ let make_macro_api ctx p =
 			delayed_macro_result := (fun() -> assert false);
 			ret
 		);
-		Interp.use_cache = (fun() ->
+		MacroApi.use_cache = (fun() ->
 			!macro_enable_cache
 		);
-		Interp.format_string = (fun s p ->
+		MacroApi.format_string = (fun s p ->
 			ctx.g.do_format_string ctx s p
 		);
-		Interp.cast_or_unify = (fun t e p ->
+		MacroApi.cast_or_unify = (fun t e p ->
 			AbstractCast.cast_or_unify_raise ctx t e p
 		);
-		Interp.add_global_metadata = (fun s1 s2 config ->
+		MacroApi.add_global_metadata = (fun s1 s2 config ->
 			let meta = (match Parser.parse_string ctx.com (s2 ^ " typedef T = T") null_pos error false with
 				| _,[ETypedef t,_] -> t.d_meta
 				| _ -> assert false
@@ -374,7 +339,7 @@ let make_macro_api ctx p =
 				ctx.g.global_metadata <- (ExtString.String.nsplit s1 ".",m,config) :: ctx.g.global_metadata;
 			) meta;
 		);
-		Interp.add_module_check_policy = (fun sl il b i ->
+		MacroApi.add_module_check_policy = (fun sl il b i ->
 			let add ctx =
 				ctx.g.module_check_policies <- (List.fold_left (fun acc s -> (ExtString.String.nsplit s ".",List.map Obj.magic il,b) :: acc) ctx.g.module_check_policies sl);
 				Hashtbl.iter (fun _ m -> m.m_extra.m_check_policy <- Typeload.get_policy ctx m.m_path) ctx.g.modules;
@@ -388,6 +353,9 @@ let make_macro_api ctx p =
 			| CompilationServer.MacroContext -> add_macro ctx
 			| CompilationServer.NormalAndMacroContext -> add ctx; add_macro ctx;
 		);
+		MacroApi.on_reuse = (fun f ->
+			macro_interp_on_reuse := f :: !macro_interp_on_reuse
+		);
 	}
 
 let rec init_macro_interp ctx mctx mint =
@@ -396,7 +364,11 @@ let rec init_macro_interp ctx mctx mint =
 	ignore(Typeload.load_module mctx (["haxe";"macro"],"Type") p);
 	flush_macro_context mint ctx;
 	Interp.init mint;
-	if !macro_enable_cache && not (Common.defined mctx.com Define.NoMacroCache) then macro_interp_cache := Some mint
+	if !macro_enable_cache && not (Common.defined mctx.com Define.NoMacroCache) then begin
+		macro_interp_cache := Some mint;
+		macro_interp_on_reuse := [];
+		macro_interp_reused := true;
+	end
 
 and flush_macro_context mint ctx =
 	let t = macro_timer ctx ["flush"] in
@@ -405,8 +377,18 @@ and flush_macro_context mint ctx =
 	let _, types, modules = ctx.g.do_generate mctx in
 	mctx.com.types <- types;
 	mctx.com.Common.modules <- modules;
+	let check_reuse() =
+		if !macro_interp_reused then
+			true
+		else if not (List.for_all (fun f -> f())  !macro_interp_on_reuse) then
+			false
+		else begin
+			macro_interp_reused := true;
+			true;
+		end
+	in
 	(* if one of the type we are using has been modified, we need to create a new macro context from scratch *)
-	let mint = if not (Interp.can_reuse mint types) then begin
+	let mint = if not (Interp.can_reuse mint types && check_reuse()) then begin
 		let com2 = mctx.com in
 		let mint = Interp.create com2 (make_macro_api ctx Globals.null_pos) in
 		let macro = ((fun() -> Interp.select mint), mctx) in
@@ -452,6 +434,7 @@ let create_macro_interp ctx mctx =
 			let mint = Interp.create com2 (make_macro_api ctx null_pos) in
 			mint, (fun() -> init_macro_interp ctx mctx mint)
 		| Some mint ->
+			macro_interp_reused := false;
 			Interp.do_reuse mint (make_macro_api ctx null_pos);
 			mint, (fun() -> ())
 	) in
@@ -507,7 +490,7 @@ let load_macro ctx display cpath f p =
 		if display then mctx.com.display <- ctx.com.display;
 		let m = (try Hashtbl.find ctx.g.types_module cpath with Not_found -> cpath) in
 		let mloaded = Typeload.load_module mctx m p in
-		api.Interp.current_macro_module <- (fun() -> mloaded);
+		api.MacroApi.current_macro_module <- (fun() -> mloaded);
 		mctx.m <- {
 			curmod = mloaded;
 			module_types = [];
@@ -660,7 +643,7 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			| MAExpr ->
 				Interp.encode_expr e
 			| MAFunction ->
-				let e = ictx.Interp.curapi.Interp.type_macro_expr e in
+				let e = ictx.Interp.curapi.MacroApi.type_macro_expr e in
 				begin match Interp.eval_expr ictx e with
 				| Some v -> v
 				| None -> Interp.vnull
@@ -696,13 +679,13 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 					else try
 						let ct = Interp.decode_ctype v in
 						Typeload.load_complex_type ctx false p ct;
-					with Interp.Invalid_expr ->
+					with MacroApi.Invalid_expr ->
 						Interp.decode_type v
 					in
 					ctx.ret <- t;
 					(EBlock [],p)
 				)
-			with Interp.Invalid_expr ->
+			with MacroApi.Invalid_expr ->
 				if v = Interp.vnull then
 					error "Unexpected null value returned from macro" p
 				else
@@ -725,14 +708,14 @@ let type_macro ctx mode cpath f (el:Ast.expr list) p =
 			delayed_macro_result := (fun() ->
 				let mint = Interp.get_ctx() in
 				match call() with
-				| None -> (fun() -> raise Interp.Abort)
+				| None -> (fun() -> raise MacroApi.Abort)
 				| Some e -> Interp.eval_delayed mint (type_expr ctx e Value)
 			);
 		);
 		ctx.m.curmod.m_extra.m_time <- -1.; (* disable caching for modules having macro-in-macro *)
 		if Common.defined ctx.com Define.MacroDebug then
 			ctx.com.warning "Macro-in-macro call detected" p;
-		let e = (EConst (Ident "__dollar__delay_call"),p) in
+		let e = (EConst (Ident "$__delayed_call__"),p) in
 		Some (EUntyped (ECall (e,[EConst (Int (string_of_int pos)),p]),p),p)
 	end else
 		call()
@@ -776,7 +759,8 @@ let interpret ctx =
 	| None -> ()
 	| Some e -> ignore(Interp.eval_expr mctx e)
 
-let setup = Interp.setup
+let setup() =
+	Interp.setup Interp.macro_api
 
 ;;
 load_macro_ref := load_macro;

+ 1 - 1
src/optimization/optimizer.ml

@@ -373,7 +373,7 @@ let rec type_inline ctx cf f ethis params tret config p ?(self_calling_closure=f
 			l.i_read <- l.i_read + (if !in_loop then 2 else 1);
 			(* never inline a function which contain a delayed macro because its bound
 				to its variables and not the calling method *)
-			if v.v_name = "__dollar__delay_call" then cancel_inlining := true;
+			if v.v_name = "$__delayed_call__" then cancel_inlining := true;
 			let e = { e with eexpr = TLocal l.i_subst } in
 			if l.i_abstract_this then mk (TCast(e,None)) v.v_type e.epos else e
 		| TConst TThis ->

+ 2 - 2
src/syntax/parser.ml

@@ -356,7 +356,7 @@ let reify in_macro =
 		let pmin = (EConst (Int (string_of_int p.pmin)),p) in
 		let pmax = (EConst (Int (string_of_int p.pmax)),p) in
 		if in_macro then
-			(EUntyped (ECall ((EConst (Ident "__dollar__mk_pos"),p),[file;pmin;pmax]),p),p)
+			(EUntyped (ECall ((EConst (Ident "$__mk_pos__"),p),[file;pmin;pmax]),p),p)
 		else
 			to_obj [("file",file);("min",pmin);("max",pmax)] p
 	and to_expr_array a p = match a with
@@ -370,7 +370,7 @@ let reify in_macro =
 		in
 		let loop e = to_expr e (snd e) in
 		match fst e with
-		| EConst (Ident n) when n.[0] = '$' && String.length n > 1 ->
+		| EConst (Ident n) when n.[0] = '$' && String.length n > 1 && n <> "$__mk_pos__" ->
 			to_string n p
 		| EConst c ->
 			expr "EConst" [to_const c p]

+ 15 - 18
std/haxe/macro/Compiler.hx

@@ -50,15 +50,15 @@ class Compiler {
 	static var path = ~/^[A-Za-z_][A-Za-z0-9_.]*$/;
 
 	public static function allowPackage( v : String ) {
-		untyped load("allow_package", 1)(v.__s);
+		load("allow_package", 1)(v);
 	}
 
 	/**
 		Set a conditional compiler flag.
 	**/
-	public static function define( flag : String, ?value : String ) untyped {
+	public static function define( flag : String, ?value : String ) {
 		var v = flag + (value == null ? "" : "=" + value);
-		load("define", 1)(v.__s);
+		load("define", 1)(v);
 	}
 
 	/**
@@ -68,7 +68,7 @@ class Compiler {
 	public static function removeField( className : String, field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( !ident.match(field) ) throw "Invalid "+field;
-		untyped load("type_patch",4)(className.__s,field.__s,isStatic == true,null);
+		load("type_patch",4)(className,field,isStatic == true,null);
 	}
 
 	/**
@@ -78,7 +78,7 @@ class Compiler {
 	public static function setFieldType( className : String, field : String, type : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( !ident.match((field.charAt(0) == "$") ? field.substr(1) : field) ) throw "Invalid "+field;
-		untyped load("type_patch",4)(className.__s,field.__s,isStatic == true,type.__s);
+		load("type_patch",4)(className,field,isStatic == true,type);
 	}
 
 	/**
@@ -88,33 +88,30 @@ class Compiler {
 	public static function addMetadata( meta : String, className : String, ?field : String, ?isStatic : Bool ) {
 		if( !path.match(className) ) throw "Invalid "+className;
 		if( field != null && !ident.match(field) ) throw "Invalid "+field;
-		untyped load("meta_patch",4)(meta.__s,className.__s,(field == null)?null:field.__s,isStatic == true);
+		load("meta_patch",4)(meta,className,field,isStatic == true);
 	}
 
 	public static function addClassPath( path : String ) {
-		untyped load("add_class_path",1)(path.__s);
+		load("add_class_path",1)(path);
 	}
 
 	public static function getOutput() : String {
-		return new String(untyped load("get_output",0)());
+		return load("get_output",0)();
 	}
 
 	public static function setOutput( fileOrDir : String ) {
-		untyped load("set_output",1)(untyped fileOrDir.__s);
+		load("set_output",1)(fileOrDir);
 	}
 
 	public static function getDisplayPos() : Null<{ file : String, pos : Int }> {
-		var o = untyped load("get_display_pos",0)();
-		if( o != null )
-			o.file = new String(o.file);
-		return o;
+		return load("get_display_pos",0)();
 	}
 
 	/**
 		Adds a native library depending on the platform (e.g. `-swf-lib` for Flash).
 	**/
 	public static function addNativeLib( name : String ) {
-		untyped load("add_native_lib",1)(name.__s);
+		load("add_native_lib",1)(name);
 	}
 
 	/**
@@ -122,7 +119,7 @@ class Compiler {
 	 **/
 	public static function addNativeArg( argument : String )
 	{
-		untyped load("add_native_arg",1)(argument.__s);
+		load("add_native_arg",1)(argument);
 	}
 
 	/**
@@ -203,7 +200,7 @@ class Compiler {
 	/**
 		Exclude a specific class, enum, or all classes and enums in a
 		package from being generated. Excluded types become `extern`.
-		
+
 		@param rec If true, recursively excludes all sub-packages.
 	**/
 	public static function exclude( pack : String, ?rec = true ) {
@@ -345,7 +342,7 @@ class Compiler {
 		through `Context.getType`.
 	**/
 	public static function addGlobalMetadata(pathFilter:String, meta:String, ?recursive:Bool = true, ?toTypes:Bool = true, ?toFields:Bool = false) {
-		untyped load("add_global_metadata",5)(untyped pathFilter.__s, meta.__s, recursive, toTypes, toFields);
+		load("add_global_metadata",5)(pathFilter, meta, recursive, toTypes, toFields);
 	}
 
 	/**
@@ -379,7 +376,7 @@ class Compiler {
 				var p = Context.currentPos();
 				{ expr : EUntyped( { expr : ECall( { expr : EConst(CIdent("__js__")), pos : p }, [ { expr : EConst(CString(f)), pos : p } ]), pos : p } ), pos : p };
 			case Top | Closure:
-				load("include_file", 2)(untyped file.__s, untyped position.__s);
+				load("include_file", 2)(file, position);
 				macro {};
 			case _:
 				Context.error("unknown includeFile position: " + position, Context.currentPos());

+ 25 - 43
std/haxe/macro/Context.hx

@@ -44,7 +44,7 @@ class Context {
 		and aborts the current macro call.
 	**/
 	public static function error( msg : String, pos : Position ) : Dynamic {
-		return load("error",2)(untyped msg.__s, pos);
+		return load("error",2)(msg, pos);
 	}
 
 	/**
@@ -52,14 +52,14 @@ class Context {
 		and aborts the compilation.
 	**/
 	public static function fatalError( msg : String, pos : Position ) : Dynamic {
-		return load("fatal_error",2)(untyped msg.__s, pos);
+		return load("fatal_error",2)(msg, pos);
 	}
 
 	/**
 		Displays a compilation warning `msg` at the given `Position` `pos`.
 	**/
 	public static function warning( msg : String, pos : Position ) {
-		load("warning",2)(untyped msg.__s, pos);
+		load("warning",2)(msg, pos);
 	}
 
 	/**
@@ -72,7 +72,7 @@ class Context {
 		file path. Otherwise it returns the absolute file path.
 	**/
 	public static function resolvePath( file : String ) {
-		return new String(load("resolve",1)(untyped file.__s));
+		return load("resolve",1)(file);
 	}
 
 	/**
@@ -83,11 +83,7 @@ class Context {
 		can be added using `haxe.macro.Compiler.addClassPath`.
 	**/
 	public static function getClassPath() : Array<String> {
-		var c : neko.NativeArray<neko.NativeString> = load("class_path",0)();
-		var a = new Array();
-		for( i in 0...neko.NativeArray.length(c) )
-			a.push(Std.string(c[i]));
-		return a;
+		return load("class_path",0)();
 	}
 
 	/**
@@ -108,9 +104,7 @@ class Context {
 	**/
 	@:require(haxe_ver >= 3.1)
 	public static function getExpectedType():Null<Type> {
-		var l : Type = load("expected_type", 0)();
-		if( l == null ) return null;
-		return l;
+		return load("expected_type", 0)();
 	}
 
 	/**
@@ -142,7 +136,7 @@ class Context {
 		Returns the current module path in/on which the macro was called.
 	**/
 	public static function getLocalModule() : String {
-		return new String(load("local_module", 0)());
+		return load("local_module", 0)();
 	}
 
 	/**
@@ -151,9 +145,7 @@ class Context {
 		If no such type exists, null is returned.
 	**/
 	public static function getLocalType() : Null<Type> {
-		var l : Type = load("local_type", 0)();
-		if( l == null ) return null;
-		return l;
+		return load("local_type", 0)();
 	}
 
 	/**
@@ -162,9 +154,7 @@ class Context {
 		If no such method exists, null is returned.
 	**/
 	public static function getLocalMethod() : Null<String> {
-		var l : String = load("local_method", 0)();
-		if (l == "") return null;
-		return new String(l);
+		return load("local_method", 0)();
 	}
 
 	/**
@@ -216,7 +206,7 @@ class Context {
 		by calling `haxe.macro.Compiler.define`.
 	**/
 	public static function defined( s : String ) : Bool {
-		return load("defined", 1)(untyped s.__s);
+		return load("defined", 1)(s);
 	}
 
 	/**
@@ -230,8 +220,7 @@ class Context {
 		The default value is `"1"`.
 	**/
 	public static function definedValue( key : String ) : String {
-		var d = load("defined_value", 1)(untyped key.__s);
-		return d == null ? null : new String(d);
+		return load("defined_value", 1)(key);
 	}
 
 	/**
@@ -255,7 +244,7 @@ class Context {
 		If no type can be found, an exception of type `String` is thrown.
 	**/
 	public static function getType( name : String ) : Type {
-		return load("get_type", 1)(untyped name.__s);
+		return load("get_type", 1)(name);
 	}
 
 	/**
@@ -268,7 +257,7 @@ class Context {
 		If no module can be found, null is returned.
 	**/
 	public static function getModule( name : String ) : Array<Type> {
-		return load("get_module", 1)(untyped name.__s);
+		return load("get_module", 1)(name);
 	}
 
 	/**
@@ -280,7 +269,7 @@ class Context {
 		The provided `Position` `pos` is used for all generated inner AST nodes.
 	**/
 	public static function parse( expr : String, pos : Position ) : Expr {
-		return load("parse", 3)(untyped expr.__s, pos, false);
+		return load("parse", 3)(expr, pos, false);
 	}
 
 	/**
@@ -288,7 +277,7 @@ class Context {
 		String `expr`.
 	**/
 	public static function parseInlineString( expr : String, pos : Position ) : Expr {
-		return load("parse", 3)(untyped expr.__s, pos, true);
+		return load("parse", 3)(expr, pos, true);
 	}
 
 	/**
@@ -308,7 +297,7 @@ class Context {
 		Returns a hashed MD5 signature of value `v`.
 	**/
 	public static function signature( v : Dynamic ) : String {
-		return new String(load("signature", 1)(v));
+		return load("signature", 1)(v);
 	}
 
 	/**
@@ -430,16 +419,14 @@ class Context {
 		Returns the information stored in `Position` `p`.
 	**/
 	public static function getPosInfos( p : Position ) : { min : Int, max : Int, file : String } {
-		var i = load("get_pos_infos",1)(p);
-		i.file = new String(i.file);
-		return i;
+		return load("get_pos_infos",1)(p);
 	}
 
 	/**
 		Builds a `Position` from `inf`.
 	**/
 	public static function makePosition( inf : { min : Int, max : Int, file : String } ) : Position {
-		return load("make_pos",3)(inf.min,inf.max,untyped inf.file.__s);
+		return load("make_pos",3)(inf.min,inf.max,inf.file);
 	}
 
 	/**
@@ -449,12 +436,7 @@ class Context {
 		`haxe.macro.Context.addResource` to add new resources to the compilation unit.
 	**/
 	public static function getResources():Map<String,haxe.io.Bytes> {
-		var x:haxe.ds.StringMap<neko.NativeString> = load("get_resources",0)();
-		var r = new haxe.ds.StringMap();
-		for (k in x.keys()) {
-			r.set(k, haxe.io.Bytes.ofData(x.get(k)));
-		}
-		return r;
+		return load("get_resources",0)();
 	}
 
 	/**
@@ -470,7 +452,7 @@ class Context {
 		name with a $ sign, this will bind it to the macro module instead.
 	**/
 	public static function addResource( name : String, data : haxe.io.Bytes ) {
-		load("add_resource",2)(untyped name.__s,data.getData());
+		load("add_resource",2)(name,data);
 	}
 
 	/**
@@ -498,9 +480,9 @@ class Context {
 		not allowed to have `.*` wildcards or `in s` shorthands.
 	**/
 	public static function defineModule( modulePath : String, types : Array<TypeDefinition>, ?imports: Array<ImportExpr>, ?usings : Array<TypePath> ) : Void {
-		if (imports == null) imports = [];
-		if (usings == null) usings = [];
-		load("define_module", 4)(untyped modulePath.__s, untyped types.__neko(), untyped imports.__neko(), untyped usings.__neko());
+		if( imports == null ) imports = [];
+		if( usings == null ) usings = [];
+		load("define_module", 4)(modulePath, types, imports, usings);
 	}
 
 	/**
@@ -568,7 +550,7 @@ class Context {
 		Has no effect if the compilation cache is not used.
 	**/
 	public static function registerModuleDependency( modulePath : String, externFile : String ) {
-		load("module_dependency", 2)(untyped modulePath.__s,untyped externFile.__s);
+		load("module_dependency", 2)(modulePath,externFile);
 	}
 
 	/**
@@ -585,7 +567,7 @@ class Context {
 		but calling this function will still trigger loading of given `modulePath`.
 	**/
 	public static function registerModuleReuseCall( modulePath : String, macroCall : String ) {
-		load("module_reuse_call", 2)(untyped modulePath.__s,untyped macroCall.__s);
+		load("module_reuse_call", 2)(modulePath,macroCall);
 	}
 
 	/**

+ 1 - 1
std/haxe/macro/Expr.hx

@@ -22,7 +22,7 @@
 package haxe.macro;
 
 #if (macro && !doc_gen)
-extern enum Position {
+@:coreType abstract Position {
 }
 #else
 /**

+ 1 - 1
std/haxe/macro/MacroStringTools.hx

@@ -39,7 +39,7 @@ class MacroStringTools {
 		elements.
 	**/
 	static public function formatString(s:String, pos:Position) {
-		return Context.load("format_string", 2)(untyped s.__s, pos);
+		return Context.load("format_string", 2)(s, pos);
 	}
 
 	/**

+ 2 - 2
std/haxe/macro/TypeTools.hx

@@ -243,7 +243,7 @@ class TypeTools {
 			throw 'Incompatible arguments: ${typeParameters.length} type parameters and ${concreteTypes.length} concrete types';
 		else if (typeParameters.length == 0)
 			return t;
-		return Context.load("apply_params", 3)(typeParameters.map(function(tp) return {name:untyped tp.name.__s, t:tp.t}), concreteTypes, t);
+		return Context.load("apply_params", 3)(typeParameters, concreteTypes, t);
 	}
 
 	/**
@@ -328,7 +328,7 @@ class TypeTools {
 	/**
 		Converts type `t` to a human-readable String representation.
 	**/
-	static public function toString( t : Type ) : String return new String(Context.load("s_type", 1)(t));
+	static public function toString( t : Type ) : String return Context.load("s_type", 1)(t);
 	#end
 
 	/**

+ 1 - 1
std/haxe/macro/TypedExprTools.hx

@@ -156,7 +156,7 @@ class TypedExprTools {
 
 	#if macro
 	static public function toString(t:TypedExpr, ?pretty = false):String {
-		return new String(haxe.macro.Context.load("s_expr", 2)(t, pretty));
+		return haxe.macro.Context.load("s_expr", 2)(t, pretty);
 	}
 	#end
 }

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä