Merge branch 'prerelease' of github.com:sqlcipher/sqlcipher into prerelease
[sqlcipher.git] / tool / vdbe-compress.tcl
blob95cc1ebf5ab78ca51539d1e4414457a7d94f88e3
1 #!/usr/bin/tcl
3 # This script makes modifications to the vdbe.c source file which reduce
4 # the amount of stack space required by the sqlite3VdbeExec() routine.
6 # The modifications performed by this script are optional. The vdbe.c
7 # source file will compile correctly with and without the modifications
8 # performed by this script. And all routines within vdbe.c will compute
9 # the same result. The modifications made by this script merely help
10 # the C compiler to generate code for sqlite3VdbeExec() that uses less
11 # stack space.
13 # Script usage:
15 # mv vdbe.c vdbe.c.template
16 # tclsh vdbe-compress.tcl <vdbe.c.template >vdbe.c
18 # Modifications made:
20 # All modifications are within the sqlite3VdbeExec() function. The
21 # modifications seek to reduce the amount of stack space allocated by
22 # this routine by moving local variable declarations out of individual
23 # opcode implementations and into a single large union. The union contains
24 # a separate structure for each opcode and that structure contains the
25 # local variables used by that opcode. In this way, the total amount
26 # of stack space required by sqlite3VdbeExec() is reduced from the
27 # sum of all local variables to the maximum of the local variable space
28 # required for any single opcode.
30 # In order to be recognized by this script, local variables must appear
31 # on the first line after the open curly-brace that begins a new opcode
32 # implementation. Local variables must not have initializers, though they
33 # may be commented.
35 # The union definition is inserted in place of a special marker comment
36 # in the preamble to the sqlite3VdbeExec() implementation.
38 #############################################################################
40 set beforeUnion {} ;# C code before union
41 set unionDef {} ;# C code of the union
42 set afterUnion {} ;# C code after the union
43 set sCtr 0 ;# Context counter
45 # Read program text up to the spot where the union should be
46 # inserted.
48 while {![eof stdin]} {
49 set line [gets stdin]
50 if {[regexp {INSERT STACK UNION HERE} $line]} break
51 append beforeUnion $line\n
54 # Process the remaining text. Build up the union definition as we go.
56 set vlist {}
57 set seenDecl 0
58 set namechars {abcdefghijklmnopqrstuvwxyz}
59 set nnc [string length $namechars]
60 while {![eof stdin]} {
61 set line [gets stdin]
62 if {[regexp "^case (OP_\\w+): \173" $line all operator]} {
63 append afterUnion $line\n
64 set vlist {}
65 while {![eof stdin]} {
66 set line [gets stdin]
67 if {[regexp {^ +(const )?\w+ \**(\w+)(\[.*\])?;} $line \
68 all constKeyword vname notused1]} {
69 if {!$seenDecl} {
70 set sname {}
71 append sname [string index $namechars [expr {$sCtr/$nnc}]]
72 append sname [string index $namechars [expr {$sCtr%$nnc}]]
73 incr sCtr
74 append unionDef " struct ${operator}_stack_vars \173\n"
75 append afterUnion \
76 "#if 0 /* local variables moved into u.$sname */\n"
77 set seenDecl 1
79 append unionDef " $line\n"
80 append afterUnion $line\n
81 lappend vlist $vname
82 } elseif {[regexp {^#(if|endif)} $line] && [llength $vlist]>0} {
83 append unionDef "$line\n"
84 append afterUnion $line\n
85 } else {
86 break
89 if {$seenDecl} {
90 append unionDef " \175 $sname;\n"
91 append afterUnion "#endif /* local variables moved into u.$sname */\n"
93 set seenDecl 0
95 if {[regexp "^\175" $line]} {
96 append afterUnion $line\n
97 set vlist {}
98 } elseif {[llength $vlist]>0} {
99 append line " "
100 foreach v $vlist {
101 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
102 regsub -all "(\[^a-zA-Z0-9>.\])${v}(\\W)" $line "\\1u.$sname.$v\\2" line
104 append afterUnion [string trimright $line]\n
105 } elseif {$line=="" && [eof stdin]} {
106 # no-op
107 } else {
108 append afterUnion $line\n
112 # Output the resulting text.
114 puts -nonewline $beforeUnion
115 puts " /********************************************************************"
116 puts " ** Automatically generated code"
117 puts " **"
118 puts " ** The following union is automatically generated by the"
119 puts " ** vdbe-compress.tcl script. The purpose of this union is to"
120 puts " ** reduce the amount of stack space required by this function."
121 puts " ** See comments in the vdbe-compress.tcl script for details."
122 puts " */"
123 puts " union vdbeExecUnion \173"
124 puts -nonewline $unionDef
125 puts " \175 u;"
126 puts " /* End automatically generated code"
127 puts " ********************************************************************/"
128 puts -nonewline $afterUnion