Bläddra i källkod

implement $setref and add a basic test

Simon Krajewski 9 år sedan
förälder
incheckning
43ebfe597b
4 ändrade filer med 42 tillägg och 2 borttagningar
  1. 3 2
      analyzer.ml
  2. 11 0
      genhl.ml
  3. 3 0
      tests/unit/src/unit/Test.hx
  4. 25 0
      tests/unit/src/unit/TestHL.hx

+ 3 - 2
analyzer.ml

@@ -152,6 +152,7 @@ let is_unbound_call_that_might_have_side_effects v el = match v.v_name,el with
 
 
 let is_ref_type = function
 let is_ref_type = function
 	| TType({t_path = ["cs"],("Ref" | "Out")},_) -> true
 	| TType({t_path = ["cs"],("Ref" | "Out")},_) -> true
+	| TAbstract({a_path=["hl";"types"],"Ref"},_) -> true
 	| _ -> false
 	| _ -> false
 
 
 let dynarray_map f d =
 let dynarray_map f d =
@@ -1139,8 +1140,8 @@ module TexprTransformer = struct
 				| TConst TSuper when ctx.com.platform = Java || ctx.com.platform = Cs ->
 				| TConst TSuper when ctx.com.platform = Java || ctx.com.platform = Cs ->
 					bb,e
 					bb,e
 				| _ ->
 				| _ ->
-					let check e t = match e.eexpr,t with
-						| TLocal v,TType({t_path = ["cs"],("Ref" | "Out")},_) ->
+					let check e t = match e.eexpr with
+						| TLocal v when is_ref_type t ->
 							v.v_capture <- true;
 							v.v_capture <- true;
 							e
 							e
 						| _ ->
 						| _ ->

+ 11 - 0
genhl.ml

@@ -1707,6 +1707,17 @@ and eval_expr ctx e =
 			let rv = (match rtype ctx r with HRef t -> alloc_reg ctx v | _ -> invalid()) in
 			let rv = (match rtype ctx r with HRef t -> alloc_reg ctx v | _ -> invalid()) in
 			op ctx (ORef (r,rv));
 			op ctx (ORef (r,rv));
 			r
 			r
+		| "$setref", [e1;e2] ->
+			let rec loop e = match e.eexpr with
+				| TParenthesis e1 | TMeta(_,e1) | TCast(e1,None) -> loop e1
+				| TLocal v -> v
+				| _ -> invalid()
+			in
+			let v = loop e1 in
+			let r = alloc_reg ctx v in
+			let rv = eval_to ctx e2 (match rtype ctx r with HRef t -> t | _ -> invalid()) in
+			op ctx (OSetref (r,rv));
+			r
 		| "$ttype", [v] ->
 		| "$ttype", [v] ->
 			let r = alloc_tmp ctx HType in
 			let r = alloc_tmp ctx HType in
 			op ctx (OType (r,to_type ctx v.etype));
 			op ctx (OType (r,to_type ctx v.etype));

+ 3 - 0
tests/unit/src/unit/Test.hx

@@ -331,6 +331,9 @@ class Test {
 			#if python
 			#if python
 			new TestPython(),
 			new TestPython(),
 			#end
 			#end
+			#if hl
+			new TestHL(),
+			#end
 			#if php
 			#if php
 			new TestPhp(),
 			new TestPhp(),
 			#end
 			#end

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

@@ -0,0 +1,25 @@
+package unit;
+
+class TestHL extends Test {
+
+	//private function refTest(i:hl.types.Ref<Int>):Void
+	//{
+		//i *= 2;
+	//}
+
+	private function refTestAssign(i:hl.types.Ref<Int>):Void
+	{
+		i.set(2);
+	}
+
+	public function testRef()
+	{
+		var i = 10;
+		refTestAssign(i);
+		eq(i, 2);
+
+		//var i = 10;
+		//refTest(i);
+		//eq(i, 20);
+	}
+}