2
0
Эх сурвалжийг харах

added __keys__ , free registers, simplified boot.

Nicolas Cannasse 20 жил өмнө
parent
commit
f438c87cb3
1 өөрчлөгдсөн 35 нэмэгдсэн , 14 устгасан
  1. 35 14
      genswf8.ml

+ 35 - 14
genswf8.ml

@@ -302,6 +302,10 @@ let alloc_reg ctx =
 	if ctx.reg_count > ctx.reg_max then ctx.reg_max <- ctx.reg_count;
 	ctx.reg_count
 
+let free_reg ctx r p =
+	if r <> ctx.reg_count then stack_error p;
+	ctx.reg_count <- ctx.reg_count - 1
+
 let best_eq t = 
 	match follow t with
 	| TMono _
@@ -631,6 +635,7 @@ and gen_switch ctx retval e cases def =
 		jmp ctx;
 	) dispatch in		
 	jend();
+	free_reg ctx r e.epos;
 	List.iter (fun j -> j()) jends
 
 and gen_match ctx retval e cases def =
@@ -664,6 +669,7 @@ and gen_match ctx retval e cases def =
 			(j,args,x) :: loop l
 	in
 	let dispatch = loop cases in
+	free_reg ctx rtag e.epos;
 	(match def with
 	| None -> if retval then push ctx [VNull]
 	| Some e -> gen_expr ctx retval e);
@@ -687,6 +693,7 @@ and gen_match ctx retval e cases def =
 		jmp ctx;
 	) dispatch in
 	jend();
+	free_reg ctx renum e.epos;
 	List.iter (fun j -> j()) jends
 
 and gen_binop ctx retval op e1 e2 =
@@ -790,6 +797,27 @@ and gen_call ctx e el =
 		push ctx [VInt nargs];
 		let k = gen_access ctx true e in
 		new_call ctx k nargs
+	| TLocal "__keys__", [e] ->
+		let r = alloc_reg ctx in
+		push ctx [VInt 0; VStr "Array"];
+		new_call ctx VarStr 0;
+		write ctx (ASetReg r);
+		write ctx APop;
+		gen_expr ctx true e;
+		write ctx AEnum2;
+		ctx.stack_size <- ctx.stack_size + 1; (* fake *)
+		let loop = pos ctx in
+		write ctx (ASetReg 0);
+		push ctx [VNull];
+		write ctx AEqual;
+		let jump_end = cjmp ctx in
+		push ctx [VReg 0; VInt 1; VReg r; VStr "push"];
+		call ctx VarObj 1;
+		write ctx APop;
+		loop false;
+		jump_end();
+		push ctx [VReg r];
+		free_reg ctx r e.epos;
 	| _ , _ ->
 		let nargs = List.length el in
 		List.iter (gen_expr ctx true) (List.rev el);
@@ -956,6 +984,7 @@ and gen_expr_2 ctx retval e =
 		call ctx VarObj 0;
 		write ctx ANot;
 		let j_end = cjmp ctx in
+		let b = open_block ctx in
 		define_var ctx v (Some (fun() -> 
 			push ctx [VInt 0; VReg r; VStr "next"];
 			call ctx VarObj 0;
@@ -964,7 +993,9 @@ and gen_expr_2 ctx retval e =
 		j_begin false;
 		j_end();
 		loop_end cont_pos;
-		if retval then getvar ctx (access_local ctx v)
+		if retval then getvar ctx (access_local ctx v);
+		b();
+		free_reg ctx r null_pos
 
 and gen_expr ctx retval e =
 	let old = ctx.stack_size in
@@ -1091,20 +1122,10 @@ let gen_boot ctx m =
 	write ctx AEval;
 	write ctx (ASetReg 0);
 	write ctx APop;
-	(* r0._global = eval("_global") *)
-	push ctx [VReg 0; VStr "_global"; VStr "_global"];
-	write ctx AEval;
-	write ctx AObjSet;
-	(* r0._root = eval("_root") *)
-	push ctx [VReg 0; VStr "_root"; VStr "_root"];
-	write ctx AEval;
-	write ctx AObjSet;
-	(* r0.current = eval("this") *)
-	push ctx [VReg 0; VStr "current"; VStr "this"];
+	(* r0.__init(eval("this")) *)
+	push ctx [VStr "this"];
 	write ctx AEval;
-	write ctx AObjSet;
-	(* Boot.__init() *)
-	push ctx [VInt 0; VReg 0; VStr "__init"];
+	push ctx [VInt 1; VReg 0; VStr "__init"];
 	call ctx VarObj 0;
 	write ctx APop