Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Slave interpreters, aliases, and upvar

19 views
Skip to first unread message

will.d...@gmail.com

unread,
Apr 11, 2007, 11:31:32 PM4/11/07
to
Is it possible for a command aliased into a slave interpreter
to use upvar to access variables in the slave? Consider the
following:

proc get {varname} {
upvar 1 $varname myvar
return $myvar
}

set interp [interp create]

$interp alias get get
$interp eval {
set a 7
get a
}

I'd like this to return "7"; instead, it tells me that there's no such
variable "myvar". Clearly, the previous callframe is *not* in the
slave. Any ideas on how to handle this?

suchenwi

unread,
Apr 12, 2007, 7:41:44 AM4/12/07
to
On 12 Apr., 05:31, "w...@wjduquette.com" <will.duque...@gmail.com>
wrote:

Interpreters are not in callstack hierarchy, for good reason. You have
to endow the slave with a command with which he can read his master's
variables:

set slave [interp create]

proc get _var {
upvar 1 $_var var
return $var
}
interp alias $slave get {} get
#-- Test:
set foo 42
puts [$slave eval {get foo}]


Neil Madden

unread,
Apr 12, 2007, 11:13:51 AM4/12/07
to
suchenwi wrote:
> On 12 Apr., 05:31, "w...@wjduquette.com" <will.duque...@gmail.com>
> wrote:
...

>> $interp alias get get
>> $interp eval {
>> set a 7
>> get a
>> }
>>
>> I'd like this to return "7"; instead, it tells me that there's no such
>> variable "myvar". Clearly, the previous callframe is *not* in the
>> slave. Any ideas on how to handle this?
>
> Interpreters are not in callstack hierarchy, for good reason. You have
> to endow the slave with a command with which he can read his master's
> variables:
>
> set slave [interp create]
>
> proc get _var {
> upvar 1 $_var var
> return $var
> }
> interp alias $slave get {} get
> #-- Test:
> set foo 42
> puts [$slave eval {get foo}]

I think Will wants a different result -- the variable is in the slave
too. It seems that when the master alias is invoked none of the
callframes from the slave are visible (to upvar, uplevel, or info
level). I don't immediately see the reason why a master cannot see the
stack-frames of the slave that invoked it (these aren't safe interpreters).

To solve Will's immediate problem, I'd guess that you could pass the
interpreter handle as part of the alias and read the variables directly:

proc get {interp varName} {
return [$interp eval [list set $varName]]


}
set interp [interp create]
$interp alias get get $interp
$interp eval {
set a 7
get a
}

Happily, this even works inside procs:

$interp eval {
proc foo {} { set b 9; get b }
foo
}

-- Neil

will.d...@gmail.com

unread,
Apr 12, 2007, 4:03:37 PM4/12/07
to
On Apr 12, 8:13 am, Neil Madden <n...@cs.nott.ac.uk> wrote:
> I think Will wants a different result -- the variable is in the slave
> too. It seems that when the master alias is invoked none of the
> callframes from the slave are visible (to upvar, uplevel, or info
> level). I don't immediately see the reason why a master cannot see the
> stack-frames of the slave that invoked it (these aren't safe interpreters).
>
> To solve Will's immediate problem, I'd guess that you could pass the
> interpreter handle as part of the alias and read the variables directly:
>
> proc get {interp varName} {
> return [$interp eval [list set $varName]]
> }
> set interp [interp create]
> $interp alias get get $interp
> $interp eval {
> set a 7
> get a
> }
>
> Happily, this even works inside procs:
>
> $interp eval {
> proc foo {} { set b 9; get b }
> foo
> }
>
> -- Neil

Neil's exactly right, that's what I'm after. And the answer is,
you can't alias a normal proc that uses upvar or uplevel into
a slave interpreter, and expect it to work across the interpreter
boundary the way it works within a single interpreter. You can
write a command that has the same effect, but it has to be
specially written.

I was hoping there was some magic incantation I hadn't run across.
Oh, well.

Thanks, both.

-- Will

MartinLemburg@UGS

unread,
Apr 13, 2007, 5:44:23 AM4/13/07
to
Hello,

I understand what Will wants, I understand Richards and Neils
explainations, but ... I don't understand, why this is planned to be
this way.

If I import a namespace command into another namespace, than this
imported namespace command will be executed inside his original
namespace:

% namespace eval ::foo {
variable foo "this is namespace foo";

proc foo {} {
variable foo;

puts "info level 0 .................= '[info level 0]'";
puts "foo ..........................= '$foo'";
puts "namespace current ............= '[namespace
current]'";
puts "info level -1 ................= '[info level -1]'";
puts "uplevel 1 {namespace current} = '[uplevel 1 [list
namespace current]]'";
}

namespace export -clear foo;
}
% namespace eval ::faa {
variable foo "this is namespace faa";

proc faa {} {
foo;
}

namespace import -force ::foo::*;
}
% ::faa::faa;
info level 0 .................= 'foo'
foo ..........................= 'this is namespace foo'
namespace current ............= '::foo'
info level -1 ................= '::faa::faa'
uplevel 1 {namespace current} = '::faa'

In my opinion, the behaviour Will wants/needs would be comparable.

What're the reasons for this design decision?

Best regards,

Martin Lemburg
UGS - Transforming the Process of Innovation

On Apr 12, 10:03 pm, "w...@wjduquette.com" <will.duque...@gmail.com>
wrote:

will.d...@gmail.com

unread,
Apr 13, 2007, 11:07:28 AM4/13/07
to
On Apr 13, 2:44 am, "MartinLemburg@UGS" <martin.lemburg....@gmx.net>
wrote:

> Hello,
>
> I understand what Will wants, I understand Richards and Neils
> explainations, but ... I don't understand, why this is planned to be
> this way.
>
> What're the reasons for this design decision?

My guess is that it's a safety thing. Slave interps were implemented
to
support the execution of untrusted code, and one of the rules when
using them for that purpose is that you *never* evaluate expressions
or scripts received from the slave in the master. I can't see how
allowing "upvar 1" or "uplevel 1" of strings received from the slave
could get me in trouble--but I can easily see how making a mistake in
the command that's using "uplevel 1" could open a vulnerability.

I do think that this should be explicitly documented in the interp(n)
man page.

Don Porter

unread,
Apr 16, 2007, 10:04:58 AM4/16/07
to
wi...@wjduquette.com wrote:
> Is it possible for a command aliased into a slave interpreter
> to use upvar to access variables in the slave?

No. The levels used by the [uplevel] and [upvar] commands refer
to the stack of CallFrame contexts stacked for use by a single
interp.

You can construct the alias to pass in the name of the slave interp
as one of the args, and then use that argument to go probing for the
value you seek. The context in the slave will not have changed.

--
| Don Porter Mathematical and Computational Sciences Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

will.d...@gmail.com

unread,
Apr 18, 2007, 12:42:52 PM4/18/07
to
Thanks for the definitive answer, Don.

Will

On Apr 16, 7:04 am, Don Porter <d...@nist.gov> wrote:


> w...@wjduquette.com wrote:
> > Is it possible for a command aliased into a slave interpreter
> > to use upvar to access variables in the slave?
>
> No. The levels used by the [uplevel] and [upvar] commands refer
> to the stack of CallFrame contexts stacked for use by a single
> interp.
>
> You can construct the alias to pass in the name of the slave interp
> as one of the args, and then use that argument to go probing for the
> value you seek. The context in the slave will not have changed.
>
> --
> | Don Porter Mathematical and Computational Sciences Division |

> | donald.por...@nist.gov Information Technology Laboratory |
> |http://math.nist.gov/~DPorter/ NIST |
> |______________________________________________________________________|


0 new messages