May 11, 2006
As of version 0.150, the offsets of the code within a delegate's function handler are not correctly calculated.  All of them seem to be set relative to the address of the first delegate declared within the scope.  This results in the following code breaking.  The windows version does not have this problem.

#class Tester
#{
#	this(void delegate() dg_) { dg = dg_; }
#	void delegate() dg;
#	void stuff() { dg(); }
#}
#
#unittest
#{
#	writefln("Starting test");
#
#	int a = 0;
#	int b = 0;
#	int c = 0;
#	int d = 0;
#
#	try
#	{
#		a++;
#		throw new Exception("test1");
#		a++;
#	}
#	catch(Exception e)
#	{
#		e.print;
#		b++;
#	}
#	finally
#	{
#		c++;
#	}
#
#	writefln("initial test.");
#
#	assert(a == 1);
#	assert(b == 1);
#	assert(c == 1);
#
#	writefln("pass");
#
#	Tester t = new Tester(
#	delegate void()
#	{
#		try
#		{
#			a++;
#			throw new Exception("test2");
#			a++;
#		}
#		catch(Exception e)
#		{
#			b++;
#			throw e;
#			b++;
#		}
#	});
#
#	try
#	{
#		c++;
#		t.stuff();
#		c++;
#	}
#	catch(Exception e)
#	{
#		d++;
#		e.print;
#	}
#
#	assert(a == 2);
#	assert(b == 2);
#	assert(c == 2);
#	assert(d == 1);
#
#
#	int q0 = 0;
#	int q1 = 0;
#	int q2 = 0;
#	int q3 = 0;
#
#	Tester t2 = new Tester(
#	delegate void()
#	{
#		try
#		{
#			q0++;
#			throw new Exception("test3");
#			q0++;
#		}
#		catch(Exception e)
#		{
#			writefln("Never called.");
#			q1++;
#			throw e;
#			q1++;
#		}
#	});
#
#	try
#	{
#		q2++;
#		t2.stuff();
#		q2++;
#	}
#	catch(Exception e)
#	{
#		q3++;
#		e.print();
#	}
#
#	assert(q0 == 1);
#	assert(q1 == 1);
#	assert(q2 == 1);
#	assert(q3 == 1);
#
#	writefln("Passed!");
#}

The catch block in the second delegate never gets invoked.  On a Linux machine. My output is as follows:

Starting test
test1
initial test.
pass
test2
test3
Error: AssertError Failure test(117)

While on windows, it passes with:

Starting test
test1
initial test.
pass
test2
Never called.
test3
Passed!


-Mik


May 24, 2006
mclysenk@mtu.edu schrieb am 2006-05-11:
> As of version 0.150, the offsets of the code within a delegate's function handler are not correctly calculated.  All of them seem to be set relative to the address of the first delegate declared within the scope.  This results in the following code breaking.  The windows version does not have this problem.
>
> #class Tester
> #{
> #	this(void delegate() dg_) { dg = dg_; }
> #	void delegate() dg;
> #	void stuff() { dg(); }
> #}
> #
> #unittest
> #{
> #	writefln("Starting test");
> #
> #	int a = 0;
> #	int b = 0;
> #	int c = 0;
> #	int d = 0;
> #
> #	try
> #	{
> #		a++;
> #		throw new Exception("test1");
> #		a++;
> #	}
> #	catch(Exception e)
> #	{
> #		e.print;
> #		b++;
> #	}
> #	finally
> #	{
> #		c++;
> #	}
> #
> #	writefln("initial test.");
> #
> #	assert(a == 1);
> #	assert(b == 1);
> #	assert(c == 1);
> #
> #	writefln("pass");
> #
> #	Tester t = new Tester(
> #	delegate void()
> #	{
> #		try
> #		{
> #			a++;
> #			throw new Exception("test2");
> #			a++;
> #		}
> #		catch(Exception e)
> #		{
> #			b++;
> #			throw e;
> #			b++;
> #		}
> #	});
> #
> #	try
> #	{
> #		c++;
> #		t.stuff();
> #		c++;
> #	}
> #	catch(Exception e)
> #	{
> #		d++;
> #		e.print;
> #	}
> #
> #	assert(a == 2);
> #	assert(b == 2);
> #	assert(c == 2);
> #	assert(d == 1);
> #
> #
> #	int q0 = 0;
> #	int q1 = 0;
> #	int q2 = 0;
> #	int q3 = 0;
> #
> #	Tester t2 = new Tester(
> #	delegate void()
> #	{
> #		try
> #		{
> #			q0++;
> #			throw new Exception("test3");
> #			q0++;
> #		}
> #		catch(Exception e)
> #		{
> #			writefln("Never called.");
> #			q1++;
> #			throw e;
> #			q1++;
> #		}
> #	});
> #
> #	try
> #	{
> #		q2++;
> #		t2.stuff();
> #		q2++;
> #	}
> #	catch(Exception e)
> #	{
> #		q3++;
> #		e.print();
> #	}
> #
> #	assert(q0 == 1);
> #	assert(q1 == 1);
> #	assert(q2 == 1);
> #	assert(q3 == 1);
> #
> #	writefln("Passed!");
> #}
>
> The catch block in the second delegate never gets invoked.  On a Linux machine. My output is as follows:
>
> Starting test
> test1
> initial test.
> pass
> test2
> test3
> Error: AssertError Failure test(117)
>
> While on windows, it passes with:
>
> Starting test
> test1
> initial test.
> pass
> test2
> Never called.
> test3
> Passed!
>
>
> -Mik

Added to DStress as http://dstress.kuehne.cn/run/t/throw_07_A.d http://dstress.kuehne.cn/run/t/throw_07_B.d

Thomas