develooper Front page | perl.perl5.porters | Postings from January 2003

eval_sv and exception handling

Thread Next
From:
rwilding
Date:
January 29, 2003 09:49
Subject:
eval_sv and exception handling
Message ID:
DD4AFB45E2CCD211B6EE0008C7333BCF0354339D@ntxmel01.micron.com
Hi All,

I'm embedding Perl as the scripting language for a c++ application.  Users
will be able to enter perl expressions to be evaluated and the results used
elsewhere in the program (by no means spectacular but i mention this so you
know that I have no control of what expression are being evaluated).

Earlier this week i struggled with trapping and reporting any
syntax/compiler time errors in the entered expression.  Since I dont want a
user's expression (or the results of the expression) to interfere with the
perl namespace I encapsulate them in an anonymous subroutine, i.e.

		SV* cv=eval_pv("sub{return  [user's expression]}");

eval_pv hides any compilation errors (such as the use mistyping) since it is
just preparing the anonymous sub and it an error occurs it simply returns an
invalid reference, it does this without setting ERRSV.  The only way to
detect the error is to manually inspect the cv->sv_any member for NULL.  I
decided to write an alternative to eval_pv which allows me to detect the
presence of the error (and pass Perl's error message to the end user).  This
is a rewrite of eval_pv from the Perl source which required changing the
flags for the internal call to eval_sv and some $@ cleanup . so far so good.

Now, I have a new problem:  If the expression compiles and MY_eval_pv
returns a valid CV and that CV kicks out an exception there is no way to
trap that exception! In plain perl i could do this (gf is an imaginary user
typo):

		$test=eval "sub{$p=5;$out=gf$p;return $out}";
		eval{
			&$test
		}	
		if($@)
		{
			print "Error", $@
		}

But there is no way (that i can see) to do an eval round an anonymous
subroutine called with call_sv.  I've looked through the Perl source and
can't find any clues of how to achieve this.  One idea I had was to somehow
tie the CV with a new RV which was named (say $temp) and then do
eval_pv("&$temp"); but that just seems messy (and I dont know if the results
from the routine will be in the right place on the stack after the eval -
though i expect they would).

Any ideas??, if there isn't a way to do this at the moment I think it would
be an important addition to the Perl core - at least for embedded perl apps.

Thanks in advance,

Rich

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About