Browse Source

[hl] CArray add blit, fix unsafeSet (#12118)

* [std/hl] Add hl.CArray.blit

* [hl] Fix hl.CArray.blit same type detection

* [hl] Fix CArray.unsafeset not working on hl/c

* [hl] Fix CArray.unsafeSet again

* [tests] add blit/set test and bump hl_ver for test

* [tests] fix if location
Yuxiao Mao 3 months ago
parent
commit
1bba8fef71

+ 6 - 6
src/generators/genhl.ml

@@ -2609,14 +2609,14 @@ and eval_expr ctx e =
 				free ctx ra;
 				free ctx ra;
 				free ctx ridx;
 				free ctx ridx;
 				v
 				v
-            | ACArray (ra, _, ridx) ->
+			| ACArray (ra, t, ridx) ->
 				hold ctx ra;
 				hold ctx ra;
 				hold ctx ridx;
 				hold ctx ridx;
-                let v = value() in
-                op ctx (OSetArray (ra,ridx,v));
-                free ctx ridx;
-                free ctx ra;
-                v
+				let v = eval_to ctx e2 t in
+				op ctx (OSetArray (ra,ridx,v));
+				free ctx ridx;
+				free ctx ra;
+				v
 			| ADynamic (ethis,f) ->
 			| ADynamic (ethis,f) ->
 				let obj = eval_null_check ctx ethis in
 				let obj = eval_null_check ctx ethis in
 				hold ctx obj;
 				hold ctx obj;

+ 5 - 5
src/generators/hl2c.ml

@@ -1042,11 +1042,11 @@ let generate_function gctx ctx f =
 		| OSetMem (b,idx,r) ->
 		| OSetMem (b,idx,r) ->
 			sexpr "*(%s*)(%s + %s) = %s" (ctype (rtype r)) (reg b) (reg idx) (reg r)
 			sexpr "*(%s*)(%s + %s) = %s" (ctype (rtype r)) (reg b) (reg idx) (reg r)
 		| OSetArray (arr,idx,v) ->
 		| OSetArray (arr,idx,v) ->
-            (match rtype arr with
-            | HAbstract _ ->
-			    sexpr "((%s*)%s)[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
-            | _ ->
-			    sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v))
+			(match rtype arr with
+			| HAbstract _ ->
+				sexpr "((%s)%s)[%s] = *%s" (ctype (rtype v)) (reg arr) (reg idx) (reg v)
+			| _ ->
+				sexpr "((%s*)(%s + 1))[%s] = %s" (ctype (rtype v)) (reg arr) (reg idx) (reg v))
 		| OSafeCast (r,v) ->
 		| OSafeCast (r,v) ->
 			let tsrc = rtype v in
 			let tsrc = rtype v in
 			let t = rtype r in
 			let t = rtype r in

+ 11 - 1
std/hl/CArray.hx

@@ -20,5 +20,15 @@ abstract CArray<T>(Abstract<"hl_carray">) {
 		return null;
 		return null;
 	}
 	}
 
 
+	#if (hl_ver >= version("1.16.0"))
+	public inline function blit( cl : Class<T>, pos : Int, src : CArray<T>, srcPos : Int, srcLen : Int ) : Void {
+		carray_blit( cast this, (cast cl:BaseType).__type__, pos, src, srcPos, srcLen );
+	}
+
+	@:hlNative("?std","carray_blit")
+	static function carray_blit( dst: CArray<Dynamic>, t : hl.Type, pos : Int, src : CArray<Dynamic>, srcPos : Int, srcLen : Int ) : Void {
+	}
+	#end
+
 }
 }
-#end
+#end

+ 1 - 1
tests/threads/build.hxml

@@ -4,4 +4,4 @@
 --dce full
 --dce full
 -D analyzer-optimize
 -D analyzer-optimize
 -D UTEST_PRINT_TESTS
 -D UTEST_PRINT_TESTS
--D hl-ver=1.15.0
+-D hl-ver=1.16.0

+ 1 - 1
tests/unit/compile-hl.hxml

@@ -3,4 +3,4 @@ compile-each.hxml
 -hl bin/unit.hl
 -hl bin/unit.hl
 #-D interp
 #-D interp
 -D hl-check
 -D hl-check
--D hl-ver=1.15.0
+-D hl-ver=1.16.0

+ 1 - 1
tests/unit/compile-hlc.hxml

@@ -3,4 +3,4 @@ compile-each.hxml
 -hl bin/hlc/unit.c
 -hl bin/hlc/unit.c
 #-D interp
 #-D interp
 -D hl-check
 -D hl-check
--D hl-ver=1.15.0
+-D hl-ver=1.16.0

+ 83 - 0
tests/unit/src/unit/issues/Issue12118.hx

@@ -0,0 +1,83 @@
+package unit.issues;
+
+@:struct
+private class NodeStruct {
+	public var bodyID : Int;
+	public var x : Int;
+	public var y : Int;
+}
+
+private class NodeObj {
+	public var bodyID : Int;
+	public var x : Int;
+	public var y : Int;
+}
+
+class Issue12118 extends Test {
+
+	#if hl
+	function testBlitStruct() {
+		var nodes = initNodeStruct(5, 10);
+		nodes.blit(NodeStruct, 1, nodes, 2, 2);
+		eq(0, nodes[0].bodyID);
+		eq(2, nodes[1].bodyID);
+		eq(3, nodes[2].bodyID);
+		eq(3, nodes[3].bodyID);
+		eq(4, nodes[4].bodyID);
+	}
+
+	function testBlitObj() {
+		var nodes = initNodeObj(5, 10);
+		nodes.blit(NodeObj, 1, nodes, 2, 2);
+		eq(0, nodes[0].bodyID);
+		eq(2, nodes[1].bodyID);
+		eq(3, nodes[2].bodyID);
+		eq(3, nodes[3].bodyID);
+		eq(4, nodes[4].bodyID);
+	}
+
+	function testSetStruct() {
+		var nodes = initNodeStruct(5, 10);
+		nodes.unsafeSet(1, nodes[3]);
+		eq(3, nodes[1].bodyID);
+		eq(13, nodes[1].x);
+		eq(0, nodes[1].y);
+		eq(nodes[3].bodyID, nodes[1].bodyID);
+		eq(nodes[3].x, nodes[1].x);
+		eq(nodes[3].y, nodes[1].y);
+	}
+
+	function testSetObj() {
+		var nodes = initNodeObj(5, 10);
+		nodes.unsafeSet(1, nodes[3]);
+		eq(3, nodes[1].bodyID);
+		eq(13, nodes[1].x);
+		eq(0, nodes[1].y);
+		eq(nodes[3].bodyID, nodes[1].bodyID);
+		eq(nodes[3].x, nodes[1].x);
+		eq(nodes[3].y, nodes[1].y);
+	}
+
+	private function initNodeStruct( count : Int, offset : Int ) {
+		var nodes = hl.CArray.alloc(NodeStruct, count);
+		for( i in 0...count ) {
+			var node = nodes[i];
+			node.bodyID = i;
+			node.x = offset + i;
+			node.y = 0;
+		}
+		return nodes;
+	}
+
+	private function initNodeObj( count : Int, offset : Int ) {
+		var nodes = hl.CArray.alloc(NodeObj, count);
+		for( i in 0...count ) {
+			var node = nodes[i];
+			node.bodyID = i;
+			node.x = offset + i;
+			node.y = 0;
+		}
+		return nodes;
+	}
+	#end
+}