Documentation Source Text

Check-in [1f4f0600ef]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Further improvements to the opcode.html document.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1f4f0600efb4371636e8b4f4ca9c91a34ad3f8a8ba9f273e468003229117f603
User & Date: drh 2017-04-29 18:03:04
Context
2017-05-02
01:31
Fix typo. check-in: f230c5ce7d user: mistachkin tags: trunk
2017-04-29
18:03
Further improvements to the opcode.html document. check-in: 1f4f0600ef user: drh tags: trunk
16:55
Improved background information on the bytecode engine. check-in: 21168dec96 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to pages/opcode.in.

57
58
59
60
61
62
63

64
65

66
67
68
69
70
71
72
..
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
...
214
215
216
217
218
219
220


221
222
223
224
225
226
227
228
229

230
231


232
233
234
235
236
237
238
...
270
271
272
273
274
275
276

277
278
279
280
281
282
283
...
306
307
308
309
310
311
312

















313
314
315
316
317
318
319
  }
  set line [string trim [string range $line 3 end]]
  if {$line==""} {
    append Opcode($current_op:text) $pend
    set pend {}
    set pstart {<p>}
  } else {

    regsub -all {>} $line {\&gt;} line
    regsub -all {<} $line {\&lt;} line

    append Opcode($current_op:text) \n$pstart$line
    set pstart {}
    set pend "</p>\n"
  }
}
unset file
set fd [open $::SRC/VERSION r]
................................................................................
  global Opcode
  set out {}
  while {[regexp {^(.*?)(OP_[A-Z][a-z])\y(.*)$} $txt \
             all pre op tail] ||
        [regexp {^(.*?)\y((OP_)?[A-Z][A-Za-z][A-Za-z0-9]+)\y(.*)$} $txt \
             all pre op opx tail]} {
    hd_resolve $pre
    if {($pre=="" || [regexp {> *$} $pre]) && ![regexp {^OP_} $op]} {

      hd_puts $op
    } else {
      regsub {^OP_} $op {} key
      if {[info exists Opcode($key:text)]} {
        hd_puts "<a href=\"opcode.html#$key\">$key</a>"
      } else {
        hd_puts $op
................................................................................
after the OP_ResultRow on the next call
to [sqlite3_step()].
}
</tcl>

<h2>Registers</h2>



<p>Every bytecode program has a fixed (but potentially large) number of
registers.  A single register can hold a variety of objects:
<ul>
<li> A NULL value
<li> A signed 64-bit integer
<li> An IEEE double-precision (64-bit) floating point number
<li> An arbitrary length strings
<li> An arbitrary length BLOB
<li> A RowSet object (used internally)

<li> A Frame object (used internally)
</ul>



<p>A register can also be "Undefined" meaning that it holds no value
at all.  Undefined is different from NULL.  Depending on compile-time
options, an attempt to read an undefined register will usually cause
a run-time error.  If the code generator ([sqlite3_prepare_v2()])
ever generates a [prepared statement] that reads an Undefined register,
that is a bug in the code generator.
................................................................................
(ex: OP_Next or OP_Prev), and so forth.
All cursors are automatically
closed when the prepared statement is [sqlite3_reset()|reset] or
[sqlite3_finalize()|finalized].
}
</tcl>


<h2>Subroutines, Coroutines, and Subprograms</h2>

<p>The bytecode engine has no stack on which to store the return address
of a subroutine.  Return addresses must be stored in registers.
Hence, bytecode subroutines are not reentrant.

<tcl>
................................................................................
OP_Program opcode invokes the trigger subprogram.  The OP_Program instruction
allocates and initializes a fresh register set for each invocation of the
subprogram, so subprograms can be reentrant and recursive.  The
OP_Param opcode is used by subprograms to access content in registers
of the calling bytecode program.
}
</tcl>


















<h1>Viewing The Bytecode</h1>

<p>Every SQL statement that SQLite interprets results in a program
for the virtual machine.  But if the SQL statement begins with
the keyword [EXPLAIN] the virtual machine will not execute the
program.  Instead, the instructions of the program will be returned,







>
|
|
>







 







|
>







 







>
>








|
>
|

>
>







 







>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
  }
  set line [string trim [string range $line 3 end]]
  if {$line==""} {
    append Opcode($current_op:text) $pend
    set pend {}
    set pstart {<p>}
  } else {
    if {![regexp {</?(ul|li|ol)} $line]} {
      regsub -all {>} $line {\&gt;} line
      regsub -all {<} $line {\&lt;} line
    }
    append Opcode($current_op:text) \n$pstart$line
    set pstart {}
    set pend "</p>\n"
  }
}
unset file
set fd [open $::SRC/VERSION r]
................................................................................
  global Opcode
  set out {}
  while {[regexp {^(.*?)(OP_[A-Z][a-z])\y(.*)$} $txt \
             all pre op tail] ||
        [regexp {^(.*?)\y((OP_)?[A-Z][A-Za-z][A-Za-z0-9]+)\y(.*)$} $txt \
             all pre op opx tail]} {
    hd_resolve $pre
    if {($pre=="" || [regexp {> *$} $pre]) && ![regexp {^OP_} $op]
         || [regexp {^object} [string trim $tail]]} {
      hd_puts $op
    } else {
      regsub {^OP_} $op {} key
      if {[info exists Opcode($key:text)]} {
        hd_puts "<a href=\"opcode.html#$key\">$key</a>"
      } else {
        hd_puts $op
................................................................................
after the OP_ResultRow on the next call
to [sqlite3_step()].
}
</tcl>

<h2>Registers</h2>

<tcl>
LinkOpcodeNames {
<p>Every bytecode program has a fixed (but potentially large) number of
registers.  A single register can hold a variety of objects:
<ul>
<li> A NULL value
<li> A signed 64-bit integer
<li> An IEEE double-precision (64-bit) floating point number
<li> An arbitrary length strings
<li> An arbitrary length BLOB
<li> A RowSet object (See the OP_RowSetAdd, OP_RowSetRead, and
                      OP_RowSetTest opcodes)
<li> A Frame object (Used by [subprograms] - see OP_Program)
</ul>
}
</tcl>

<p>A register can also be "Undefined" meaning that it holds no value
at all.  Undefined is different from NULL.  Depending on compile-time
options, an attempt to read an undefined register will usually cause
a run-time error.  If the code generator ([sqlite3_prepare_v2()])
ever generates a [prepared statement] that reads an Undefined register,
that is a bug in the code generator.
................................................................................
(ex: OP_Next or OP_Prev), and so forth.
All cursors are automatically
closed when the prepared statement is [sqlite3_reset()|reset] or
[sqlite3_finalize()|finalized].
}
</tcl>

<tcl>hd_fragment subprog subprograms</tcl>
<h2>Subroutines, Coroutines, and Subprograms</h2>

<p>The bytecode engine has no stack on which to store the return address
of a subroutine.  Return addresses must be stored in registers.
Hence, bytecode subroutines are not reentrant.

<tcl>
................................................................................
OP_Program opcode invokes the trigger subprogram.  The OP_Program instruction
allocates and initializes a fresh register set for each invocation of the
subprogram, so subprograms can be reentrant and recursive.  The
OP_Param opcode is used by subprograms to access content in registers
of the calling bytecode program.
}
</tcl>

<h2>Self-Altering Code</h2>

<tcl>
LinkOpcodeNames {
<p>Some opcodes are self-altering.
For example, the OP_Init opcode (which is always the first opcode
run a bytecode program) increments its P1 operand.  Subsequent
OP_Once opcodes compare their P1 operands to the P1 value for
the OP_Init opcode in order to determine if the one-time initialization
code that follows should be skipped.
Another example is the OP_String8 opcode which converts its P4
operand from UTF-8 into the correct database string encoding, then
converts itself into a OP_String opcode.
}
</tcl>


<h1>Viewing The Bytecode</h1>

<p>Every SQL statement that SQLite interprets results in a program
for the virtual machine.  But if the SQL statement begins with
the keyword [EXPLAIN] the virtual machine will not execute the
program.  Instead, the instructions of the program will be returned,