diff --git a/src/compiler/hxb/hxbReader.ml b/src/compiler/hxb/hxbReader.ml index 6b4304d6be4..0ee9da82e8d 100644 --- a/src/compiler/hxb/hxbReader.ml +++ b/src/compiler/hxb/hxbReader.ml @@ -33,6 +33,7 @@ class hxb_reader val vars = Hashtbl.create 0 val mutable type_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None) val mutable field_type_parameters = Array.make 0 (mk_type_param "" t_dynamic None) + val mutable local_type_parameters = [] val mutable tvoid = None method get_tvoid = @@ -594,6 +595,18 @@ class hxb_reader let i = self#read_uleb128 in (* Printf.eprintf " Get type type param %d\n" i; *) (type_type_parameters.(i)).ttp_type + | 7 -> + let k = self#read_uleb128 in + let i = self#read_uleb128 in + let rec loop left params = match params with + | _ :: params when left > 0 -> + loop (left - 1) params + | params :: _ -> + params.(i).ttp_type + | _ -> + error (Printf.sprintf "Bad index into local params: %i" k) + in + loop k local_type_parameters | 10 -> TInst(self#read_class_ref,[]) | 11 -> @@ -735,6 +748,7 @@ class hxb_reader let args = self#read_list (fun () -> self#read_tfunction_arg) in let r = self#read_type_instance in let e = self#read_texpr in + let args = List.map (fun ((v,close),cto) -> close(); (v,cto)) args in { tf_args = args; tf_type = r; @@ -757,17 +771,24 @@ class hxb_reader | _ -> assert false method read_var = + let close = ref (fun () -> ()) in (* TODO: awkward *) let id = IO.read_i32 ch in let name = self#read_string in - let t = self#read_type_instance in - let kind = self#read_var_kind in let extra = self#read_option (fun () -> + let params = ref [] in + self#read_type_parameters null_module ([],name) (fun a -> + local_type_parameters <- a :: local_type_parameters; + params := Array.to_list a; + close := (fun () -> local_type_parameters <- List.tl local_type_parameters) + ); let vexpr = self#read_option (fun () -> self#read_texpr) in { - v_params = []; (* TODO *) + v_params = !params; v_expr = vexpr; }; ) in + let t = self#read_type_instance in + let kind = self#read_var_kind in let flags = IO.read_i32 ch in let meta = self#read_metadata in let pos = self#read_pos in @@ -782,7 +803,7 @@ class hxb_reader v_flags = flags; } in Hashtbl.add vars id v; - v + v,!close method read_texpr = let t = self#read_type_instance in @@ -803,10 +824,14 @@ class hxb_reader (* vars 20-29 *) | 20 -> TLocal (Hashtbl.find vars (IO.read_i32 ch)) - | 21 -> TVar (self#read_var,None) + | 21 -> + let v,close = self#read_var in + close(); + TVar (v,None) | 22 -> - let v = self#read_var in + let v,close = self#read_var in let e = self#read_texpr in + close(); TVar (v, Some e) (* blocks 30-49 *) @@ -887,8 +912,9 @@ class hxb_reader | 83 -> let e1 = self#read_texpr in let catches = self#read_list (fun () -> - let v = self#read_var in + let v,close = self#read_var in let e = self#read_texpr in + close(); (v,e) ) in TTry(e1,catches) @@ -901,9 +927,10 @@ class hxb_reader let e2 = self#read_texpr in TWhile(e1,e2,DoWhile) | 86 -> - let v = self#read_var in + let v,close = self#read_var in let e1 = self#read_texpr in let e2 = self#read_texpr in + close(); TFor(v,e1,e2) (* control flow 90-99 *) diff --git a/src/compiler/hxb/hxbWriter.ml b/src/compiler/hxb/hxbWriter.ml index e66bd2e8d74..a4f1f226583 100644 --- a/src/compiler/hxb/hxbWriter.ml +++ b/src/compiler/hxb/hxbWriter.ml @@ -229,6 +229,7 @@ class ['a] hxb_writer val mutable ttp_key = None val mutable type_type_parameters = new pool val mutable field_type_parameters = new pool + val mutable local_type_parameters = [] (* Chunks *) @@ -330,10 +331,25 @@ class ['a] hxb_writer let i = type_type_parameters#get (snd c.cl_path) in chunk#write_byte 6; chunk#write_uleb128 i + with Not_found -> try + let rec loop k l = match l with + | [] -> + raise Not_found + | pool :: l -> + begin try + let i = pool#get (snd c.cl_path) in + chunk#write_byte 7; + chunk#write_uleb128 k; + chunk#write_uleb128 i + with Not_found -> + loop (k + 1) l + end + in + loop 0 local_type_parameters with Not_found -> (* error ("Unbound type parameter " ^ (s_type_path c.cl_path)) *) Printf.eprintf "%s Unbound type parameter %s\n" todo_error (s_type_path c.cl_path); - chunk#write_byte 0 + chunk#write_byte 40 end | TInst(c,[]) -> chunk#write_byte 10; @@ -738,19 +754,30 @@ class ['a] hxb_writer in chunk#write_byte b + method set_local_type_parameters (params : typed_type_param list) = + let pool = new pool in + local_type_parameters <- pool :: local_type_parameters; + List.iter (fun ttp -> + ignore(pool#add ttp.ttp_name ttp); + ) params + method write_var v = + let close = ref (fun () -> ()) in (* TODO: awkward *) chunk#write_i32 v.v_id; chunk#write_string v.v_name; - self#write_type_instance v.v_type; - self#write_var_kind v.v_kind; chunk#write_option v.v_extra (fun ve -> - (* TODO *) - (* chunk#write_list ve.v_params self#write_typed_type_param; *) + self#set_local_type_parameters ve.v_params; + chunk#write_list ve.v_params self#write_type_parameter_forward; + chunk#write_list ve.v_params self#write_type_parameter_data; chunk#write_option ve.v_expr self#write_texpr; + close := (fun () -> local_type_parameters <- List.tl local_type_parameters) ); + self#write_type_instance v.v_type; + self#write_var_kind v.v_kind; chunk#write_i32 v.v_flags; self#write_metadata v.v_meta; self#write_pos v.v_pos; + !close method write_texpr (e : texpr) = let rec loop e = @@ -787,11 +814,12 @@ class ['a] hxb_writer chunk#write_i32 v.v_id; | TVar(v,None) -> chunk#write_byte 21; - self#write_var v; + self#write_var v () | TVar(v,Some e1) -> chunk#write_byte 22; - self#write_var v; + let close = self#write_var v in loop e1; + close() (* blocks 30-49 *) | TBlock [] -> chunk#write_byte 30; @@ -820,8 +848,9 @@ class ['a] hxb_writer | TFunction tf -> chunk#write_byte 50; chunk#write_list tf.tf_args (fun (v,eo) -> - self#write_var v; - chunk#write_option eo loop + let close = self#write_var v in + chunk#write_option eo loop; + close(); ); self#write_type_instance tf.tf_type; loop tf.tf_expr; @@ -877,7 +906,7 @@ class ['a] hxb_writer chunk#write_byte 83; loop e1; chunk#write_list catches (fun (v,e) -> - self#write_var v; + self#write_var v (); loop e ); | TWhile(e1,e2,flag) -> @@ -886,7 +915,7 @@ class ['a] hxb_writer loop e2; | TFor(v,e1,e2) -> chunk#write_byte 86; - self#write_var v; + self#write_var v (); loop e1; loop e2; (* control flow 90-99 *) diff --git a/tests/unit/src/unit/issues/Issue10124.hx b/tests/unit/src/unit/issues/Issue10124.hx index 2963ccd265e..bca95176edc 100644 --- a/tests/unit/src/unit/issues/Issue10124.hx +++ b/tests/unit/src/unit/issues/Issue10124.hx @@ -30,12 +30,11 @@ class Issue10124 extends Test { } function test3() { - // function rest(...values:T):Array { - // return values.toArray(); - // } - // var a = rest(5, 6.2, 7); - // aeq([5, 6.2, 7], a); - // eq('Array', HelperMacros.typeString(a)); - Assert.pass(); + function rest(...values:T):Array { + return values.toArray(); + } + var a = rest(5, 6.2, 7); + aeq([5, 6.2, 7], a); + eq('Array', HelperMacros.typeString(a)); } } diff --git a/tests/unit/src/unit/issues/Issue2889.hx b/tests/unit/src/unit/issues/Issue2889.hx index cab5fc96b4f..67cbe875f4e 100644 --- a/tests/unit/src/unit/issues/Issue2889.hx +++ b/tests/unit/src/unit/issues/Issue2889.hx @@ -1,16 +1,14 @@ package unit.issues; class Issue2889 extends Test { - public function test() - { - // function mapMappable (m:Mappable, f:A->B):Mappable { - // return m.map(f); - // } - // var r = mapMappable([1], function (y) return y+1); - // var r:Array = cast r; - // eq(r.length,1); - // eq(2,r[0]); - utest.Assert.pass(); + public function test() { + function mapMappable(m:Mappable, f:A->B):Mappable { + return m.map(f); + } + var r = mapMappable([1], function(y) return y + 1); + var r:Array = cast r; + eq(r.length, 1); + eq(2, r[0]); } function testDynamic() { @@ -25,14 +23,14 @@ class Issue2889 extends Test { } function testFilterStructure() { - var a:{ function filter(f:Int->Bool):Array; } = [1, 2]; + var a:{function filter(f:Int->Bool):Array;} = [1, 2]; var b = a.filter(function(x) return x % 2 == 0); eq(1, b.length); eq(2, b[0]); } function testMapStructure() { - var a:{ function map(f:Int->Int):Array; } = [1, 2]; + var a:{function map(f:Int->Int):Array;} = [1, 2]; var b = a.map(function(x) return x * 2); eq(2, b.length); eq(2, b[0]); @@ -41,6 +39,5 @@ class Issue2889 extends Test { } private typedef Mappable = { - public function map (f:Y->X):Array; + public function map(f:Y->X):Array; } - diff --git a/tests/unit/src/unit/issues/Issue5793.hx b/tests/unit/src/unit/issues/Issue5793.hx index 4898aa7c9c0..3e3ff272c47 100644 --- a/tests/unit/src/unit/issues/Issue5793.hx +++ b/tests/unit/src/unit/issues/Issue5793.hx @@ -1,25 +1,24 @@ package unit.issues; class Issue5793 extends Test { - public function test() { - // function run1() { - // function foo (expected:Array, a:T) { - // eq(expected[0], a); - // } - // foo([2], 2); - // } - // run1(); + public function test() { + function run1() { + function foo(expected:Array, a:T) { + eq(expected[0], a); + } + foo([2], 2); + } + run1(); - // function run2() { - // function bar(expected:Array, a:A) { - // function baz(expected:Array, b:B) { - // eq(expected[0], b); - // } - // baz(expected,a); - // } - // bar([42],42); - // } - // run2(); - utest.Assert.pass(); - } + function run2() { + function bar(expected:Array, a:A) { + function baz(expected:Array, b:B) { + eq(expected[0], b); + } + baz(expected, a); + } + bar([42], 42); + } + run2(); + } } diff --git a/tests/unit/src/unit/issues/Issue6106.hx b/tests/unit/src/unit/issues/Issue6106.hx index 892e9747b84..76618daca92 100644 --- a/tests/unit/src/unit/issues/Issue6106.hx +++ b/tests/unit/src/unit/issues/Issue6106.hx @@ -3,12 +3,13 @@ package unit.issues; class Issue6106 extends unit.Test { function test() { var code = 0; - // function assertEquals(expected:T, actual:T) { - // if(expected != actual) code++; - // } + function assertEquals(expected:T, actual:T) { + if (expected != actual) + code++; + } - // var f = function() assertEquals(1, 1); - // f(); + var f = function() assertEquals(1, 1); + f(); noAssert(); } } diff --git a/tests/unit/src/unit/issues/Issue6304.hx b/tests/unit/src/unit/issues/Issue6304.hx index 319d95e84a9..688558d7bd9 100644 --- a/tests/unit/src/unit/issues/Issue6304.hx +++ b/tests/unit/src/unit/issues/Issue6304.hx @@ -2,16 +2,15 @@ package unit.issues; class Issue6304 extends unit.Test { function test() { - // eq(2, main1([], 1)); - utest.Assert.pass(); + eq(2, main1([], 1)); } - static function main1 (arr:Array<{}>, multiplier:Int) { - // function doSomething () { - // var mul:Int = multiplier; - // arr.push({}); - // return arr.length + mul; - // }; - // return doSomething(); + static function main1(arr:Array<{}>, multiplier:Int) { + function doSomething() { + var mul:Int = multiplier; + arr.push({}); + return arr.length + mul; + }; + return doSomething(); } } diff --git a/tests/unit/src/unit/issues/Issue6560.hx b/tests/unit/src/unit/issues/Issue6560.hx index c7c7c835719..9131cfeb82b 100644 --- a/tests/unit/src/unit/issues/Issue6560.hx +++ b/tests/unit/src/unit/issues/Issue6560.hx @@ -1,15 +1,13 @@ package unit.issues; class Issue6560 extends unit.Test { - - function test() { - // function foo(a:F):Array { - // if (false) foo(1); - // return if (a == null) [] else foo(null); - // } - // var bar:Array = foo(1); - // eq(0, bar.length); - utest.Assert.pass(); - } - + function test() { + function foo(a:F):Array { + if (false) + foo(1); + return if (a == null) [] else foo(null); + } + var bar:Array = foo(1); + eq(0, bar.length); + } } diff --git a/tests/unit/src/unit/issues/Issue6751.hx b/tests/unit/src/unit/issues/Issue6751.hx index 4ee52f195ba..6ac717631e3 100644 --- a/tests/unit/src/unit/issues/Issue6751.hx +++ b/tests/unit/src/unit/issues/Issue6751.hx @@ -3,20 +3,23 @@ package unit.issues; import unit.HelperMacros.typedAs; private abstract O(String) { - public function new(s) this = s; - @:to function toInt() return 42; + public function new(s) + this = s; + + @:to function toInt() + return 42; } private abstract A(T) from T {} class Issue6751 extends Test { function test() { - // function make(o:A) return o; + function make(o:A) + return o; - // var o = new O("hello"); - // var a = make(o); - // typedAs(a, (null : A)); - // eq(Std.string(a), "hello"); - utest.Assert.pass(); + var o = new O("hello"); + var a = make(o); + typedAs(a, (null : A)); + eq(Std.string(a), "hello"); } }