Tcl Source Code

View Ticket
Login
Ticket UUID: 1688593
Title: compiling variable links
Type: Patch Version: None
Submitter: msofer Created on: 2007-03-26 17:43:06
Subsystem: 47. Bytecode Compiler Assigned To: msofer
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2007-04-03 08:35:11
Resolution: Accepted Closed By: msofer
    Closed on: 2007-04-03 01:35:11
Description:
Attached a patch that compiles [global], [variable], [upvar] and [namespace upvar] to bytecodes.

Comments are still somewhat sparse, and new tests might yet be required.
User Comments: msofer added on 2007-04-03 08:35:11:

File Added - 223477: varCompiler2.patch

Logged In: YES 
user_id=148712
Originator: YES

Final patch, committed. Added comments in tclCompCmds.c. Also verified that this patch does not interfere with varName resolvers as used by Itcl: lookup for upvar purposes bypasses the resolvers anyway, as determined by the LOOKUP_FOR_UPVAR flag in tclVar.c
File Added: varCompiler2.patch

msofer added on 2007-03-28 22:11:56:

File Added - 222675: varCompiler1.patch

Logged In: YES 
user_id=148712
Originator: YES

Second patch - only changed in TEBC, slight optimisation of the new instructions.
File Added: varCompiler1.patch

andreas_kupries added on 2007-03-27 01:22:34:
Logged In: YES 
user_id=75003
Originator: NO

Ad 1: Ok. I did not know that of the compiler. I thought that maybe the command compiler has to do the cleanup. Having it in the general code does make sense. I guess it remembers the location of the first instruction and on error simply rewind to location. Thanks for the explanation.

Ad 2: The bug is in my understanding of how the compiler works, apparently. I simply did not see which pieces of the code do the check that 'the local variables are known at compile time'. I see the loop doing the compilation, but did not see how it does the checks. Looking again my guess is that the important parts of the check are hidden in 'PushVarName'.

I guess I should have waited for the extensively commented version of the patch.

msofer added on 2007-03-27 01:16:03:
Logged In: YES 
user_id=148712
Originator: YES

(1) on returning TCL_ERROR from a command compiler, all instructions that were previously emitted will be cleaned up. The only "garbage" that may remain are newly created literals

(2) that thing is supposed to only compile to bytecodes when all the local variables are known at compile time, and to return TCL_ERROR if any one fails. Is there a bug?

I see that eg

  proc a {} {set a b; upvar 1 $::q $a}

is not compiled but calls [upvar] at runtime:

  Command 1: "set a b"
    (0) push1 0         # "b"
    (2) storeScalar1 %v0        # var "a"
    (4) pop
  Command 2: "upvar 1 $::q $a"
    (5) push1 3         # "upvar"
    (7) push1 1         # "1"
    (9) push1 2         # "::q"
    (11) loadScalarStk
    (12) loadScalar1 %v0        # var "a"
    (14) invokeStk1 4
    (16) done

andreas_kupries added on 2007-03-27 00:58:26:
Logged In: YES 
user_id=75003
Originator: NO

Quick review ...

In the compilers for (namespace) upvar, what you return ERROR to force outline execution if the 'thisVar' is not local. However I see no code to remove  the instructions for var pairs which were ok and came before the variable which forced the outline compile.

I.e. a command like "upvar 1 $vara here $varb <NOT_LOCAL_VAR>" (*) causes compilation of the vara/here pair, and then aborts for varb. But the instructions for vara are still in the result, are they not ?

(*) I used <NOT_LOCAL_VAR> as placeholder because I have currently no idea how a variable name cannot be local. Shrug.

Oh, I just saw that the code seems to assume that the 'local token' is a always varname, i.e. constant. It does not seem to handle the case of a the token being a command, or varr reference, i.e. ([...], $xxx), like in

    upvar 1 $external [ourvar]
    upvar 1 $external $myvar

Both of these are cases which should force outline compile.

msofer added on 2007-03-27 00:43:10:

File Added - 222338: varCompiler.patch

Attachments: