Преглед изворни кода

[hl] add more GUID tests and fixes (#12440)

* [hl] add more GUID tests and fixes

* [hlc] fix OToInt to 64bit value

* [tests] add a -i32 to guid case

* [hl] add guid array str test and fixes

* [hl] allow compare GUID and sort GUID array
Yuxiao Mao пре 1 дан
родитељ
комит
a18279fc8d

+ 19 - 3
src/generators/genhl.ml

@@ -80,6 +80,7 @@ type array_impl = {
 	af32 : tclass;
 	af64 : tclass;
 	ai64 : tclass option;
+	aguid : tclass option;
 }
 
 type constval =
@@ -157,7 +158,10 @@ let is_extern_field f =
 
 let is_array_class name =
 	match name with
-	| "hl.types.ArrayDyn" | "hl.types.ArrayBytes_Int" | "hl.types.ArrayBytes_Float" | "hl.types.ArrayObj" | "hl.types.ArrayBytes_hl_F32" | "hl.types.ArrayBytes_hl_UI16" | "hl.types.ArrayBytes_hl_UI8" | "hl.types.ArrayBytes_hl_I64" -> true
+	| "hl.types.ArrayDyn" | "hl.types.ArrayBytes_Int" | "hl.types.ArrayBytes_Float" | "hl.types.ArrayObj"
+	| "hl.types.ArrayBytes_hl_F32" | "hl.types.ArrayBytes_hl_UI16" | "hl.types.ArrayBytes_hl_UI8" | "hl.types.ArrayBytes_hl_I64"
+	| "hl.types.ArrayBytes_hl_GUID"
+		-> true
 	| _ -> false
 
 let is_array_type t =
@@ -288,11 +292,16 @@ let array_class ctx t =
 		ctx.array_impl.af32
 	| HF64 ->
 		ctx.array_impl.af64
-	| HI64 | HGUID ->
+	| HI64 ->
 		begin match ctx.array_impl.ai64 with
 		| None -> die "" __LOC__
 		| Some c -> c
 		end
+	| HGUID ->
+		begin match ctx.array_impl.aguid with
+		| None -> die "" __LOC__
+		| Some c -> c
+		end
 	| HDyn ->
 		ctx.array_impl.adyn
 	| _ ->
@@ -2830,7 +2839,7 @@ and eval_expr ctx e =
 		| HI64 ->
 			array_bytes 3 HI64 "I64" (fun b i r -> OSetMem (b,i,r))
 		| HGUID ->
-			array_bytes 3 HGUID "HGUID" (fun b i r -> OSetMem (b,i,r))
+			array_bytes 3 HGUID "GUID" (fun b i r -> OSetMem (b,i,r))
 		| _ ->
 			let at = if is_dynamic et then et else HDyn in
 			let size = reg_int ctx (List.length el) in
@@ -4186,6 +4195,13 @@ let create_context com =
 					None
 				else
 					Some (get_class "ArrayBytes_hl_I64");
+			aguid =
+				if Gctx.raw_defined com "hl_legacy32"
+					|| hl_ver <> "" && compare_version hl_ver "1.13.0" < 0
+				then
+					None
+				else
+					Some (get_class "ArrayBytes_hl_GUID");
 		};
 		base_class = get_class "Class";
 		base_enum = get_class "Enum";

+ 5 - 1
src/generators/hl2c.ml

@@ -998,7 +998,11 @@ let generate_function gctx ctx f =
 		| OToUFloat (r,v) ->
 			sexpr "%s = (%s)(unsigned)%s" (reg r) (ctype (rtype r)) (reg v)
 		| OToInt (r,v) ->
-			sexpr "%s = (int)%s" (reg r) (reg v)
+			let rt = rtype r in
+			if type_size_bits rt <= 2 then
+				sexpr "%s = (int)%s" (reg r) (reg v)
+			else
+				sexpr "%s = (int64)%s" (reg r) (reg v)
 		| ONew r ->
 			(match rtype r with
 			| HObj o | HStruct o -> sexpr "%s = (%s)hl_alloc_obj(%s)" (reg r) (tname o.pname) (type_value ctx (rtype r))

+ 0 - 2
src/generators/hlcode.ml

@@ -403,8 +403,6 @@ let rec safe_cast t1 t2 =
 		List.for_all2 (fun t1 t2 -> safe_cast t2 t1 || (t1 = HDyn && is_dynamic t2)) args1 args2 && safe_cast t1 t2
 	| HArray t1,HArray t2 ->
 		compatible_element_types t1 t2
-	| (HI64|HGUID), (HI64|HGUID) ->
-		true
 	| _ ->
 		tsame t1 t2
 

+ 2 - 2
std/hl/Api.hx

@@ -54,8 +54,8 @@ extern class Api {
 	#end
 	#if (hl_ver >= version("1.15.0"))
 	@:hlNative("?std", "register_guid_name") private static function _registerGUIDName( guid : hl.I64, bytes : hl.Bytes ) : Void;
-	static inline function registerGUIDName( guid : GUID, name : String ) {
-		return _registerGUIDName(guid,@:privateAccess name.bytes);
+	static inline function registerGUIDName( guid : GUID, name : Null<String> ) {
+		_registerGUIDName(guid, @:privateAccess name?.bytes);
 	}
 	#end
 	#if (hl_ver >= version("1.16.0"))

+ 16 - 1
std/hl/GUID.hx

@@ -22,4 +22,19 @@
 
 package hl;
 
-@:coreType @:notNull @:runtimeValue abstract GUID to I64 from I64 {}
+@:coreType @:notNull @:runtimeValue abstract GUID to I64 from I64 {
+	// Same as `Std.string`, but copied here to prevent Std.string(const TInt) optimization on GUID
+	public function toString() {
+		var len = 0;
+		var bytes = hl.Bytes.fromValue(this, new hl.Ref(len));
+		return @:privateAccess String.__alloc__(bytes, len);
+	}
+
+	#if (hl_ver >= version("1.12.0") && !hl_legacy32)
+	@:op(a==b) function eq(v:GUID) : Bool;
+	@:op(a>=b) function gte(v:GUID) : Bool;
+	@:op(a<=b) function lte(v:GUID) : Bool;
+	@:op(a>b) function gt(v:GUID) : Bool;
+	@:op(a<b) function lt(v:GUID) : Bool;
+	#end
+}

+ 6 - 2
std/hl/types/ArrayBase.hx

@@ -166,8 +166,12 @@ class ArrayBase extends ArrayAccess {
 		return a;
 	}
 
-	public static function allocHGUID(bytes:BytesAccess<I64>, length:Int) @:privateAccess {
-		return allocI64(bytes, length);
+	public static function allocGUID(bytes:BytesAccess<GUID>, length:Int) @:privateAccess {
+		var a:ArrayBytes.ArrayGUID = untyped $new(ArrayBytes.ArrayGUID);
+		a.length = length;
+		a.bytes = bytes;
+		a.size = length;
+		return a;
 	}
 	#end
 }

+ 2 - 2
std/hl/types/ArrayBytes.hx

@@ -148,7 +148,7 @@ class BytesIterator<T> extends ArrayIterator<T> {
 		var tid = Type.get((cast null : T));
 		if (tid == Type.get(0))
 			(bytes : Bytes).sortI32(0, length, cast f);
-		else if( tid == Type.get((0:hl.I64)) ) {
+		else if( tid == Type.get((0:hl.I64)) || tid == Type.get((0:hl.GUID)) ) {
 			#if (hl_ver >= version("1.16.0") && !hl_legacy32)
 			(bytes : Bytes).sortI64(0, length, cast f);
 			#else
@@ -372,5 +372,5 @@ typedef ArrayF32 = ArrayBytes<F32>;
 typedef ArrayF64 = ArrayBytes<Float>;
 #if (hl_ver >= version("1.13.0") && !hl_legacy32)
 typedef ArrayI64 = ArrayBytes<I64>;
-typedef ArrayGUID = ArrayBytes<I64>;
+typedef ArrayGUID = ArrayBytes<GUID>;
 #end

+ 10 - 0
std/hl/types/ArrayDyn.hx

@@ -239,6 +239,16 @@ class ArrayDyn extends ArrayAccess {
 			allowReinterpret = false;
 			return arr;
 		}
+		if (t == Type.get((null : ArrayBytes.ArrayGUID))) {
+			var a:BytesAccess<GUID> = null;
+			a = new Bytes(array.length << a.sizeBits);
+			for (i in 0...array.length)
+				a[i] = array.getDyn(i);
+			var arr = ArrayBase.allocGUID(a, array.length);
+			array = arr;
+			allowReinterpret = false;
+			return arr;
+		}
 		#end
 		return null;
 	}

+ 52 - 0
tests/unit/src/unit/TestHL.hx

@@ -149,6 +149,46 @@ class TestHL extends Test {
 		t(v == num.ui16);
 	}
 
+	public function testGuid() {
+		var num = new Numbers(); // prevent @:analyzer(ignore)
+		var v : hl.GUID = haxe.Int64.make(0xF, 1);
+		num.loadInt64(v);
+		t(num.guid == num.i64);
+		t(num.guid == v);
+		t(v == num.guid);
+		t(num.i64 == v);
+		t(v == num.i64);
+		eq("####-#w##-##&", Std.string(v));
+		eq("####-#w##-##&", Std.string(num.guid));
+		hl.Api.registerGUIDName(v, "fooF");
+		eq("fooF", Std.string(v));
+		eq("fooF", Std.string(num.guid));
+		hl.Api.registerGUIDName(v, null);
+		eq("####-#w##-##&", Std.string(v));
+		eq("####-#w##-##&", Std.string(num.guid));
+
+		var v : hl.GUID = haxe.Int64.make(0xF, 1);
+		eq("####-#w##-##&", Std.string(v));
+		hl.Api.registerGUIDName(v, "fooF");
+		eq("fooF", Std.string(v));
+		hl.Api.registerGUIDName(v, null);
+		eq("####-#w##-##&", Std.string(v));
+
+		var v : hl.GUID = 0xF001;
+		eq("####-####-D#&", Std.string(v));
+
+		var v : hl.GUID = -0xF001;
+		eq("zzzz-zzzz-kzz", Std.string(v));
+
+		var v : hl.GUID = 0;
+		num.loadInt64(v);
+		eq("0", Std.string(v));
+		eq("0", Std.string(num.guid));
+
+		var v : hl.GUID = 0;
+		eq("0", Std.string(v));
+	}
+
 	public function testNumbersNull() {
 		var num : NumbersNull = {};
 		t(cast(num.nui8, hl.UI16) == 0);
@@ -202,6 +242,18 @@ class TestHL extends Test {
 		t(arr[0] == i64);
 		t(arr[1] == guid);
 		t(arr[2] == 10);
+		eq("####-#2##-##&", Std.string(arr[0]));
+		eq("####-#9zz-zzz", Std.string(arr[1]));
+		eq("####-####-##8", Std.string(arr[2]));
+		eq("[####-#2##-##&,####-#9zz-zzz,####-####-##8]", Std.string(arr));
+		hl.Api.registerGUIDName(guid, "fooF");
+		eq("fooF", Std.string(arr[1]));
+		eq("[####-#2##-##&,fooF,####-####-##8]", Std.string(arr));
+		hl.Api.registerGUIDName(guid, null);
+		eq("####-#9zz-zzz", Std.string(arr[1]));
+		eq("[####-#2##-##&,####-#9zz-zzz,####-####-##8]", Std.string(arr));
+		arr.sort((a, b) -> a > b ? 1 : -1);
+		eq("[####-####-##8,####-#2##-##&,####-#9zz-zzz]", Std.string(arr));
 
 		var arr : Array<hl.I64> = [];
 		var i64 : hl.I64 = haxe.Int64.make(1, 1);