Browse Source

slightly change enum initialization

Nicolas Cannasse 8 years ago
parent
commit
aa690c4e1a
5 changed files with 55 additions and 38 deletions
  1. 16 24
      src/generators/genhl.ml
  2. 13 0
      src/generators/hlinterp.ml
  3. 0 14
      std/hl/BaseType.hx
  4. 8 0
      std/hl/Type.hx
  5. 18 0
      std/hl/_std/Type.hx

+ 16 - 24
src/generators/genhl.ml

@@ -3088,54 +3088,46 @@ let generate_static_init ctx types main =
 
 			| TEnumDecl e when not e.e_extern ->
 
-				let t = enum_class ctx e in
-				let g = alloc_global ctx (match t with HObj o -> o.pname | _ -> assert false) t in
+				let et = enum_class ctx e in
+				let t = enum_type ctx e in
+
+				let ret = alloc_tmp ctx HType in
+				op ctx (OType (ret, et));
+				hold ctx ret;
+				let rt = alloc_tmp ctx HType in
+				op ctx (OType (rt, t));
+				let r = alloc_tmp ctx (class_type ctx ctx.base_enum [] false) in
+				op ctx (OCall2 (r, alloc_fun_path ctx ([],"Type") "initEnum", ret, rt));
+				free ctx ret;
 
 				let index name =
-					match t with
+					match et with
 					| HObj o ->
 						fst (try get_index name o with Not_found -> assert false)
 					| _ ->
 						assert false
 				in
-				let r = alloc_tmp ctx t in
-				let rt = alloc_tmp ctx HType in
-				op ctx (ONew r);
-
-				let max_val = ref (-1) in
-				PMap.iter (fun _ c ->
-					match follow c.ef_type with
-					| TFun _ -> ()
-					| _ -> if c.ef_index > !max_val then max_val := c.ef_index;
-				) e.e_constrs;
 
 				let avalues = alloc_tmp ctx HArray in
-				op ctx (OType (rt, HDyn));
-				op ctx (OCall2 (avalues, alloc_std ctx "alloc_array" [HType;HI32] HArray, rt, reg_int ctx (!max_val + 1)));
+				op ctx (OField (avalues, r, index "__evalues__"));
 
 				List.iter (fun n ->
 					let f = PMap.find n e.e_constrs in
 					match follow f.ef_type with
 					| TFun _ -> ()
 					| _ ->
-						let t = to_type ctx f.ef_type in
 						let g = alloc_global ctx (efield_name e f) t in
 						let r = alloc_tmp ctx t in
-						op ctx (OMakeEnum (r,f.ef_index,[]));
+						let rd = alloc_tmp ctx HDyn in
+						op ctx (OGetArray (rd,avalues, reg_int ctx f.ef_index));
+						op ctx (OSafeCast (r, rd));
 						op ctx (OSetGlobal (g,r));
-						let d = alloc_tmp ctx HDyn in
-						op ctx (OToDyn (d,r));
-						op ctx (OSetArray (avalues, reg_int ctx f.ef_index, d));
 				) e.e_names;
 
-				op ctx (OType (rt, (to_type ctx (TEnum (e,List.map snd e.e_params)))));
-				op ctx (OCall3 (alloc_tmp ctx HVoid, alloc_fun_path ctx (["hl"],"Enum") "new",r,rt,avalues));
-
 				(match Codegen.build_metadata ctx.com (TEnumDecl e) with
 				| None -> ()
 				| Some e -> op ctx (OSetField (r,index "__meta__",eval_to ctx e HDyn)));
 
-				op ctx (OSetGlobal (g,r));
 
 			| TAbstractDecl { a_path = [], name; a_pos = pos } ->
 				(match name with

+ 13 - 0
src/generators/hlinterp.ml

@@ -1552,6 +1552,14 @@ let load_native ctx lib name t =
 				| HEnum e -> (match e.eglobal with None -> VNull | Some g -> ctx.t_globals.(g))
 				| _ -> VNull)
 			| _ -> assert false)
+		| "type_set_global" ->
+			(function
+			| [VType t; v] ->
+				VBool (match t with
+				| HObj c -> (match c.pclassglobal with None -> false | Some g -> ctx.t_globals.(g) <- v; true)
+				| HEnum e -> (match e.eglobal with None -> false | Some g -> ctx.t_globals.(g) <- v; true)
+				| _ -> false)
+			| _ -> assert false)
 		| "type_name" ->
 			(function
 			| [VType t] ->
@@ -1618,6 +1626,11 @@ let load_native ctx lib name t =
 				| HEnum e -> VArray (Array.map (fun (f,_,_) -> VBytes (caml_to_hl f)) e.efields,HBytes)
 				| _ -> VNull)
 			| _ -> assert false)
+		| "type_enum_values" ->
+			(function
+			| [VType (HEnum e as t)] ->
+				VArray (Array.mapi (fun i (_,_,args) -> if Array.length args <> 0 then VNull else VDyn (VEnum (i,[||]),t)) e.efields,HDyn)
+			| _ -> assert false)
 		| "type_enum_eq" ->
 			(function
 			| [VDyn (VEnum _, HEnum _); VNull] | [VNull; VDyn (VEnum _, HEnum _)] -> VBool false

+ 0 - 14
std/hl/BaseType.hx

@@ -56,20 +56,6 @@ class Enum extends BaseType {
 	public var __emap__ : hl.types.BytesMap;
 	public var __constructs__ : Array<String>;
 	public var __evalues__ : NativeArray<Dynamic>;
-	function new(t,vals) @:privateAccess {
-		__type__ = t;
-		__evalues__ = vals;
-		__ename__ = t.getName();
-		__emap__ = new hl.types.BytesMap();
-		__constructs__ = new Array();
-		var cl = t.getEnumFields();
-		for( i in 0...cl.length ) {
-			var name = cl[i];
-			__emap__.set(name, i);
-			__constructs__.push(String.fromUCS2(name));
-		}
-		std.Type.register(__ename__.bytes,this);
-	}
 }
 
 @:keep

+ 8 - 0
std/hl/Type.hx

@@ -81,6 +81,10 @@ abstract TypeKind(Int) {
 		return null;
 	}
 
+	@:hlNative("std","type_set_global") public function setGlobal( v : Dynamic ) : Bool {
+		return false;
+	}
+
 	@:hlNative("std","type_args_count") public function getArgsCount() : Int {
 		return 0;
 	}
@@ -93,6 +97,10 @@ abstract TypeKind(Int) {
 		return null;
 	}
 
+	@:hlNative("std","type_enum_values") public function getEnumValues() : NativeArray<Dynamic> {
+		return null;
+	}
+
 	@:hlNative("std","alloc_obj") public function allocObject() : Dynamic {
 		return null;
 	}

+ 18 - 0
std/hl/_std/Type.hx

@@ -42,6 +42,24 @@ class Type {
 		untyped $allTypes(new hl.types.BytesMap());
 	}
 
+	@:keep static function initEnum( et : hl.Type, t : hl.Type ) : hl.BaseType.Enum @:privateAccess {
+		var e : hl.BaseType.Enum = et.allocObject();
+		e.__type__ = t;
+		e.__evalues__ = t.getEnumValues();
+		e.__ename__ = t.getName();
+		e.__emap__ = new hl.types.BytesMap();
+		e.__constructs__ = new Array();
+		var cl = t.getEnumFields();
+		for( i in 0...cl.length ) {
+			var name = cl[i];
+			e.__emap__.set(name, i);
+			e.__constructs__.push(String.fromUCS2(name));
+		}
+		register(e.__ename__.bytes,e);
+		t.setGlobal(e);
+		return e;
+	}
+
 	@:keep static function register( b : hl.Bytes, t : hl.BaseType ) : Void {
 		allTypes.set(b, t);
 	}