浏览代码

more hl support

Nicolas Cannasse 9 年之前
父节点
当前提交
9329ee8b0b

+ 103 - 34
genhl.ml

@@ -266,7 +266,7 @@ let list_iteri f l =
 	let p = ref 0 in
 	List.iter (fun v -> f !p v; incr p) l
 
-let rec tstr ?(detailed=false) t =
+let rec tstr ?(stack=[]) ?(detailed=false) t =
 	match t with
 	| HVoid -> "void"
 	| HI8 -> "i8"
@@ -290,8 +290,10 @@ let rec tstr ?(detailed=false) t =
 		"type"
 	| HRef t ->
 		"ref(" ^ tstr t ^ ")"
+	| HVirtual v when List.memq v stack ->
+		"..."
 	| HVirtual v ->
-		"virtual(" ^ String.concat "," (List.map (fun (f,_,t) -> f ^":"^tstr t) (Array.to_list v.vfields)) ^ ")"
+		"virtual(" ^ String.concat "," (List.map (fun (f,_,t) -> f ^":"^tstr ~stack:(v::stack) t) (Array.to_list v.vfields)) ^ ")"
 	| HDynObj ->
 		"dynobj"
 	| HAbstract (s,_) ->
@@ -340,7 +342,10 @@ let rec safe_cast t1 t2 =
 			p.pname = p2.pname || (match p.psuper with None -> false | Some p -> loop p)
 		in
 		loop p1
-	| _ -> tsame t1 t2
+	| HFun (args1,t1), HFun (args2,HVoid) when List.length args1 = List.length args2 ->
+		List.for_all2 tsame args1 args2
+	| _ ->
+		tsame t1 t2
 
 let to_utf8 str =
 	try
@@ -458,6 +463,8 @@ let rec to_type ctx t =
 		to_type ctx (!f())
 	| TFun (args, ret) ->
 		HFun (List.map (fun (_,_,t) -> to_type ctx t) args, to_type ctx ret)
+	| TAnon a when (match !(a.a_status) with Statics _ | EnumStatics _  -> true | _ -> false) ->
+		HType
 	| TAnon a ->
 		(try
 			(* can't use physical comparison in PMap since addresses might change in GC compact,
@@ -540,7 +547,18 @@ and class_type ctx c pl =
 	let c = if c.cl_extern then resolve_class ctx c pl else c in
 	try
 		PMap.find c.cl_path ctx.cached_types
-	with Not_found ->
+	with Not_found when c.cl_interface ->
+		let vp = {
+			vfields = [||];
+			vindex = PMap.empty;
+		} in
+		let t = HVirtual vp in
+		ctx.cached_types <- PMap.add c.cl_path t ctx.cached_types;
+		let fields = PMap.fold (fun cf acc -> (cf.cf_name,alloc_string ctx cf.cf_name,to_type ctx cf.cf_type) :: acc) c.cl_fields [] in
+		vp.vfields <- Array.of_list fields;
+		Array.iteri (fun i (n,_,_) -> vp.vindex <- PMap.add n i vp.vindex) vp.vfields;
+		t
+	| Not_found ->
 		let pname = s_type_path c.cl_path in
 		let p = {
 			pname = pname;
@@ -685,9 +703,6 @@ let jump_back ctx =
 let rtype ctx r =
 	DynArray.get ctx.m.mregs.arr r
 
-let resolve_field ctx p fname proto =
-	try fst (PMap.find fname p.pindex) with Not_found -> assert false
-
 let reg_int ctx v =
 	let r = alloc_tmp ctx HI32 in
 	op ctx (OInt (r,alloc_i32 ctx (Int32.of_int v)));
@@ -799,6 +814,31 @@ and cast_to ctx (r:reg) (t:ttype) p =
 	| _ ->
 		invalid()
 
+and object_access ctx eobj t f =
+	match t with
+	| HObj p ->
+		(try
+			let fid = fst (PMap.find f.cf_name p.pindex) in
+			if f.cf_kind = Method MethNormal then
+				AInstanceProto (eobj, fid)
+			else
+				AInstanceField (eobj, fid)
+		with Not_found ->
+			ADynamic (eobj, alloc_string ctx f.cf_name))
+	| HVirtual v ->
+		(try
+			let fid = PMap.find f.cf_name v.vindex in
+			if f.cf_kind = Method MethNormal then
+				AVirtualMethod (eobj, fid)
+			else
+				AInstanceField (eobj, fid)
+		with Not_found ->
+			ADynamic (eobj, alloc_string ctx f.cf_name))
+	| HDyn None ->
+		ADynamic (eobj, alloc_string ctx f.cf_name)
+	| _ ->
+		error ("Unsupported field access " ^ tstr t) eobj.epos
+
 and get_access ctx e =
 	match e.eexpr with
 	| TField (ethis, a) ->
@@ -808,23 +848,14 @@ and get_access ctx e =
 		| FStatic (c,({ cf_kind = Method _ } as f)), _ ->
 			AStaticFun (alloc_fid ctx c f)
 		| FClosure (Some (cdef,pl), ({ cf_kind = Method m } as f)), TInst (c,_)
-		| FInstance (cdef,pl,({ cf_kind = Method m } as f)), TInst (c,_) when m <> MethDynamic ->
-			if not (is_overriden ctx c f) then
-				AInstanceFun (ethis, alloc_fid ctx (resolve_class ctx cdef pl) f)
-			else (match class_type ctx cdef pl with
-			| HObj p -> AInstanceProto (ethis, resolve_field ctx p f.cf_name true)
-			| _ -> assert false)
+		| FInstance (cdef,pl,({ cf_kind = Method m } as f)), TInst (c,_) when m <> MethDynamic && not (c.cl_interface || is_overriden ctx c f) ->
+			AInstanceFun (ethis, alloc_fid ctx (resolve_class ctx cdef pl) f)
 		| FInstance (cdef,pl,f), _ | FClosure (Some (cdef,pl), f), _ ->
-			(match class_type ctx cdef pl with
-			| HObj p -> AInstanceField (ethis, resolve_field ctx p f.cf_name false)
-			| _ -> assert false)
+			object_access ctx ethis (class_type ctx cdef pl) f
 		| FClosure (None,_), _ ->
 			assert false
-		| FAnon cf, _ ->
-			(match to_type ctx ethis.etype with
-			| HVirtual v when cf.cf_kind = Method MethNormal -> AVirtualMethod (ethis, try PMap.find cf.cf_name v.vindex with Not_found -> assert false)
-			| HVirtual v -> (try AInstanceField (ethis, PMap.find cf.cf_name v.vindex) with Not_found -> ADynamic (ethis, alloc_string ctx cf.cf_name))
-			| _ -> assert false)
+		| FAnon f, _ ->
+			object_access ctx ethis (to_type ctx ethis.etype) f
 		| FDynamic name, _ ->
 			ADynamic (ethis, alloc_string ctx name)
 		| FEnum (_,ef), _ ->
@@ -1431,6 +1462,20 @@ and eval_expr ctx e =
 			unop r;
 			op ctx (OSetField (robj,f,r));
 			r2
+		| AGlobal g, Prefix ->
+			let r = alloc_tmp ctx (to_type ctx e.etype) in
+			op ctx (OGetGlobal (r,g));
+			unop r;
+			op ctx (OSetGlobal (g,r));
+			r
+		| AGlobal g, Postfix ->
+			let r = alloc_tmp ctx (to_type ctx e.etype) in
+			let r2 = alloc_tmp ctx (rtype ctx r) in
+			op ctx (OGetGlobal (r,g));
+			op ctx (OMov (r2,r));
+			unop r;
+			op ctx (OSetGlobal (g,r));
+			r2
 		| _ ->
 			error ("TODO " ^ s_expr (s_type (print_context())) e) e.epos
 		);
@@ -1532,7 +1577,16 @@ and eval_expr ctx e =
 	| TArray (a,i) ->
 		let ra = eval_null_check ctx a in
 		let ri = eval_to ctx i HI32 in
-		let at = (match follow a.etype with TInst ({ cl_path = [],"Array" },[t]) -> to_type ctx t | _ -> assert false) in
+		let ra, at = (match follow a.etype with
+			| TInst ({ cl_path = [],"Array" },[t]) -> ra, to_type ctx t
+			| t when t == t_dynamic ->
+				let at = e.etype in
+				let aa = alloc_tmp ctx (to_type ctx (ctx.com.basic.tarray at)) in
+				op ctx (OSafeCast (aa,ra));
+				aa, to_type ctx at
+			| _ ->
+				error ("Invalid array access on " ^ s_type (print_context()) a.etype) a.epos
+		) in
 		(match at with
 		| HI32 ->
 			let hbytes = alloc_tmp ctx HBytes in
@@ -1683,8 +1737,8 @@ and eval_expr ctx e =
 		ctx.m.mtrys <- ctx.m.mtrys + 1;
 		let tret = to_type ctx e.etype in
 		let result = alloc_tmp ctx tret in
-		let r = eval_to ctx etry tret in
-		if tret <> HVoid then op ctx (OMov (result,r));
+		let r = eval_expr ctx etry in
+		if tret <> HVoid then op ctx (OMov (result,cast_to ctx r tret etry.epos));
 		ctx.m.mtrys <- ctx.m.mtrys - 1;
 		op ctx (OEndTrap 0);
 		let j = jump ctx (fun n -> OJAlways n) in
@@ -1698,15 +1752,28 @@ and eval_expr ctx e =
 					op ctx (OMov (rv, rtrap))
 				else
 					error "Unsupported catch" ec.epos;
-				let r = eval_to ctx ec tret in
-				if tret <> HVoid then op ctx (OMov (result,r));
+				let r = eval_expr ctx ec in
+				if tret <> HVoid then op ctx (OMov (result,cast_to ctx r tret ec.epos));
 				if next = [] then [] else jump ctx (fun n -> OJAlways n) :: loop next
 		in
 		List.iter (fun j -> j()) (loop catches);
 		j();
 		result
-	| TTypeExpr _ | TCast (_,Some _) ->
-		error ("TODO " ^ s_expr (s_type (print_context())) e) e.epos
+	| TTypeExpr t ->
+		let r = alloc_tmp ctx HType in
+		op ctx (OType (r, (match t with
+			| TClassDecl c -> class_type ctx c []
+			| TEnumDecl e -> enum_type ctx e
+			| _ -> assert false)));
+		r
+	| TCast (ev,Some t) ->
+		let r = alloc_tmp ctx (to_type ctx (match t with TClassDecl c -> TInst (c,List.map (fun _ -> t_dynamic) c.cl_params) | _ -> assert false)) in
+		let re = eval_expr ctx ev in
+		if safe_cast (rtype ctx re) (rtype ctx r) then
+			op ctx (OMov (r,re))
+		else
+			error "TODO : safe-cast" e.epos;
+		r
 
 and build_capture_vars ctx f =
 	let ignored_vars = ref PMap.empty in
@@ -1874,7 +1941,7 @@ let generate_static ctx c f =
 
 let generate_member ctx c f =
 	match f.cf_kind with
-	| Var _ -> ()
+	| Var _ | Method MethDynamic -> ()
 	| Method m ->
 		ignore(make_fun ctx (alloc_fid ctx c f) (match f.cf_expr with Some { eexpr = TFunction f } -> f | _ -> error "Missing function body" f.cf_pos) (Some c) None);
 		if f.cf_name = "toString" && not (List.memq f c.cl_overrides) && not (PMap.mem "__string" c.cl_fields) then begin
@@ -1892,6 +1959,8 @@ let generate_enum ctx e =
 
 let generate_type ctx t =
 	match t with
+	| TClassDecl { cl_interface = true }->
+		()
 	| TClassDecl c when c.cl_extern ->
 		List.iter (fun f ->
 			List.iter (fun (name,args,pos) ->
@@ -2294,12 +2363,12 @@ let check code =
 	in
 	Array.iter (fun fd ->
 		if fd.findex >= Array.length ftypes then failwith ("Invalid function index " ^ string_of_int fd.findex);
-		if ftypes.(fd.findex) <> HVoid then failwith "Duplicate function bind";
+		if ftypes.(fd.findex) <> HVoid then failwith ("Duplicate function bind " ^ string_of_int fd.findex);
 		ftypes.(fd.findex) <- fd.ftype;
 	) code.functions;
 	Array.iter (fun (_,_,t,idx) ->
 		if idx >= Array.length ftypes then failwith ("Invalid native function index " ^ string_of_int idx);
-		if ftypes.(idx) <> HVoid then failwith "Duplicate function bind";
+		if ftypes.(idx) <> HVoid then failwith ("Duplicate native function bind " ^ string_of_int idx);
 		Hashtbl.add is_native_fun idx true;
 		ftypes.(idx) <- t
 	) code.natives;
@@ -3476,9 +3545,6 @@ let generate com =
 	) com.types;
 	List.iter (generate_type ctx) com.types;
 	let ep = generate_static_init ctx in
-	PMap.iter (fun (s,p) fid ->
-		if not (Hashtbl.mem ctx.defined_funs fid) then failwith ("Unresolved method " ^ s_type_path p ^ ":" ^ s)
-	) ctx.cfids.map;
 	let code = {
 		version = 1;
 		entrypoint = ep;
@@ -3491,6 +3557,9 @@ let generate com =
 	} in
 	Array.sort (fun (lib1,_,_,_) (lib2,_,_,_) -> lib1 - lib2) code.natives;
 	if Common.defined com Define.Dump then Std.output_file "dump/hlcode.txt" (dump code);
+	PMap.iter (fun (s,p) fid ->
+		if not (Hashtbl.mem ctx.defined_funs fid) then failwith ("Unresolved method " ^ s_type_path p ^ ":" ^ s)
+	) ctx.cfids.map;
 	check code;
 	let ch = IO.output_string() in
 	write_code ch code;

+ 100 - 0
std/hl/_std/Reflect.hx

@@ -0,0 +1,100 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+@:coreApi 
+class Reflect {
+
+	public static function hasField( o : Dynamic, field : String ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function field( o : Dynamic, field : String ) : Dynamic {
+		throw "TODO";
+		return null;
+	}
+
+	public static function setField( o : Dynamic, field : String, value : Dynamic ) : Void {
+		throw "TODO";
+	}
+
+	public static function getProperty( o : Dynamic, field : String ) : Dynamic {
+		throw "TODO";
+		return null;
+	}
+
+	public static function setProperty( o : Dynamic, field : String, value : Dynamic ) : Void {
+		throw "TODO";
+	}
+
+	public static function callMethod( o : Dynamic, func : haxe.Constraints.Function, args : Array<Dynamic> ) : Dynamic {
+		throw "TODO";
+		return null;
+	}
+
+	public static function fields( o : Dynamic ) : Array<String> {
+		throw "TODO";
+		return null;
+	}
+
+	public static function isFunction( f : Dynamic ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function compare<T>( a : T, b : T ) : Int {
+		throw "TODO";
+		return 0;
+	}
+
+	public static function compareMethods( f1 : Dynamic, f2 : Dynamic ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function isObject( v : Dynamic ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function isEnumValue( v : Dynamic ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function deleteField( o : Dynamic, field : String ) : Bool {
+		throw "TODO";
+		return false;
+	}
+
+	public static function copy<T>( o : T ) : T {
+		throw "TODO";
+		return null;
+	}
+
+	@:overload(function( f : Array<Dynamic> -> Void ) : Dynamic {})
+	public static function makeVarArgs( f : Array<Dynamic> -> Dynamic ) : Dynamic {
+		throw "TODO";
+		return null;
+	}
+
+}

+ 74 - 0
std/hl/_std/haxe/ds/IntMap.hx

@@ -0,0 +1,74 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package haxe.ds;
+
+@:coreApi
+class IntMap<T> implements haxe.Constraints.IMap<Int,T> {
+
+	var h : hl.types.NativeIntMap;
+
+	public function new() : Void {
+		h = new hl.types.NativeIntMap();
+	}
+
+	public function set( key : Int, value : T ) : Void {
+		@:privateAccess h.set(key,value);
+	}
+
+	public function get( key : Int ) : Null<T> {
+		return @:privateAccess h.get(key);
+	}
+
+	public function exists( key : Int ) : Bool {
+		return @:privateAccess h.exists(key);
+	}
+
+	public function remove( key : Int ) : Bool {
+		return @:privateAccess h.remove(key);
+	}
+
+	public function keys() : Iterator<Int> {
+		return new hl.types.NativeArray.NativeArrayIterator<Int>(h.keysArray());
+	}
+
+	public function iterator() : Iterator<T> {
+		return h.iterator();
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		var keys = h.keysArray();
+		var values = h.valuesArray();
+		s.addChar('{'.code);
+		for( i in 0...keys.length ) {
+			if( i > 0 )
+				s.add(", ");
+			s.add(keys[i]);
+			s.add(" => ");
+			s.add(values[i]);
+		}
+		s.addChar('}'.code);
+		return s.toString();
+	}
+
+}

+ 74 - 0
std/hl/_std/haxe/ds/ObjectMap.hx

@@ -0,0 +1,74 @@
+/*
+ * Copyright (C)2005-2012 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+package haxe.ds;
+
+@:coreApi
+class ObjectMap<K:{},T> implements haxe.Constraints.IMap<K,T> {
+
+	var h : hl.types.NativeObjectMap;
+
+	public function new() : Void {
+		h = new hl.types.NativeObjectMap();
+	}
+
+	public function set( key : K, value : T ) : Void {
+		@:privateAccess h.set(key,value);
+	}
+
+	public function get( key : K ) : Null<T> {
+		return @:privateAccess h.get(key);
+	}
+
+	public function exists( key : K ) : Bool {
+		return @:privateAccess h.exists(key);
+	}
+
+	public function remove( key : K ) : Bool {
+		return @:privateAccess h.remove(key);
+	}
+
+	public function keys() : Iterator<K> {
+		return new hl.types.NativeArray.NativeArrayIterator<K>(cast h.keysArray());
+	}
+
+	public function iterator() : Iterator<T> {
+		return h.iterator();
+	}
+
+	public function toString() : String {
+		var s = new StringBuf();
+		var keys = h.keysArray();
+		var values = h.valuesArray();
+		s.addChar('{'.code);
+		for( i in 0...keys.length ) {
+			if( i > 0 )
+				s.add(", ");
+			s.add(keys[i]);
+			s.add(" => ");
+			s.add(values[i]);
+		}
+		s.addChar('}'.code);
+		return s.toString();
+	}
+
+}

+ 20 - 0
std/hl/types/NativeArray.hx

@@ -1,5 +1,25 @@
 package hl.types;
 
+@:generic class NativeArrayIterator<T> {
+	var arr : NativeArray<T>;
+	var pos : Int;
+	var length : Int;
+	
+	public inline function new(arr:NativeArray<T>) {
+		this.arr = arr;
+		pos = 0;
+		length = arr.length;
+	}
+	
+	public inline function hasNext() {
+		return pos < length;
+	}
+	
+	public inline function next() {
+		return arr[pos++];
+	}
+}
+
 @:coreType abstract NativeArray<T> {
 	public var length(get,never):Int;	
 	@:extern public inline function new( length : Int ) {

+ 1 - 21
std/hl/types/NativeBytesMap.hx

@@ -1,25 +1,5 @@
 package hl.types;
 
-class NativeBytesMapIterator {
-	var arr : NativeArray<Dynamic>;
-	var pos : Int;
-	var length : Int;
-	
-	public inline function new(h:NativeBytesMap) {
-		this.arr = h.valuesArray();
-		pos = 0;
-		length = arr.length;
-	}
-	
-	public inline function hasNext() {
-		return pos < length;
-	}
-	
-	public inline function next() {
-		return arr[pos++];
-	}
-}
-
 abstract NativeBytesMap(NativeAbstract<"BytesMap">) {
 
 	@:extern public inline function new() {
@@ -60,7 +40,7 @@ abstract NativeBytesMap(NativeAbstract<"BytesMap">) {
 	}
 
 	@:extern public inline function iterator() {
-		return new NativeBytesMapIterator(cast this);
+		return new NativeArray.NativeArrayIterator<Dynamic>(valuesArray());
 	}
 
 }

+ 46 - 0
std/hl/types/NativeIntMap.hx

@@ -0,0 +1,46 @@
+package hl.types;
+
+abstract NativeIntMap(NativeAbstract<"IntMap">) {
+
+	@:extern public inline function new() {
+		this = alloc();
+	}
+	
+	@:hlNative("std","hialloc") function alloc() : NativeAbstract<"IntMap"> {
+		return null;
+	}
+
+	@:hlNative("std","hiset")
+	public function set( key : Int, value : Dynamic ) {
+	}
+
+	@:hlNative("std","hiexists")
+	public function exists( key : Int ) : Bool {
+		return false;
+	}
+	
+	@:hlNative("std","higet")
+	public function get( key : Int ) : Dynamic {
+		return null;
+	}
+
+	@:hlNative("std","hiremove")
+	public function remove( key : Int ) : Bool {
+		return false;
+	}
+
+	@:hlNative("std","hikeys")
+	public function keysArray() : NativeArray<Int> {
+		return null;
+	}
+
+	@:hlNative("std","hivalues")
+	public function valuesArray() : NativeArray<Dynamic> {
+		return null;
+	}
+
+	@:extern public inline function iterator() {
+		return new NativeArray.NativeArrayIterator<Dynamic>(valuesArray());
+	}
+
+}

+ 46 - 0
std/hl/types/NativeObjectMap.hx

@@ -0,0 +1,46 @@
+package hl.types;
+
+abstract NativeObjectMap(NativeAbstract<"ObjectMap">) {
+
+	@:extern public inline function new() {
+		this = alloc();
+	}
+	
+	@:hlNative("std","hoalloc") function alloc() : NativeAbstract<"ObjectMap"> {
+		return null;
+	}
+
+	@:hlNative("std","hoset")
+	public function set( key : Dynamic, value : Dynamic ) {
+	}
+
+	@:hlNative("std","hoexists")
+	public function exists( key : Dynamic ) : Bool {
+		return false;
+	}
+	
+	@:hlNative("std","hoget")
+	public function get( key : Dynamic ) : Dynamic {
+		return null;
+	}
+
+	@:hlNative("std","horemove")
+	public function remove( key : Dynamic ) : Bool {
+		return false;
+	}
+
+	@:hlNative("std","hokeys")
+	public function keysArray() : NativeArray<Dynamic> {
+		return null;
+	}
+
+	@:hlNative("std","hovalues")
+	public function valuesArray() : NativeArray<Dynamic> {
+		return null;
+	}
+
+	@:extern public inline function iterator() {
+		return new NativeArray.NativeArrayIterator<Dynamic>(valuesArray());
+	}
+
+}