Browse Source

secure hash

Nicolas Cannasse 17 years ago
parent
commit
945034dc34
4 changed files with 66 additions and 50 deletions
  1. 1 0
      doc/CHANGES.txt
  2. 11 4
      genswf8.ml
  3. 41 36
      genswf9.ml
  4. 13 10
      std/Hash.hx

+ 1 - 0
doc/CHANGES.txt

@@ -17,6 +17,7 @@
 	use flash9 fast switch for enums
 	use flash9 fast switch for enums
 	always use match for enums (no switch even if constant)
 	always use match for enums (no switch even if constant)
 	fixed DateTools.format %I and %l in Flash/JS
 	fixed DateTools.format %I and %l in Flash/JS
+	securized Hash for JS and Flash
 
 
 2007-10-31: 1.16
 2007-10-31: 1.16
 	use _sans font for default flash traces (better Linux support)
 	use _sans font for default flash traces (better Linux support)

+ 11 - 4
genswf8.ml

@@ -846,13 +846,14 @@ and gen_call ctx e el =
 		push ctx [VInt nargs];
 		push ctx [VInt nargs];
 		let k = gen_access ctx true e in
 		let k = gen_access ctx true e in
 		new_call ctx k nargs
 		new_call ctx k nargs
-	| TLocal "__keys__", [e] ->
+	| TLocal "__keys__", [e2]
+	| TLocal "__hkeys__", [e2] ->
 		let r = alloc_tmp ctx in
 		let r = alloc_tmp ctx in
 		push ctx [VInt 0; VStr ("Array",true)];
 		push ctx [VInt 0; VStr ("Array",true)];
 		new_call ctx VarStr 0;
 		new_call ctx VarStr 0;
 		set_tmp ctx r;
 		set_tmp ctx r;
 		write ctx APop;
 		write ctx APop;
-		gen_expr ctx true e;
+		gen_expr ctx true e2;
 		write ctx AEnum2;
 		write ctx AEnum2;
 		ctx.stack_size <- ctx.stack_size + 1; (* fake *)
 		ctx.stack_size <- ctx.stack_size + 1; (* fake *)
 		let loop = pos ctx in
 		let loop = pos ctx in
@@ -860,7 +861,13 @@ and gen_call ctx e el =
 		push ctx [VNull];
 		push ctx [VNull];
 		write ctx AEqual;
 		write ctx AEqual;
 		let jump_end = cjmp ctx in
 		let jump_end = cjmp ctx in
-		push ctx [VReg 0; VInt 1];
+		if e.eexpr = TLocal "__hkeys__" then begin			
+			push ctx [VInt 1; VInt 1; VReg 0; VStr ("substr",true)];
+			call ctx VarObj 1;
+		end else begin
+			push ctx [VReg 0];
+		end;
+		push ctx [VInt 1];
 		get_tmp ctx r;
 		get_tmp ctx r;
 		push ctx [VStr ("push",true)];
 		push ctx [VStr ("push",true)];
 		call ctx VarObj 1;
 		call ctx VarObj 1;
@@ -868,7 +875,7 @@ and gen_call ctx e el =
 		loop false;
 		loop false;
 		jump_end();
 		jump_end();
 		get_tmp ctx r;
 		get_tmp ctx r;
-		free_tmp ctx r e.epos;
+		free_tmp ctx r e2.epos;
 	| TLocal "__unprotect__", [{ eexpr = TConst (TString s) }] ->
 	| TLocal "__unprotect__", [{ eexpr = TConst (TString s) }] ->
 		push ctx [VStr (s,false)]
 		push ctx [VStr (s,false)]
 	| _ , _ ->
 	| _ , _ ->

+ 41 - 36
genswf9.ml

@@ -219,23 +219,23 @@ let classify ctx t =
 	| TLazy _ ->
 	| TLazy _ ->
 		assert false
 		assert false
 
 
-let ident ctx i = type_path ctx ([],i)
+let ident i = HMPath ([],i)
 
 
 let as3 p =
 let as3 p =
 	HMName (p,HNNamespace "http://adobe.com/AS3/2006/builtin")
 	HMName (p,HNNamespace "http://adobe.com/AS3/2006/builtin")
 
 
-let property ctx p t =
+let property p t =
 	match follow t with
 	match follow t with
 	| TInst ({ cl_path = [],"Array" },_) ->
 	| TInst ({ cl_path = [],"Array" },_) ->
 		(match p with
 		(match p with
-		| "length" | "copy" | "insert" | "remove" | "iterator" -> ident ctx p
+		| "length" | "copy" | "insert" | "remove" | "iterator" -> ident p
 		| _ -> as3 p);
 		| _ -> as3 p);
 	| TInst ({ cl_path = [],"String" },_) ->
 	| TInst ({ cl_path = [],"String" },_) ->
 		(match p with
 		(match p with
-		| "length" | "charCodeAt" (* use haXe version *) -> ident ctx p
+		| "length" | "charCodeAt" (* use haXe version *) -> ident p
 		| _ -> as3 p);
 		| _ -> as3 p);
 	| _ ->
 	| _ ->
-		ident ctx p
+		ident p
 
 
 let default_infos() =
 let default_infos() =
 	{
 	{
@@ -524,7 +524,7 @@ let begin_fun ctx args tret el stat p =
 					hltc_name = None;
 					hltc_name = None;
 				}
 				}
 			) (List.rev ctx.trys));
 			) (List.rev ctx.trys));
-			hlf_locals = Array.of_list (List.map (fun (id,name,t) -> ident ctx name, Some (type_id ctx t), id) ctx.block_vars);
+			hlf_locals = Array.of_list (List.map (fun (id,name,t) -> ident name, Some (type_id ctx t), id) ctx.block_vars);
 		} in
 		} in
 		let mt = {
 		let mt = {
 			hlmt_mark = As3hlparse.alloc_mark();
 			hlmt_mark = As3hlparse.alloc_mark();
@@ -609,7 +609,7 @@ let gen_access ctx e (forset : 'a) : 'a access =
 	| TLocal i ->
 	| TLocal i ->
 		gen_local_access ctx i e.epos forset
 		gen_local_access ctx i e.epos forset
 	| TField (e1,f) ->
 	| TField (e1,f) ->
-		let id = property ctx f e1.etype in
+		let id = property f e1.etype in
 		(match e1.eexpr with
 		(match e1.eexpr with
 		| TConst TThis when not ctx.in_static -> write ctx (HFindPropStrict id)
 		| TConst TThis when not ctx.in_static -> write ctx (HFindPropStrict id)
 		| _ -> gen_expr ctx true e1);
 		| _ -> gen_expr ctx true e1);
@@ -646,7 +646,7 @@ let rec gen_expr_content ctx retval e =
 	| TEnumField (e,s) ->
 	| TEnumField (e,s) ->
 		let id = type_path ctx e.e_path in
 		let id = type_path ctx e.e_path in
 		write ctx (HGetLex id);
 		write ctx (HGetLex id);
-		write ctx (HGetProp (ident ctx s));
+		write ctx (HGetProp (ident s));
 	| TObjectDecl fl ->
 	| TObjectDecl fl ->
 		List.iter (fun (name,e) ->
 		List.iter (fun (name,e) ->
 			write ctx (HString name);
 			write ctx (HString name);
@@ -794,11 +794,11 @@ let rec gen_expr_content ctx retval e =
 		let here, start = jump_back ctx in
 		let here, start = jump_back ctx in
 		here();
 		here();
 		write ctx (HReg r.rid);
 		write ctx (HReg r.rid);
-		write ctx (HCallProperty (ident ctx "hasNext",0));
+		write ctx (HCallProperty (ident "hasNext",0));
 		let jend = jump ctx J3False in
 		let jend = jump ctx J3False in
 		let acc = gen_local_access ctx v e.epos Write in
 		let acc = gen_local_access ctx v e.epos Write in
 		write ctx (HReg r.rid);
 		write ctx (HReg r.rid);
-		write ctx (HCallProperty (ident ctx "next",0));
+		write ctx (HCallProperty (ident "next",0));
 		setvar ctx acc false;
 		setvar ctx acc false;
 		gen_expr ctx false e;
 		gen_expr ctx false e;
 		start J3Always;
 		start J3Always;
@@ -870,9 +870,9 @@ let rec gen_expr_content ctx retval e =
 		let rindex = alloc_reg ctx KInt in
 		let rindex = alloc_reg ctx KInt in
 		gen_expr ctx true e0;
 		gen_expr ctx true e0;
 		write ctx HDup;
 		write ctx HDup;
-		write ctx (HGetProp (ident ctx "index"));
+		write ctx (HGetProp (ident "index"));
 		set_reg ctx rindex;
 		set_reg ctx rindex;
-		write ctx (HGetProp (ident ctx "params"));
+		write ctx (HGetProp (ident "params"));
 		set_reg ctx rparams;
 		set_reg ctx rparams;
 		let branch = begin_branch ctx in
 		let branch = begin_branch ctx in
 		let jswitch = jump ctx J3Always in
 		let jswitch = jump ctx J3Always in
@@ -951,7 +951,8 @@ and gen_call ctx retval e el =
 	| TLocal "__float__", [e] ->
 	| TLocal "__float__", [e] ->
 		gen_expr ctx true e;
 		gen_expr ctx true e;
 		write ctx HToNumber
 		write ctx HToNumber
-	| TLocal "__keys__" , [e] ->
+	| TLocal "__hkeys__" , [e2]
+	| TLocal "__keys__" , [e2] ->
 		let racc = alloc_reg ctx (KType (type_path ctx ([],"Array"))) in
 		let racc = alloc_reg ctx (KType (type_path ctx ([],"Array"))) in
 		let rcounter = alloc_reg ctx KInt in
 		let rcounter = alloc_reg ctx KInt in
 		let rtmp = alloc_reg ctx KDynamic in
 		let rtmp = alloc_reg ctx KDynamic in
@@ -959,14 +960,18 @@ and gen_call ctx retval e el =
 		set_reg ctx rcounter;
 		set_reg ctx rcounter;
 		write ctx (HArray 0);
 		write ctx (HArray 0);
 		set_reg ctx racc;
 		set_reg ctx racc;
-		gen_expr ctx true e;
+		gen_expr ctx true e2;
 		set_reg ctx rtmp;
 		set_reg ctx rtmp;
 		let start, loop = jump_back ctx in
 		let start, loop = jump_back ctx in
 		write ctx (HReg racc.rid);
 		write ctx (HReg racc.rid);
 		write ctx (HReg rtmp.rid);
 		write ctx (HReg rtmp.rid);
 		write ctx (HReg rcounter.rid);
 		write ctx (HReg rcounter.rid);
 		write ctx HForIn;
 		write ctx HForIn;
-		write ctx (HCallPropVoid (ident ctx "push",1));
+		if e.eexpr = TLocal "__hkeys__" then begin
+			write ctx (HSmallInt 1);
+			write ctx (HCallProperty (as3 "substr",1));
+		end;
+		write ctx (HCallPropVoid (as3 "push",1));
 		start();
 		start();
 		write ctx (HNext (rtmp.rid,rcounter.rid));
 		write ctx (HNext (rtmp.rid,rcounter.rid));
 		loop J3True;
 		loop J3True;
@@ -1003,12 +1008,12 @@ and gen_call ctx retval e el =
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
 		write ctx (HConstructSuper (List.length el));
 		write ctx (HConstructSuper (List.length el));
 	| TField ({ eexpr = TConst TSuper },f) , _ ->
 	| TField ({ eexpr = TConst TSuper },f) , _ ->
-		let id = ident ctx f in
+		let id = ident f in
 		write ctx (HFindPropStrict id);
 		write ctx (HFindPropStrict id);
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
 		write ctx (HCallSuper (id,List.length el));
 		write ctx (HCallSuper (id,List.length el));
 	| TField ({ eexpr = TConst TThis },f) , _ when not ctx.in_static ->
 	| TField ({ eexpr = TConst TThis },f) , _ when not ctx.in_static ->
-		let id = ident ctx f in
+		let id = ident f in
 		write ctx (HFindPropStrict id);
 		write ctx (HFindPropStrict id);
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
 		write ctx (if retval then HCallProperty (id,List.length el) else HCallPropVoid (id,List.length el));
 		write ctx (if retval then HCallProperty (id,List.length el) else HCallPropVoid (id,List.length el));
@@ -1016,14 +1021,14 @@ and gen_call ctx retval e el =
 		gen_expr ctx true e1;
 		gen_expr ctx true e1;
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
 		if not retval then
 		if not retval then
-			write ctx (HCallPropVoid (property ctx f e1.etype,List.length el))
+			write ctx (HCallPropVoid (property f e1.etype,List.length el))
 		else
 		else
 			let coerce() =
 			let coerce() =
 				match follow e.etype with
 				match follow e.etype with
 				| TFun (_,r) -> coerce ctx (classify ctx r)
 				| TFun (_,r) -> coerce ctx (classify ctx r)
 				| _ -> ()
 				| _ -> ()
 			in
 			in
-			write ctx (HCallProperty (property ctx f e1.etype,List.length el));
+			write ctx (HCallProperty (property f e1.etype,List.length el));
 			(match follow e1.etype with
 			(match follow e1.etype with
 			| TInst ({ cl_path = [],"Array" },_) ->
 			| TInst ({ cl_path = [],"Array" },_) ->
 				(match f with
 				(match f with
@@ -1044,7 +1049,7 @@ and gen_call ctx retval e el =
 		let id = type_path ctx e.e_path in
 		let id = type_path ctx e.e_path in
 		write ctx (HGetLex id);
 		write ctx (HGetLex id);
 		List.iter (gen_expr ctx true) el;
 		List.iter (gen_expr ctx true) el;
-		write ctx (HCallProperty (ident ctx f,List.length el));
+		write ctx (HCallProperty (ident f,List.length el));
 	| _ ->
 	| _ ->
 		gen_expr ctx true e;
 		gen_expr ctx true e;
 		write ctx HGetGlobalScope;
 		write ctx HGetGlobalScope;
@@ -1240,7 +1245,7 @@ let generate_construct ctx fdata cfields =
 	(* make all args optional to allow no-param constructor *)
 	(* make all args optional to allow no-param constructor *)
 	let f = begin_fun ctx (List.map (fun (a,o,t) -> a,true,t) fdata.tf_args) fdata.tf_type [fdata.tf_expr] false fdata.tf_expr.epos in
 	let f = begin_fun ctx (List.map (fun (a,o,t) -> a,true,t) fdata.tf_args) fdata.tf_type [fdata.tf_expr] false fdata.tf_expr.epos in
 	(* if skip_constructor, then returns immediatly *)
 	(* if skip_constructor, then returns immediatly *)
-	let id = ident ctx "skip_constructor" in
+	let id = ident "skip_constructor" in
 	getvar ctx (VGlobal (type_path ctx ([],ctx.boot)));
 	getvar ctx (VGlobal (type_path ctx ([],ctx.boot)));
 	getvar ctx (VId id);
 	getvar ctx (VId id);
 	let j = jump ctx J3False in
 	let j = jump ctx J3False in
@@ -1250,7 +1255,7 @@ let generate_construct ctx fdata cfields =
 	PMap.iter (fun _ f ->
 	PMap.iter (fun _ f ->
 		match f.cf_expr with
 		match f.cf_expr with
 		| Some { eexpr = TFunction fdata } when f.cf_set = NormalAccess ->
 		| Some { eexpr = TFunction fdata } when f.cf_set = NormalAccess ->
-			let id = ident ctx f.cf_name in
+			let id = ident f.cf_name in
 			write ctx (HFindProp id);
 			write ctx (HFindProp id);
 			write ctx (HFunction (generate_method ctx fdata false));
 			write ctx (HFunction (generate_method ctx fdata false));
 			write ctx (HInitProp id);
 			write ctx (HInitProp id);
@@ -1276,7 +1281,7 @@ let generate_class_init ctx c hc =
 		| Some { eexpr = TFunction fdata } when f.cf_set = NormalAccess ->
 		| Some { eexpr = TFunction fdata } when f.cf_set = NormalAccess ->
 			write ctx HDup;
 			write ctx HDup;
 			write ctx (HFunction (generate_method ctx fdata true));
 			write ctx (HFunction (generate_method ctx fdata true));
-			write ctx (HInitProp (ident ctx f.cf_name));
+			write ctx (HInitProp (ident f.cf_name));
 		| _ -> ()
 		| _ -> ()
 	) c.cl_ordered_statics;
 	) c.cl_ordered_statics;
 	if not c.cl_interface then write ctx HPopScope;
 	if not c.cl_interface then write ctx HPopScope;
@@ -1397,7 +1402,7 @@ let generate_class ctx c =
 		| None -> acc
 		| None -> acc
 		| Some k ->
 		| Some k ->
 			{
 			{
-				hlf_name = ident ctx f.cf_name;
+				hlf_name = ident f.cf_name;
 				hlf_slot = 0;
 				hlf_slot = 0;
 				hlf_kind = k;
 				hlf_kind = k;
 				hlf_metas = None;
 				hlf_metas = None;
@@ -1424,7 +1429,7 @@ let generate_class ctx c =
 			let count = (match k with HFMethod _ -> st_meth_count | HFVar _ -> st_field_count | _ -> assert false) in
 			let count = (match k with HFMethod _ -> st_meth_count | HFVar _ -> st_field_count | _ -> assert false) in
 			incr count;
 			incr count;
 			{
 			{
-				hlf_name = ident ctx f.cf_name;
+				hlf_name = ident f.cf_name;
 				hlf_slot = !count;
 				hlf_slot = !count;
 				hlf_kind = k;
 				hlf_kind = k;
 				hlf_metas = None;
 				hlf_metas = None;
@@ -1435,9 +1440,9 @@ let generate_class ctx c =
 let generate_enum ctx e =
 let generate_enum ctx e =
 	let name_id = type_path ctx e.e_path in
 	let name_id = type_path ctx e.e_path in
 	let f = begin_fun ctx [("tag",false,t_string);("index",false,t_int);("params",false,mk_mono())] t_void [ethis] false e.e_pos in
 	let f = begin_fun ctx [("tag",false,t_string);("index",false,t_int);("params",false,mk_mono())] t_void [ethis] false e.e_pos in
-	let tag_id = ident ctx "tag" in
-	let index_id = ident ctx "index" in
-	let params_id = ident ctx "params" in
+	let tag_id = ident "tag" in
+	let index_id = ident "index" in
+	let params_id = ident "params" in
 	write ctx (HFindProp tag_id);
 	write ctx (HFindProp tag_id);
 	write ctx (HReg 1);
 	write ctx (HReg 1);
 	write ctx (HInitProp tag_id);
 	write ctx (HInitProp tag_id);
@@ -1452,14 +1457,14 @@ let generate_enum ctx e =
 	let f = begin_fun ctx [] t_string [] true e.e_pos in
 	let f = begin_fun ctx [] t_string [] true e.e_pos in
 	write ctx (HGetLex (type_path ctx ([],ctx.boot)));
 	write ctx (HGetLex (type_path ctx ([],ctx.boot)));
 	write ctx HThis;
 	write ctx HThis;
-	write ctx (HCallProperty (ident ctx "enum_to_string",1));
+	write ctx (HCallProperty (ident "enum_to_string",1));
 	write ctx HRet;
 	write ctx HRet;
 	let tostring = f() in
 	let tostring = f() in
 	let st_count = ref 0 in
 	let st_count = ref 0 in
 	let constrs = PMap.fold (fun f acc ->
 	let constrs = PMap.fold (fun f acc ->
 		incr st_count;
 		incr st_count;
 		{
 		{
-			hlf_name = ident ctx f.ef_name;
+			hlf_name = ident f.ef_name;
 			hlf_slot = !st_count;
 			hlf_slot = !st_count;
 			hlf_kind = (match f.ef_type with
 			hlf_kind = (match f.ef_type with
 				| TFun (args,_) ->
 				| TFun (args,_) ->
@@ -1498,9 +1503,9 @@ let generate_enum ctx e =
 			{ hlf_name = tag_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
 			{ hlf_name = tag_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
 			{ hlf_name = index_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
 			{ hlf_name = index_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
 			{ hlf_name = params_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
 			{ hlf_name = params_id; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; }; hlf_metas = None };
-			{ hlf_name = ident ctx "__enum__"; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVBool true; hlv_const = true }; hlf_metas = None };
+			{ hlf_name = ident "__enum__"; hlf_slot = 0; hlf_kind = HFVar { hlv_type = None; hlv_value = HVBool true; hlv_const = true }; hlf_metas = None };
 			{
 			{
-				hlf_name = ident ctx "toString";
+				hlf_name = ident "toString";
 				hlf_slot = 0;
 				hlf_slot = 0;
 				hlf_kind = HFMethod {
 				hlf_kind = HFMethod {
 					hlm_type = tostring;
 					hlm_type = tostring;
@@ -1513,12 +1518,12 @@ let generate_enum ctx e =
 		|];
 		|];
 		hlc_static_construct = empty_method ctx e.e_pos;
 		hlc_static_construct = empty_method ctx e.e_pos;
 		hlc_static_fields = Array.of_list ({
 		hlc_static_fields = Array.of_list ({
-			hlf_name = ident ctx "__isenum";
+			hlf_name = ident "__isenum";
 			hlf_slot = !st_count + 2;
 			hlf_slot = !st_count + 2;
 			hlf_kind = HFVar { hlv_type = None; hlv_value = HVBool true; hlv_const = true; };
 			hlf_kind = HFVar { hlv_type = None; hlv_value = HVBool true; hlv_const = true; };
 			hlf_metas = None;
 			hlf_metas = None;
 		} :: {
 		} :: {
-			hlf_name = ident ctx "__constructs__";
+			hlf_name = ident "__constructs__";
 			hlf_slot = !st_count + 1;
 			hlf_slot = !st_count + 1;
 			hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; };
 			hlf_kind = HFVar { hlv_type = None; hlv_value = HVNone; hlv_const = false; };
 			hlf_metas = None;
 			hlf_metas = None;
@@ -1555,7 +1560,7 @@ let generate_resources ctx hres =
 		setvar ctx VArray false;
 		setvar ctx VArray false;
 	) hres;
 	) hres;
 	write ctx (HReg r.rid);
 	write ctx (HReg r.rid);
-	write ctx (HInitProp (ident ctx "__res"))
+	write ctx (HInitProp (ident "__res"))
 
 
 let generate_inits ctx types hres =
 let generate_inits ctx types hres =
 	let f = begin_fun ctx [] t_void [ethis] false null_pos in
 	let f = begin_fun ctx [] t_void [ethis] false null_pos in
@@ -1606,7 +1611,7 @@ let generate_inits ctx types hres =
 	) types;
 	) types;
 	write ctx HRetVoid;
 	write ctx HRetVoid;
 	write ctx (HFunction (finit()));
 	write ctx (HFunction (finit()));
-	write ctx (HInitProp (ident ctx "init"));
+	write ctx (HInitProp (ident "init"));
 
 
 	(* generate resources *)
 	(* generate resources *)
 	generate_resources ctx hres;
 	generate_resources ctx hres;

+ 13 - 10
std/Hash.hx

@@ -57,9 +57,9 @@ class Hash<T> {
 	**/
 	**/
 	public function set( key : String, value : T ) : Void {
 	public function set( key : String, value : T ) : Void {
 		#if flash
 		#if flash
-		untyped h[key] = value;
+		untyped h["$"+key] = value;
 		#else js
 		#else js
-		untyped h[key] = value;
+		untyped h["$"+key] = value;
 		#else neko
 		#else neko
 		untyped __dollar__hset(h,key.__s,value,null);
 		untyped __dollar__hset(h,key.__s,value,null);
 		#else error
 		#else error
@@ -71,9 +71,9 @@ class Hash<T> {
 	**/
 	**/
 	public function get( key : String ) : Null<T> {
 	public function get( key : String ) : Null<T> {
 		#if flash
 		#if flash
-		return untyped h[key];
+		return untyped h["$"+key];
 		#else js
 		#else js
-		return untyped h[key];
+		return untyped h["$"+key];
 		#else neko
 		#else neko
 		return untyped __dollar__hget(h,key.__s,null);
 		return untyped __dollar__hget(h,key.__s,null);
 		#else error
 		#else error
@@ -87,11 +87,12 @@ class Hash<T> {
 	**/
 	**/
 	public function exists( key : String ) : Bool {
 	public function exists( key : String ) : Bool {
 		#if flash9
 		#if flash9
-		return untyped h.hasOwnProperty(key);
+		return untyped h.hasOwnProperty("$"+key);
 		#else flash
 		#else flash
-		return untyped h["hasOwnProperty"](key);
+		return untyped h["hasOwnProperty"]("$"+key);
 		#else js
 		#else js
 		try {
 		try {
+			key = "$"+key;
 			return untyped this.hasOwnProperty.call(h,key);
 			return untyped this.hasOwnProperty.call(h,key);
 		}catch(e:Dynamic){
 		}catch(e:Dynamic){
 			untyped __js__("
 			untyped __js__("
@@ -112,17 +113,19 @@ class Hash<T> {
 	**/
 	**/
 	public function remove( key : String ) : Bool {
 	public function remove( key : String ) : Bool {
 		#if flash9
 		#if flash9
+		key = "$"+key;
 		if( untyped !h.hasOwnProperty(key) ) return false;
 		if( untyped !h.hasOwnProperty(key) ) return false;
 		untyped __delete__(h,key);
 		untyped __delete__(h,key);
 		return true;
 		return true;
 		#else flash
 		#else flash
+		key = "$"+key;
 		if( untyped !h["hasOwnProperty"](key) ) return false;
 		if( untyped !h["hasOwnProperty"](key) ) return false;
 		untyped __delete__(h,key);
 		untyped __delete__(h,key);
 		return true;
 		return true;
 		#else js
 		#else js
 		if( !exists(key) )
 		if( !exists(key) )
 			return false;
 			return false;
-		untyped __js__("delete")(h[key]);
+		untyped __js__("delete")(h["$"+key]);
 		return true;
 		return true;
 		#else neko
 		#else neko
 		return untyped __dollar__hremove(h,key.__s,null);
 		return untyped __dollar__hremove(h,key.__s,null);
@@ -135,14 +138,14 @@ class Hash<T> {
 	**/
 	**/
 	public function keys() : Iterator<String> {
 	public function keys() : Iterator<String> {
 		#if flash9
 		#if flash9
-		return untyped (__keys__(h)).iterator();
+		return untyped (__hkeys__(h)).iterator();
 		#else flash
 		#else flash
-		return untyped (__keys__(h))["iterator"]();
+		return untyped (__hkeys__(h))["iterator"]();
 		#else js
 		#else js
 		var a = new Array<String>();
 		var a = new Array<String>();
 		untyped __js__("
 		untyped __js__("
 			for(var i in this.h)
 			for(var i in this.h)
-				a.push(i);
+				a.push(i.substr(1));
 		");
 		");
 		return a.iterator();
 		return a.iterator();
 		#else neko
 		#else neko