Browse Source

[lua] more guards and tests for lua multireturn

Justin Donaldson 9 years ago
parent
commit
20c827628b
2 changed files with 32 additions and 0 deletions
  1. 4 0
      src/generators/genlua.ml
  2. 28 0
      tests/unit/src/unit/TestLua.hx

+ 4 - 0
src/generators/genlua.ml

@@ -1785,6 +1785,7 @@ let transform_multireturn ctx = function
 						let e = Type.map_expr loop e in
 						mk_mr_box ctx e
 
+					(* Don't bother wrapping multireturn function results if we don't use the return values *)
 					| TBlock el ->
 						let el2 = List.map (fun x ->
 						    match x.eexpr with
@@ -1797,6 +1798,9 @@ let transform_multireturn ctx = function
 					(* if we found a field access for a multi-return local - that's fine, because it'll be generated as a local var *)
 					| TField ({ eexpr = TLocal v}, _) when Meta.has Meta.MultiReturn v.v_meta ->
 						e
+					| TReturn Some(e2) when is_multireturn e2.etype ->
+						abort "You cannot return a multireturn type from a haxe function" c.cl_pos;
+						e
 
 					(*
 						if we found usage of local var we previously marked with @:multiReturn as a value itself,

+ 28 - 0
tests/unit/src/unit/TestLua.hx

@@ -8,11 +8,13 @@ class TestLua extends Test {
 		eq(lua.Lua.type(untyped __lua__("multi")), "table");
 		eq(l, "table");
 	}
+
 	function testMultiReturnPlainFunctionCall(){
 		var multi : Multi = untyped MultiCall.doit();
 		// this shouldn't box the result
 		eq(untyped __lua__("multi"), null);
 	}
+
 	function testMultiReturnValue(){
 		var multi : Multi = untyped MultiCall.doit();
 		var l = lua.Lua.type(multi.b);
@@ -20,6 +22,29 @@ class TestLua extends Test {
 		eq(untyped __lua__("multi"), null);
 		eq(l, "string");
 	}
+
+	function testMultiReturnArgument(){
+		// make sure multireturns passed as arguments are wrapped
+		eq(MultiCall.acceptMr(untyped MultiCall.doit()), true);
+	}
+
+	function testMultiReturnValueHandled(){
+		// make sure that multireturn is not wrapped if return values not used
+		var old_hx_box_mr = untyped _hx_box_mr;
+		var called = false;
+		untyped _hx_box_mr = function(){
+			called = true;
+		}
+		var k = lua.NativeStringTools.find("foo bar", "foo");
+		eq(called,false);
+		called = true;
+		// make sure that multireturn is wrapped if return values not used
+		var l = lua.NativeStringTools.find("foo bar", "foo");
+		var m = l + '';
+		eq(called, true);
+		untyped _hx_box_mr = old_hx_box_mr;
+	}
+
 }
 
 @:multiReturn extern class Multi {
@@ -31,4 +56,7 @@ class MultiCall {
 	public static function doit() : Dynamic {
 		return untyped __lua__("1,'hi'");	
 	}
+	public static function acceptMr(m:Multi){
+		return lua.Lua.type(m) == "table";
+	}
 }