Procházet zdrojové kódy

[hl] use hl.NativeArray for Vector (#11568)

* [hl] use hl.NativeArray for Vector

* add HArray,HArray case to compare function

* Fix Array in NativeArray error, add array get bytes

---------

Co-authored-by: Yuxiao Mao <[email protected]>
Simon Krajewski před 11 měsíci
rodič
revize
3b050f0a10

+ 1 - 1
src/generators/genhl.ml

@@ -2034,7 +2034,7 @@ and eval_expr ctx e =
 			hold ctx arr;
 			hold ctx arr;
 			let pos = eval_to ctx pos HI32 in
 			let pos = eval_to ctx pos HI32 in
 			free ctx arr;
 			free ctx arr;
-			let r = alloc_tmp ctx at in
+			let r = if is_array_type at then alloc_tmp ctx HDyn else alloc_tmp ctx at in
 			op ctx (OGetArray (r, arr, pos));
 			op ctx (OGetArray (r, arr, pos));
 			cast_to ctx r (to_type ctx e.etype) e.epos
 			cast_to ctx r (to_type ctx e.etype) e.epos
 		| "$aset", [a; pos; value] ->
 		| "$aset", [a; pos; value] ->

+ 18 - 20
std/haxe/ds/Vector.hx

@@ -27,18 +27,13 @@ using cpp.NativeArray;
 #end
 #end
 
 
 private typedef VectorData<T> =
 private typedef VectorData<T> =
-	#if flash10
-	flash.Vector<T>
-	#elseif neko
-	neko.NativeArray<T>
-	#elseif java
-	java.NativeArray<T>
-	#elseif lua
-	lua.Table<Int, T>
-	#elseif eval
-	eval.Vector<T>
-	#else
-	Array<T>
+	#if flash10 flash.Vector<T>
+	#elseif neko neko.NativeArray<T>
+	#elseif java java.NativeArray<T>
+	#elseif lua lua.Table<Int, T>
+	#elseif eval eval.Vector<T>
+	#elseif hl hl.NativeArray<T>
+	#else Array<T>
 	#end;
 	#end;
 
 
 /**
 /**
@@ -76,6 +71,8 @@ abstract Vector<T>(VectorData<T>) {
 		this = untyped __lua_table__({length: length});
 		this = untyped __lua_table__({length: length});
 		#elseif eval
 		#elseif eval
 		this = new eval.Vector(length);
 		this = new eval.Vector(length);
+		#elseif hl
+		this = new hl.NativeArray<T>(length);
 		#else
 		#else
 		this = [];
 		this = [];
 		untyped this.length = length;
 		untyped this.length = length;
@@ -95,7 +92,6 @@ abstract Vector<T>(VectorData<T>) {
 		#elseif python
 		#elseif python
 		this = python.Syntax.code("([{0}]*{1})", defaultValue, length);
 		this = python.Syntax.code("([{0}]*{1})", defaultValue, length);
 		#else
 		#else
-
 		#if flash10
 		#if flash10
 		this = new flash.Vector<T>(length, true);
 		this = new flash.Vector<T>(length, true);
 		#elseif neko
 		#elseif neko
@@ -108,12 +104,13 @@ abstract Vector<T>(VectorData<T>) {
 		this = untyped __lua_table__({length: length});
 		this = untyped __lua_table__({length: length});
 		#elseif eval
 		#elseif eval
 		this = new eval.Vector(length);
 		this = new eval.Vector(length);
+		#elseif hl
+		this = new hl.NativeArray<T>(length);
 		#else
 		#else
 		this = [];
 		this = [];
 		untyped this.length = length;
 		untyped this.length = length;
 		#end
 		#end
 		fill(defaultValue);
 		fill(defaultValue);
-
 		#end
 		#end
 	}
 	}
 
 
@@ -174,7 +171,8 @@ abstract Vector<T>(VectorData<T>) {
 		Sets all `length` elements of `this` Vector to `value`.
 		Sets all `length` elements of `this` Vector to `value`.
 	**/
 	**/
 	public inline function fill(value:T):Void
 	public inline function fill(value:T):Void
-		for (i in 0...length) this[i] = value;
+		for (i in 0...length)
+			this[i] = value;
 
 
 	/**
 	/**
 		Copies `length` of elements from `src` Vector, beginning at `srcPos` to
 		Copies `length` of elements from `src` Vector, beginning at `srcPos` to
@@ -183,12 +181,12 @@ abstract Vector<T>(VectorData<T>) {
 		The results are unspecified if `length` results in out-of-bounds access,
 		The results are unspecified if `length` results in out-of-bounds access,
 		or if `src` or `dest` are null
 		or if `src` or `dest` are null
 	**/
 	**/
-	public static #if (java || neko || cpp || eval) inline #end function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
+	public static #if (java || neko || cpp || eval || hl) inline #end function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
 		#if neko
 		#if neko
 		untyped __dollar__ablit(dest, destPos, src, srcPos, len);
 		untyped __dollar__ablit(dest, destPos, src, srcPos, len);
 		#elseif java
 		#elseif java
 		java.lang.System.arraycopy(src, srcPos, dest, destPos, len);
 		java.lang.System.arraycopy(src, srcPos, dest, destPos, len);
-		#elseif cpp
+		#elseif (cpp || hl)
 		dest.toData().blit(destPos, src.toData(), srcPos, len);
 		dest.toData().blit(destPos, src.toData(), srcPos, len);
 		#elseif eval
 		#elseif eval
 		src.toData().blit(srcPos, dest.toData(), destPos, len);
 		src.toData().blit(srcPos, dest.toData(), destPos, len);
@@ -222,7 +220,7 @@ abstract Vector<T>(VectorData<T>) {
 	/**
 	/**
 		Creates a new Array, copy the content from the Vector to it, and returns it.
 		Creates a new Array, copy the content from the Vector to it, and returns it.
 	**/
 	**/
-	public #if (flash || cpp || js || java || eval) inline #end function toArray():Array<T> {
+	public #if (flash || cpp || js || java || eval || hl) inline #end function toArray():Array<T> {
 		#if cpp
 		#if cpp
 		return this.copy();
 		return this.copy();
 		#elseif python
 		#elseif python
@@ -234,7 +232,7 @@ abstract Vector<T>(VectorData<T>) {
 		#else
 		#else
 		var a = new Array();
 		var a = new Array();
 		var len = length;
 		var len = length;
-		#if (neko)
+		#if (neko || hl)
 		// prealloc good size
 		// prealloc good size
 		if (len > 0)
 		if (len > 0)
 			a[len - 1] = get(0);
 			a[len - 1] = get(0);
@@ -377,7 +375,7 @@ abstract Vector<T>(VectorData<T>) {
 		If `f` is null, the result is unspecified.
 		If `f` is null, the result is unspecified.
 	**/
 	**/
 	public inline function sort(f:T->T->Int):Void {
 	public inline function sort(f:T->T->Int):Void {
-		#if (neko || java || eval)
+		#if (neko || java || eval || hl)
 		throw "not yet supported";
 		throw "not yet supported";
 		#elseif lua
 		#elseif lua
 		haxe.ds.ArraySort.sort(cast this, f);
 		haxe.ds.ArraySort.sort(cast this, f);

+ 13 - 0
std/hl/NativeArray.hx

@@ -99,4 +99,17 @@ package hl;
 	public inline function blit(pos:Int, src:NativeArray<T>, srcPos:Int, srcLen:Int):Void {
 	public inline function blit(pos:Int, src:NativeArray<T>, srcPos:Int, srcLen:Int):Void {
 		real_blit(cast this, pos, cast src, srcPos, srcLen);
 		real_blit(cast this, pos, cast src, srcPos, srcLen);
 	}
 	}
+
+	#if (hl_ver >= version("1.15.0"))
+	@:hlNative("std", "array_bytes") static function get_bytes(a:NativeArray<Any>):Bytes {
+		return null;
+	}
+
+	/**
+		Get the bytes reference from an native array (no copy occurs)
+	**/
+	public inline function getBytes():Bytes {
+		return get_bytes(cast this);
+	}
+	#end
 }
 }

+ 0 - 99
std/hl/_std/haxe/ds/Vector.hx

@@ -1,99 +0,0 @@
-/*
- * Copyright (C)2005-2019 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;
-
-private typedef VectorData<T> = Array<T>
-
-@:coreApi
-abstract Vector<T>(VectorData<T>) {
-	extern overload public inline function new(length:Int) {
-		this = [];
-		if (length > 0)
-			this[length - 1] = @:nullSafety(Off) cast null;
-	}
-
-	extern overload public inline function new(length:Int, defaultValue:T):Vector<T> {
-		this = [
-			for (i in 0...length) defaultValue
-		];
-	}
-
-	@:op([]) public inline function get(index:Int):T {
-		return this[index];
-	}
-
-	@:op([]) public inline function set(index:Int, val:T):T {
-		return this[index] = val;
-	}
-
-	public var length(get, never):Int;
-
-	inline function get_length():Int {
-		return this.length;
-	}
-
-	public inline function fill(value:T):Void
-		for (i in 0...length) this[i] = value;
-
-	public static inline function blit<T>(src:Vector<T>, srcPos:Int, dest:Vector<T>, destPos:Int, len:Int):Void {
-		(cast dest : hl.types.ArrayBase.ArrayAccess).blit(destPos, (cast src : hl.types.ArrayBase.ArrayAccess), srcPos, len);
-	}
-
-	public inline function toArray():Array<T> {
-		return this.copy();
-	}
-
-	public inline function toData():VectorData<T>
-		return this;
-
-	static public inline function fromData<T>(data:VectorData<T>):Vector<T>
-		return cast data;
-
-	static public inline function fromArrayCopy<T>(array:Array<T>):Vector<T> {
-		return cast array.copy();
-	}
-
-	public inline function copy<T>():Vector<T> {
-		return cast this.copy();
-	}
-
-	public inline function join<T>(sep:String):String {
-		return this.join(sep);
-	}
-
-	public inline function sort(f:T->T->Int):Void {
-		this.sort(f);
-	}
-
-	public inline function map<S>(f:T->S):Vector<S> {
-		var length = length;
-		var r = new Vector<S>(length);
-		var i = 0;
-		var len = length;
-		for (i in 0...len) {
-			var v = f(get(i));
-			r.set(i, v);
-		}
-		return r;
-	}
-}

+ 1 - 1
tests/unit/src/unit/UnitBuilder.hx

@@ -174,7 +174,7 @@ class UnitBuilder {
 					case EBinop(OpEq, e1, e2):
 					case EBinop(OpEq, e1, e2):
 						mkEq(e1, e2, e.pos);
 						mkEq(e1, e2, e.pos);
 					case EBinop(OpNotEq, e1, e2):
 					case EBinop(OpNotEq, e1, e2):
-						macro t($e1 != $e2);
+						macro @:pos(e.pos) t($e1 != $e2);
 					case EBinop(OpGt | OpGte | OpLt | OpLte, _, _):
 					case EBinop(OpGt | OpGte | OpLt | OpLte, _, _):
 						{
 						{
 							expr: (macro t($e)).expr,
 							expr: (macro t($e)).expr,

+ 30 - 0
tests/unit/src/unit/issues/Issue11734.hx

@@ -5,6 +5,22 @@ import unit.Test;
 import hl.NativeArray;
 import hl.NativeArray;
 #end
 #end
 
 
+private class Group<T> {
+	public var grid : haxe.ds.Vector<Array<T>>;
+	public function new(size:Int) {
+		grid = new haxe.ds.Vector(size);
+		for (i in 0...size)
+			grid[i] = [];
+	}
+}
+
+private class Foo {
+	public var x : Int;
+	public function new(x:Int) {
+		this.x = x;
+	}
+}
+
 class Issue11734 extends Test {
 class Issue11734 extends Test {
 	#if hl
 	#if hl
 	function test() {
 	function test() {
@@ -16,4 +32,18 @@ class Issue11734 extends Test {
 		feq(1.0, a[0]);
 		feq(1.0, a[0]);
 	}
 	}
 	#end
 	#end
+
+	function testArrayInVector() {
+		var g = new Group<Foo>(5);
+		for (i in 0...5)
+			g.grid[i].push(new Foo(10+i));
+		eq(10, g.grid[0][0].x);
+		eq(14, g.grid[4][0].x);
+
+		var g = new Group<Float>(5);
+		for (i in 0...5)
+			g.grid[i].push(10.0+i);
+		feq(10.0, g.grid[0][0]);
+		feq(14.0, g.grid[4][0]);
+	}
 }
 }

+ 2 - 2
tests/unit/src/unitstd/haxe/ds/Vector.unit.hx

@@ -27,7 +27,7 @@ vec.get(2) == vNullBool;
 // fromArray
 // fromArray
 var arr = ["1", "2", "3"];
 var arr = ["1", "2", "3"];
 var vec:haxe.ds.Vector<String> = haxe.ds.Vector.fromArrayCopy(arr);
 var vec:haxe.ds.Vector<String> = haxe.ds.Vector.fromArrayCopy(arr);
-#if (!flash && !neko && !jvm && !lua && !eval && !php)
+#if (!flash && !neko && !jvm && !lua && !eval && !php && !hl)
 arr != vec.toData();
 arr != vec.toData();
 #end
 #end
 vec.length == 3;
 vec.length == 3;
@@ -192,7 +192,7 @@ vec2[1] == "value: 13";
 
 
 // sort
 // sort
 
 
-#if !(neko || jvm || eval)
+#if !(neko || jvm || eval || hl)
 var vec = new haxe.ds.Vector(4);
 var vec = new haxe.ds.Vector(4);
 vec[0] = 99;
 vec[0] = 99;
 vec[1] = 101;
 vec[1] = 101;