Browse Source

Added initial SAFE_POINT code

Hugh Sanderson 15 years ago
parent
commit
535f78e79d
1 changed files with 28 additions and 0 deletions
  1. 28 0
      gencpp.ml

+ 28 - 0
gencpp.ml

@@ -139,6 +139,7 @@ type context =
 	mutable ctx_return_from_internal_node : bool;
 	mutable ctx_debug : bool;
 	mutable ctx_debug_type : bool;
+	mutable ctx_do_safe_point : bool;
 	mutable ctx_real_this_ptr : bool;
 	mutable ctx_dynamic_this_ptr : bool;
 	mutable ctx_static_id_curr : int;
@@ -160,6 +161,7 @@ let new_context writer debug =
 	ctx_debug_type = debug;
 	ctx_return_from_block = false;
 	ctx_return_from_internal_node = false;
+	ctx_do_safe_point = false;
 	ctx_real_this_ptr = true;
 	ctx_dynamic_this_ptr = false;
 	ctx_static_id_curr = 0;
@@ -644,6 +646,23 @@ let tmatch_params_to_args params =
 		List.fold_left
 			(fun acc (v,t) -> incr n; match v with None -> acc | Some v -> (v,t,!n) :: acc) [] l)
 
+exception AlreadySafe;;
+exception PossibleRecursion;;
+
+let expression_needs_safe_point expression =
+	try (
+	let rec needs_safe expression always_executed  =
+	   (* TODO - fill this out *)
+		Type.iter (fun expr -> match expr.eexpr with
+			| TNew (_,_,_) when always_executed -> raise AlreadySafe
+			| TCall (_,_) -> raise PossibleRecursion
+			| _ -> needs_safe expr false;
+			) expression in
+	needs_safe expression true;
+	false;
+	) with  AlreadySafe -> false
+	      | PossibleRecursion -> true
+;;
 
 (*
   This is the big one.
@@ -666,6 +685,8 @@ let rec gen_expression ctx retval expression =
 	ctx.ctx_return_from_block <- false;
 	let return_from_internal_node = ctx.ctx_return_from_internal_node in
 	ctx.ctx_return_from_internal_node <- false;
+	let do_safe_point = ctx.ctx_do_safe_point in
+	ctx.ctx_do_safe_point <- false;
 
 	(* Annotate source code with debug - can get a bit verbose.  Mainly for debugging code gen,
 		rather than the run time *)
@@ -783,13 +804,16 @@ let rec gen_expression ctx retval expression =
 
 		let pop_real_this_ptr = clear_real_this_ptr ctx true in
 
+		let do_safe = expression_needs_safe_point func_def.tf_expr in
 		if (block) then begin
 			writer#begin_block;
+			ctx.ctx_do_safe_point <- do_safe;
 			gen_expression ctx false func_def.tf_expr;
 			output_i "return null();\n";
 			writer#end_block;
 		end else begin
 			writer#begin_block;
+			if (do_safe) then output_i "__SAFE_POINT;\n";
 			(* Save old values, and equalize for new input ... *)
 			let old_used = ctx.ctx_static_id_used in
 			let old_curr = ctx.ctx_static_id_curr in
@@ -1075,6 +1099,7 @@ let rec gen_expression ctx retval expression =
 			)
 		end else begin
 			writer#begin_block;
+			if (do_safe_point) then output_i "__SAFE_POINT\n";
 			(* Save old values, and equalize for new input ... *)
 			let old_used = ctx.ctx_static_id_used in
 			let old_curr = ctx.ctx_static_id_curr in
@@ -1222,6 +1247,7 @@ let rec gen_expression ctx retval expression =
 		output_i "";
 		gen_expression ctx false loop;
 		output ";\n";
+		output_i "__SAFE_POINT\n";
 		ctx.ctx_writer#end_block;
 	| TIf (condition, if_expr, optional_else_expr)  ->
 		let output_if_expr expr terminate =
@@ -1275,6 +1301,7 @@ let rec gen_expression ctx retval expression =
 			output  "while(";
 			gen_expression ctx true condition;
 			output ")";
+			ctx.ctx_do_safe_point <- true;
 			gen_expression ctx false repeat
 	| TWhile (condition, repeat, Ast.DoWhile ) ->
 			output "do";
@@ -1495,6 +1522,7 @@ let gen_field ctx class_name ptr_name is_static is_external is_interface field =
 			output (gen_arg_list function_def.tf_args "__o_");
 			output ")";
 
+			ctx.ctx_do_safe_point <- expression_needs_safe_point function_def.tf_expr;
 			if (has_default_values function_def.tf_args) then begin
 				ctx.ctx_writer#begin_block;
 				generate_default_values ctx function_def.tf_args "__o_";