[m-rev.] for review: contexts in .NET backend.

Tyson Dowd trd at cs.mu.OZ.AU
Fri Mar 16 11:41:48 AEDT 2001


Hi,


===================================================================


Estimated hours taken: 5
Branches: main

Add support for context output to the .NET backend.

We output 
	.line 42 'filename.m'
into the IL aseembler.  The assembler will create the appropriate
debugging information, and then the .NET debugger can do source linked
debugging.

Note that we don't handle contexts in foreign language (MC++) code yet.

compiler/il_peephole.m:
	Handle context instructions.
	
compiler/ilasm.m:
compiler/ilds.m:
	Add context instructions to the IL "instruction set".

compiler/mlds_to_il.m:
	Create context instructions whenever we have context information
	available.  


Warning: Remote host denied X11 forwarding.
TERM: Undefined variable.
? make_all.log
? zzdiff.context1
? zzlog.context1
? zzreview.context1
? zzdiff.context2
? samples/hello.il
? samples/cat.il
? samples/ultra_sub.il
? scripts/canonical_grade
cvs server: Diffing .
cvs server: Diffing bindist
cvs server: Diffing boehm_gc
cvs server: Diffing boehm_gc/Mac_files
cvs server: Diffing boehm_gc/cord
cvs server: Diffing boehm_gc/cord/private
cvs server: Diffing boehm_gc/include
cvs server: Diffing boehm_gc/include/private
cvs server: Diffing browser
cvs server: Diffing bytecode
cvs server: Diffing bytecode/test
cvs server: Diffing compiler
Index: compiler/il_peephole.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/il_peephole.m,v
retrieving revision 1.1
diff -u -r1.1 il_peephole.m
--- compiler/il_peephole.m	2000/10/14 04:00:11	1.1
+++ compiler/il_peephole.m	2001/03/16 00:32:56
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 2000 The University of Melbourne.
+% Copyright (C) 2000-2001 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
@@ -432,6 +432,7 @@
 can_call(label(_Label)) 			= no. 
 can_call(start_block(_, _Id)) 			= no.
 can_call(end_block(_, _Id)) 			= no.
+can_call(context(_, _)) 			= no.
 can_call(ret) 					= no. 
 can_call((and)) 				= no. 
 can_call(ann_catch) 				= no. 
@@ -529,10 +530,11 @@
 	% control flow, they are simply part of instr for
 	% convenience.
 :- func equivalent_to_nop(instr) = bool.
-equivalent_to_nop(comment(_)) 			= yes.
-equivalent_to_nop(start_block(scope(_), _)) 	= yes.
-equivalent_to_nop(end_block(scope(_), _)) 	= yes.
-equivalent_to_nop(nop) 				= yes. 
+equivalent_to_nop(comment(_)) 				= yes.
+equivalent_to_nop(start_block(scope(_), _)) 		= yes.
+equivalent_to_nop(end_block(scope(_), _))	 	= yes.
+equivalent_to_nop(nop) 					= yes. 
+equivalent_to_nop(context(_, _)) 			= yes. 
 
 equivalent_to_nop(start_block(try, _))			= no.
 equivalent_to_nop(end_block(try, _))			= no.
@@ -654,6 +656,7 @@
 can_branch(end_block(_, _)) 				= no.
 can_branch(comment(_)) 					= no.
 can_branch(start_block(_, _)) 				= no.
+can_branch(context(_, _)) 				= no.
 can_branch(nop) 					= no. 
 can_branch(label(_Label)) 				= no. 
 can_branch(call(_MethodRef)) 				= no. 
Index: compiler/ilasm.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ilasm.m,v
retrieving revision 1.4
diff -u -r1.4 ilasm.m
--- compiler/ilasm.m	2001/01/12 03:41:05	1.4
+++ compiler/ilasm.m	2001/03/16 00:32:57
@@ -735,6 +735,13 @@
 	io__write_int(Id),
 	io__write_string(" (try block)").
 
+output_instr(context(File, Line)) -->
+	io__write_string(".line "),
+	io__write_int(Line),
+	io__write_string(" '"),
+	io__write_string(File),
+	io__write_string("'\n").
+
 output_instr(call(MethodRef)) --> 
 	io__write_string("call\t"),
 	output_methodref(MethodRef).
Index: compiler/ilds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ilds.m,v
retrieving revision 1.1
diff -u -r1.1 ilds.m
--- compiler/ilds.m	2000/10/14 04:00:11	1.1
+++ compiler/ilds.m	2001/03/16 00:32:57
@@ -194,11 +194,13 @@
 
 	% NOT INSTRUCTIONS AT ALL
 	% These are just added to the IL instructions to make it easy to
-	% generate instructions.
+	% generate instructions and include debugging information.
 	--->	comment(string)
 	;	label(label)				% a label 
 	;	start_block(blocktype, blockid)		% new block 
 	;	end_block(blocktype, blockid)		% end block
+	;	context(string, int)			% context of following 
+							% code (filename, line)
 
 	% BASE INSTRUCTIONS
 
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.13
diff -u -r1.13 mlds_to_il.m
--- compiler/mlds_to_il.m	2001/02/20 07:52:18	1.13
+++ compiler/mlds_to_il.m	2001/03/16 00:33:00
@@ -324,6 +324,7 @@
 			% scope.
 		il_info_get_locals_list(Locals),
 		{ InstrsTree = tree__list([
+			context_node(Context),
 			instr_node(start_block(scope(Locals), BlockId)),
 			InstrsTree0, 
 			MaybeRet,
@@ -349,7 +350,7 @@
 
 
 generate_method_defn(DataDefn) --> 
-	{ DataDefn = defn(data(DataName), _Context, _DeclsFlags, Entity) },
+	{ DataDefn = defn(data(DataName), Context, _DeclsFlags, Entity) },
 	il_info_get_module_name(ModuleName),
 	{ ClassName = mlds_module_name_to_class_name(ModuleName) },
 
@@ -377,11 +378,6 @@
 		{ FieldRef = make_fieldref(il_array_type,
 			ClassName, FieldName) },
 
-		{ AllocComment = comment_node(
-			string__append("allocation for ", FieldName)) },
-		{ InitComment = comment_node(
-			string__append("initializer for ", FieldName)) },
-
 			% If we had to allocate memory, the code
 			% we generate looks like this:
 			%
@@ -424,12 +420,22 @@
 
 			% Add a store after the alloc instrs (if necessary)
 		{ AllocInstrs = list__condense(tree__flatten(
-			tree(AllocComment,
-			tree(AllocInstrsTree, StoreAllocTree)))) },
+			tree__list([
+				context_node(Context),
+				comment_node(string__append("allocation for ",
+					FieldName)),
+				AllocInstrsTree, 
+				StoreAllocTree]))) },
+
 			% Add a load before the init instrs (if necessary)
 		{ InitInstrs = list__condense(tree__flatten(
-			tree(InitComment,
-			tree(LoadTree, tree(InitInstrTree, StoreInitTree))))) },
+			tree__list([
+				context_node(Context),
+				comment_node(string__append("initializer for ",
+					FieldName)),
+				LoadTree,
+				InitInstrTree,
+				StoreInitTree]))) },
 		
 			% Add these instructions to the lists of
 			% allocation/initialization instructions.
@@ -516,7 +522,7 @@
 :- pred generate_defn_initializer(mlds__defn, instr_tree, instr_tree, 
 	il_info, il_info).
 :- mode generate_defn_initializer(in, in, out, in, out) is det.
-generate_defn_initializer(defn(Name, _Context, _DeclFlags, Entity),
+generate_defn_initializer(defn(Name, Context, _DeclFlags, Entity),
 		Tree0, Tree) --> 
 	( 
 		{ Name = data(DataName) },
@@ -544,6 +550,7 @@
 				Comment) },
 			{ Tree = tree__list([
 				Tree0,
+				context_node(Context),
 				comment_node(Comment),
 				LoadMemRefInstrs,
 				AllocInstrs,
@@ -679,7 +686,7 @@
 :- pred statement_to_il(mlds__statement, instr_tree, il_info, il_info).
 :- mode statement_to_il(in, out, in, out) is det.
 
-statement_to_il(statement(block(Defns, Statements), _Context), Instrs) -->
+statement_to_il(statement(block(Defns, Statements), Context), Instrs) -->
 	il_info_get_module_name(ModuleName),
 	il_info_get_next_block_id(BlockId),
 	{ list__map(defn_to_local(ModuleName), Defns, Locals) },
@@ -690,7 +697,8 @@
 	{ list__map((pred((K - V)::in, (K - W)::out) is det :- 
 		W = mlds_type_to_ilds_type(V)), Locals, ILLocals) },
 	{ Instrs = tree__list([
-			node([start_block(scope(ILLocals), BlockId)]),
+			context_node(Context),
+			instr_node(start_block(scope(ILLocals), BlockId)),
 			InitInstrsTree,
 			comment_node("block body"),
 			BlockInstrs,
@@ -698,11 +706,12 @@
 			]) },
 	il_info_remove_locals(Locals).
 
-statement_to_il(statement(atomic(Atomic), _Context), Instrs) -->
-	atomic_statement_to_il(Atomic, Instrs).
+statement_to_il(statement(atomic(Atomic), Context), Instrs) -->
+	atomic_statement_to_il(Atomic, AtomicInstrs),
+	{ Instrs = tree(context_node(Context), AtomicInstrs) }.
 
 statement_to_il(statement(call(Sig, Function, _This, Args, Returns, IsTail), 
-		_Context), Instrs) -->
+		Context), Instrs) -->
 	( { IsTail = tail_call } ->
 		% For tail calls, to make the code verifiable, 
 		% we need a `ret' instruction immediately after
@@ -739,6 +748,7 @@
 			ReturnParam, ParamsList))] }
 	),		
 	{ Instrs = tree__list([
+			context_node(Context),
 			comment_node("call"), 
 			LoadMemRefInstrs,
 			ArgsLoadInstrs,
@@ -750,12 +760,13 @@
 			]) }.
 
 statement_to_il(statement(if_then_else(Condition, ThenCase, ElseCase), 
-		_Context), Instrs) -->
+		Context), Instrs) -->
 	generate_condition(Condition, ConditionInstrs, ElseLabel),
 	il_info_make_next_label(DoneLabel),
 	statement_to_il(ThenCase, ThenInstrs),
 	maybe_map_fold(statement_to_il, ElseCase, empty, ElseInstrs),
 	{ Instrs = tree__list([
+		context_node(Context),
 		comment_node("if then else"),
 		ConditionInstrs,
 		comment_node("then case"),
@@ -776,12 +787,13 @@
 	{ error("mlds_to_il.m: `switch' not supported") }.
 
 statement_to_il(statement(while(Condition, Body, AtLeastOnce), 
-		_Context), Instrs) -->
+		Context), Instrs) -->
 	generate_condition(Condition, ConditionInstrs, EndLabel),
 	il_info_make_next_label(StartLabel),
 	statement_to_il(Body, BodyInstrs),
 	{ AtLeastOnce = no,
 		Instrs = tree__list([
+			context_node(Context),
 			comment_node("while"),
 			instr_node(label(StartLabel)),
 			ConditionInstrs,
@@ -793,6 +805,7 @@
 			% XXX this generates a branch over branch which
 			% is suboptimal.
 		Instrs = tree__list([
+			context_node(Context),
 			comment_node("while (actually do ... while)"),
 			instr_node(label(StartLabel)),
 			BodyInstrs,
@@ -804,10 +817,11 @@
 	}.
 
 
-statement_to_il(statement(return(Rvals), _Context), Instrs) -->
+statement_to_il(statement(return(Rvals), Context), Instrs) -->
 	( { Rvals = [Rval] } ->
 		load(Rval, LoadInstrs),
 		{ Instrs = tree__list([
+			context_node(Context),
 			LoadInstrs,
 			instr_node(ret)]) }
 	;
@@ -815,15 +829,25 @@
 		{ sorry(this_file, "multiple return values") }
 	).
 
-statement_to_il(statement(label(Label), _Context), Instrs) -->
+statement_to_il(statement(label(Label), Context), Instrs) -->
 	{ string__format("label %s", [s(Label)], Comment) },
-	{ Instrs = node([comment(Comment), label(Label)]) }.
+	{ Instrs = node([
+			comment(Comment),
+			context_instr(Context),
+			label(Label)
+		]) }.
+
+
 
-statement_to_il(statement(goto(Label), _Context), Instrs) -->
+statement_to_il(statement(goto(Label), Context), Instrs) -->
 	{ string__format("goto %s", [s(Label)], Comment) },
-	{ Instrs = node([comment(Comment), br(label_target(Label))]) }.
+	{ Instrs = node([
+			comment(Comment),
+			context_instr(Context),
+			br(label_target(Label))
+		]) }.
 
-statement_to_il(statement(do_commit(Ref), _Context), Instrs) -->
+statement_to_il(statement(do_commit(Ref), Context), Instrs) -->
 
 	% For commits, we use exception handling.
 	%
@@ -836,13 +860,14 @@
 
 	load(Ref, RefLoadInstrs),
 	{ Instrs = tree__list([
-		comment_node("do_commit/1"),
-		RefLoadInstrs,
-		instr_node(throw)
+			context_node(Context),
+			comment_node("do_commit/1"),
+			RefLoadInstrs,
+			instr_node(throw)
 		]) }.
 
 statement_to_il(statement(try_commit(Ref, GoalToTry, CommitHandlerGoal), 
-		_Context), Instrs) -->
+		Context), Instrs) -->
 
 	% For commits, we use exception handling.
 	%
@@ -873,6 +898,7 @@
 			unexpected(this_file, "non-class for commit ref")
 	},	
 	{ Instrs = tree__list([
+		context_node(Context),
 		comment_node("try_commit/3"),
 
 		instr_node(start_block(try, TryBlockId)),
@@ -890,11 +916,12 @@
 
 		]) }.
 
-statement_to_il(statement(computed_goto(Rval, MLDSLabels), _Context), 
+statement_to_il(statement(computed_goto(Rval, MLDSLabels), Context), 
 		Instrs) -->
 	load(Rval, RvalLoadInstrs),
 	{ Targets = list__map(func(L) = label_target(L), MLDSLabels) },
 	{ Instrs = tree__list([
+		context_node(Context),
 		comment_node("computed goto"),
 		RvalLoadInstrs,
 		instr_node(switch(Targets))
@@ -921,6 +948,8 @@
 		{ ClassName = mlds_module_name_to_class_name(NewModuleName) },
 		signature(_, RetType, Params) =^ signature, 
 			% If there is a return value, put it in succeeded.
+			% XXX this is incorrect for functions, which might
+			% return a useful value.
 		{ RetType = void ->
 			StoreReturnInstr = []
 		;
@@ -2425,7 +2454,7 @@
 :- pred call_field_constructor(list(ilds__id), mlds__defn, list(instr)).
 :- mode call_field_constructor(in, in, out) is det.
 call_field_constructor(ObjClassName, MLDSDefn, Instrs) :-
-	MLDSDefn = mlds__defn(EntityName, _Context, _DeclFlags, Entity), 
+	MLDSDefn = mlds__defn(EntityName, Context, _DeclFlags, Entity), 
 	( 
 		Entity = mlds__data(Type, _Initializer),
 		EntityName = data(DataName)
@@ -2438,14 +2467,18 @@
 			ILType = il_envptr_type
 		->
 			ClassName = il_envptr_class_name,
-			Instrs = [ldarg(index(0)),
+			Instrs = [
+				context_instr(Context),
+				ldarg(index(0)),
 				newobj_constructor(ClassName),
 				stfld(FieldRef)]
 		;
 			ILType = il_commit_type
 		->
 			ClassName = il_commit_class_name,
-			Instrs = [ldarg(index(0)),
+			Instrs = [
+				context_instr(Context),
+				ldarg(index(0)),
 				newobj_constructor(ClassName),
 				stfld(FieldRef)]
 		;
@@ -2679,6 +2712,17 @@
 	% Use this to make comments into trees easily.
 :- func comment_node(string) = instr_tree.
 comment_node(S) = node([comment(S)]).
+
+	% Use this to make contexts into trees easily.
+:- func context_node(mlds__context) = instr_tree.
+context_node(Context) = node([context_instr(Context)]).
+
+:- func context_instr(mlds__context) = instr.
+context_instr(Context) = context(FileName, LineNumber) :-
+	ProgContext = mlds__get_prog_context(Context),
+	term__context_file(ProgContext, FileName),
+	term__context_line(ProgContext, LineNumber).
+
 
 	% Use this to make instructions into trees easily.
 :- func instr_node(instr) = instr_tree.
cvs server: Diffing compiler/notes
cvs server: Diffing debian
cvs server: Diffing deep
cvs server: Diffing detail
cvs server: Diffing doc
cvs server: Diffing extras
cvs server: Diffing extras/aditi
cvs server: Diffing extras/cgi
cvs server: Diffing extras/complex_numbers
cvs server: Diffing extras/complex_numbers/samples
cvs server: Diffing extras/complex_numbers/tests
cvs server: Diffing extras/concurrency
cvs server: Diffing extras/curs
cvs server: Diffing extras/curs/samples
cvs server: Diffing extras/curses
cvs server: Diffing extras/curses/sample
cvs server: Diffing extras/dynamic_linking
cvs server: Diffing extras/exceptions
cvs server: Diffing extras/graphics
cvs server: Diffing extras/graphics/mercury_opengl
cvs server: Diffing extras/graphics/mercury_tcltk
cvs server: Diffing extras/graphics/samples
cvs server: Diffing extras/graphics/samples/calc
cvs server: Diffing extras/graphics/samples/maze
cvs server: Diffing extras/graphics/samples/pent
cvs server: Diffing extras/lazy_evaluation
cvs server: Diffing extras/lazy_evaluation/examples
cvs server: Diffing extras/lex
cvs server: Diffing extras/lex/samples
cvs server: Diffing extras/logged_output
cvs server: Diffing extras/moose
cvs server: Diffing extras/moose/samples
cvs server: Diffing extras/morphine
cvs server: Diffing extras/morphine/non-regression-tests
cvs server: Diffing extras/morphine/scripts
cvs server: Diffing extras/morphine/source
cvs server: Diffing extras/odbc
cvs server: Diffing extras/opium_m
cvs server: Diffing extras/opium_m/non-regression-tests
cvs server: Diffing extras/opium_m/scripts
cvs server: Diffing extras/opium_m/source
cvs server: Diffing extras/posix
cvs server: Diffing extras/quickcheck
cvs server: Diffing extras/quickcheck/tutes
cvs server: Diffing extras/references
cvs server: Diffing extras/references/samples
cvs server: Diffing extras/references/tests
cvs server: Diffing extras/stream
cvs server: Diffing extras/trailed_update
cvs server: Diffing extras/trailed_update/samples
cvs server: Diffing extras/trailed_update/tests
cvs server: Diffing extras/xml
cvs server: Diffing extras/xml/samples
cvs server: Diffing java
cvs server: Diffing library
cvs server: Diffing lp_solve
cvs server: Diffing lp_solve/lp_examples
cvs server: Diffing profiler
cvs server: Diffing quickcheck
cvs server: Diffing quickcheck/tutes
cvs server: Diffing readline
cvs server: Diffing readline/doc
cvs server: Diffing readline/examples
cvs server: Diffing readline/shlib
cvs server: Diffing readline/support
cvs server: Diffing robdd
cvs server: Diffing runtime
cvs server: Diffing runtime/GETOPT
cvs server: Diffing runtime/machdeps
cvs server: Diffing samples
cvs server: Diffing samples/c_interface
cvs server: Diffing samples/c_interface/c_calls_mercury
cvs server: Diffing samples/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/c_interface/mercury_calls_c
cvs server: Diffing samples/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/c_interface/mercury_calls_fortran
cvs server: Diffing samples/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/diff
cvs server: Diffing samples/muz
cvs server: Diffing samples/rot13
cvs server: Diffing samples/solutions
cvs server: Diffing samples/tests
cvs server: Diffing samples/tests/c_interface
cvs server: Diffing samples/tests/c_interface/c_calls_mercury
cvs server: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs server: Diffing samples/tests/c_interface/mercury_calls_c
cvs server: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs server: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs server: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs server: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs server: Diffing samples/tests/diff
cvs server: Diffing samples/tests/muz
cvs server: Diffing samples/tests/rot13
cvs server: Diffing samples/tests/solutions
cvs server: Diffing samples/tests/toplevel
cvs server: Diffing scripts
cvs server: Diffing tools
cvs server: Diffing trace
cvs server: Diffing trax
cvs server: Diffing trial
cvs server: Diffing util


-- 
       Tyson Dowd           # 
                            #  Surreal humour isn't everyone's cup of fur.
     trd at cs.mu.oz.au        # 
http://www.cs.mu.oz.au/~trd #
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list