More on byte compilation

31 views
Skip to first unread message

call_me_anything

unread,
Feb 10, 2007, 10:31:25 AM2/10/07
to
proc B x {
if $x {
this is an error
} else {
set a b
}
}

B 0
=> works correctly.

B 1
=> error. invalid command "this".


The big question is :
If procs are byte compiled, then why the error was not caught during
byte-compilation itself ?
Why did it kept lurking till execution.
Is the body of if, else statements is not included in byte
compilation ? Then is it not inefficeint to do so ?


I need a good and simple document on byte compilation.
Please send some good link if you know of one.

Bryan Oakley

unread,
Feb 10, 2007, 11:00:22 AM2/10/07
to
call_me_anything wrote:
> proc B x {
> if $x {
> this is an error
> } else {
> set a b
> }
> }
>
> B 0
> => works correctly.
>
> B 1
> => error. invalid command "this".
>
>
> The big question is :
> If procs are byte compiled, then why the error was not caught during
> byte-compilation itself ?

Because it's not an error. While "this" may not be a command at the time
B is defined, it could very well be a command by the time something
actually tries to run the "B" command.

We certainly don't want proc definitions to fail just because the body
of the proc calls a command that has not yet been defined. Otherwise, it
would be impossible to do something like:

proc A {} {
B "Hello World"
}
proc B {s} {
puts $s
}

One would have to make sure that B is defined first which would be an
onerous task, if not virtually impossible in a large application.

Out of curiosity, why all the facination with the byte code compiler?
Are you trying to extend it or optimize it in some manner?

--
Bryan Oakley
http://www.tclscripting.com

Uwe Klein

unread,
Feb 10, 2007, 10:56:39 AM2/10/07
to
call_me_anything wrote:
> proc B x {
> if $x {
> this is an error
> } else {
> set a b
> }
> }
>
> B 0
> => works correctly.
>
> B 1
> => error. invalid command "this".
>
>
> The big question is :
> If procs are byte compiled, then why the error was not caught during
> byte-compilation itself ?

it was caught during byte compile ;-)
But Tcl is lazy, the proc is "compiled" on first execution.

> Why did it kept lurking till execution.
> Is the body of if, else statements is not included in byte
> compilation ? Then is it not inefficeint to do so ?
>
>
> I need a good and simple document on byte compilation.
> Please send some good link if you know of one.
>

start here:
http://wiki.tcl.tk/2?bytecode

uwe

Message has been deleted

Kevin Kenny

unread,
Feb 10, 2007, 11:31:12 AM2/10/07
to
call_me_anything wrote:
> proc B x {
> if $x {
> this is an error
> } else {
> set a b
> }
> }
>
> B 0
> => works correctly.
>
> B 1
> => error. invalid command "this".
>
>
> The big question is :
> If procs are byte compiled, then why the error was not caught during
> byte-compilation itself ?

Because the byte-compiler intentionally defers errors as late in
the process as possible. If you define a [this] command after
the byte compilation, B will find it.

Correcting your unbraced $x (which keeps us from compiling the
[if] command, and worse, from compiling its body!), the bytecode
looks like:

Command 1: "if {$x} {\n this is an error\n } else {\n "
(0) loadScalar1 %v0 # var "x"
(2) tryCvtToNumeric
(3) jumpFalse1 +14 # pc 17
Command 2: "this is an error"
(5) push1 0 # "this"
(7) push1 1 # "is"
(9) push1 2 # "an"
(11) push1 3 # "error"
(13) invokeStk1 4
(15) jump1 +11 # pc 26
Command 3: "set a b"
(17) startCommand 9 # next cmd at pc 26
(22) push1 4 # "b"
(24) storeScalar1 %v1 # var "a"
(26) done

The significant part is bytecodes 5-14. They say: "push to the stack, in
order, the four literals {this} {is} {an} {error}, and invoke them as
a four-word command." The actual meaning of the command isn't checked
until run time.

Even gross syntax errors are deferred until run time if possible,
in case commands get redefined. There are bytecodes like 'exprStk'
that say, "try to compile the value at the top of the stack as
an expression, evaluate it in the current context and stack its
result." The bytecode compiler sometimes even emits code that
has no other purpose than to report a syntax error - after all,
that syntax error can be embedded in a [catch].

> I need a good and simple document on byte compilation.
> Please send some good link if you know of one.

It's just in the source. Since users don't need to know, nobody's
troubled to do a good manual. From the perspective of a Tcl programmer,
or the programmer of a C extension for Tcl, bytecode should be
invisible. The only way that you should be able to tell that there
is a bytecode engine at all is that your code runs faster. And the
bytecode interpreter is an extraordinary complex piece of code in which
there are Lovecraftian horrors. Much comprehensibility has been
sacrificed for performance. People who can't learn from the source
code are well advised to start their explorations somewhere else.

--
73 de ke9tv/2, Kevin

Donal K. Fellows

unread,
Feb 10, 2007, 8:12:37 PM2/10/07
to
Kevin Kenny wrote:
> People who can't learn from the source
> code are well advised to start their explorations somewhere else.

FWIW, I don't recommend starting on any of the other following areas
either (since I think the bytecode engine is simpler than them), in no
particular order:
- Regexp engine
- Notifier
- Encoding engine
- Virtual filesystem laye
- Tcl Library initialization
- Namespace teardown

Tk has a few very hard bits too; the option database code and the
response to the world totally changing are areas that spring to
mind...

Donal.

Kevin Kenny

unread,
Feb 10, 2007, 11:45:30 PM2/10/07
to
Donal K. Fellows wrote:
> FWIW, I don't recommend starting on any of the other following areas
> either (since I think the bytecode engine is simpler than them), in no
> particular order:
> - Regexp engine
> - Notifier
> - Encoding engine
> - Virtual filesystem laye[r]

> - Tcl Library initialization
> - Namespace teardown

I'd say that a few of those are in need of radical refactoring, except
for the fact that they'd probably turn out nearly the same when we got
done. The regexp engine, for instance, solves a damned difficult
problem. I think you have to be barking mad to write one. (I say that
from some experience: I wrote grep for GECOS, back in the day...)

Donal K. Fellows

unread,
Feb 11, 2007, 1:29:02 PM2/11/07
to
Kevin Kenny wrote:
> I'd say that a few of those are in need of radical refactoring,

The encoding engine definitely needs it, but there's something very
strange going on in that code. It's currently the only code in the
core of Tcl that actively resists changes. (Of the others, the RE
engine is the only part I dare touch, speaking as someone who has
added considerably to the complexity of namespace death over the past
couple of years...)

Donal.

Christian Gollwitzer

unread,
Feb 12, 2007, 5:21:56 AM2/12/07
to
Kevin Kenny wrote:
> call_me_anything wrote:
>
>> proc B x {
>> if $x {
>> this is an error
>> } else {
>> set a b
>> }
>> }
> Correcting your unbraced $x (which keeps us from compiling the
> [if] command, and worse, from compiling its body!), the bytecode
> looks like:
>
> Command 1: "if {$x} {\n this is an error\n } else {\n "
> (0) loadScalar1 %v0 # var "x"
> (2) tryCvtToNumeric
> (3) jumpFalse1 +14 # pc 17
> Command 2: "this is an error"


While it should usually not matter, it could be interesting to read this
bytecode from parts of a program that need speedup. How did you generate
this disassembly? By hand? Is there a tcl command to do it? I'm familiar
with a few assembly languages, so this bytecode disassembly looks quite
readable to me.

Christian

suchenwi

unread,
Feb 12, 2007, 6:20:43 AM2/12/07
to
On 12 Feb., 11:21, Christian Gollwitzer <Christian.Gollwit...@uni-

bayreuth.de> wrote:
> Is there a tcl command to do it? I'm familiar
> with a few assembly languages, so this bytecode disassembly looks quite
> readable to me.

See man tclvars: compile Tcl with TCL_COMPILE_DEBUG, then at runtime
set tcl_traceCompile or tcl_traceExec to nonzero values.

Donal K. Fellows

unread,
Feb 12, 2007, 8:30:48 AM2/12/07
to
Christian Gollwitzer wrote:
> How did you generate this disassembly? By hand?
> Is there a tcl command to do it?

Compile Tcl (preferably the HEAD) with the configure option --enable-
symbols=compile and then use a script like this:

proc dumpCompilations script {
set script "set ::tcl_traceCompile 2;$script"
catch { uplevel 1 $script } msg opt
set ::tcl_traceCompile 0
return -options $opt $msg
}
proc B x { ... }
dumpCompilations {
# Remember, procedures are compiled lazily...
B foo bar anything to trigger compilation
}

Note that you don't want to set tcl_traceCompile when it is compiling
interactive commands; it adds a lot to the noise. Especially if you
get bits of the [history] mechanism in there.

> I'm familiar with a few assembly languages, so this
> bytecode disassembly looks quite readable to me.

Thanks on the readability point; I've been working to improve it
somewhat in 8.5. :-)

Donal.

Bryan Oakley

unread,
Feb 10, 2007, 11:00:22 AM2/10/07
to
call_me_anything wrote:
> proc B x {
> if $x {
> this is an error
> } else {
> set a b
> }
> }
>
> B 0
> => works correctly.
>
> B 1
> => error. invalid command "this".
>
>
> The big question is :
> If procs are byte compiled, then why the error was not caught during
> byte-compilation itself ?

Because it's not an error. While "this" may not be a command at the time

Donal K. Fellows

unread,
Feb 13, 2007, 3:44:14 PM2/13/07
to
Donal K. Fellows wrote:
> FWIW, I don't recommend starting on any of the other following areas
> either (since I think the bytecode engine is simpler than them), in no
> particular order:
[...]

Forgot to add "Traces" to that list. Traces are horrible.

Donal.

Stephan Kuhagen

unread,
Feb 14, 2007, 1:00:46 AM2/14/07
to
Donal K. Fellows wrote:

> Forgot to add "Traces" to that list. Traces are horrible.

But one of the most useful and coolest features of Tcl! Never want to miss
them.

Regards
Stephan

Donal K. Fellows

unread,
Feb 14, 2007, 4:41:01 AM2/14/07
to
Stephan Kuhagen wrote:
> But one of the most useful and coolest features of Tcl! Never want to miss
> them.

I like *using* traces, yes, but the implementation code for them is
deeply scary. Of course, that's the way it should be: Tcl does the
nasty bits so you don't have to!

Donal.

Darren New

unread,
Feb 14, 2007, 11:43:15 AM2/14/07
to
Donal K. Fellows wrote:
> Of course, that's the way it should be: Tcl does the
> nasty bits so you don't have to!

QOTW!

--
Darren New / San Diego, CA, USA (PST)
New horror show, now only in Las Vegas:
HANNIBAL LUXOR!

Reply all
Reply to author
Forward
0 new messages