Short overview of the sieve runtime machine
Showing
1 changed file
with
140 additions
and
0 deletions
libsieve/README
0 → 100644
1 | |||
2 | 1. Overview | ||
3 | |||
4 | A compiled sieve program consists of a sequence of cells. Each cell | ||
5 | is a pointer to sieve_op_t data, i.e. it points to an instruction handler | ||
6 | (sieve_instr_t type) or to a memory location containing sieve_value_t | ||
7 | structure. The exact interpretation of this pointer depends on the | ||
8 | value of program counter. The very first entry in a sieve program | ||
9 | (pc = 0) is always a NULL pointer. The next entry (pc = 1) is always | ||
10 | expected to contain a valid instruction handler. When executing a | ||
11 | program, the sieve runtime evaluator starts from pc = 1. It reads | ||
12 | the cell contents, interprets it as address of an instruction handler, | ||
13 | increments the program counter and executes the handler. The evaluator | ||
14 | stops executing the program when it encounters a NULL pointer. | ||
15 | |||
16 | When invoked, an instruction handler receives a single argument: a pointer | ||
17 | to the sieve_machine_t structure, describing current runtime environment. | ||
18 | If the handler needs any surplus arguments, it is its responsibility | ||
19 | to retrieve them from the program cells immediately following the | ||
20 | handler address and increment the pc value accordingly. | ||
21 | |||
22 | 2. Existing handlers | ||
23 | |||
24 | 2.1. Push | ||
25 | |||
26 | Name: instr_push | ||
27 | Arguments: None | ||
28 | |||
29 | Pushes current numeric register on stack. | ||
30 | |||
31 | 2.2. Pop | ||
32 | |||
33 | Name: instr_pop | ||
34 | Arguments: None | ||
35 | |||
36 | Pops the top of stack value into the numeric register. | ||
37 | |||
38 | 2.3. Unconditional branch | ||
39 | |||
40 | Name: instr_branch | ||
41 | Arguments: [pc ] (number) New value for pc. | ||
42 | |||
43 | 2.4. Branch if not zero | ||
44 | |||
45 | Name: instr_brnz | ||
46 | Arguments: [pc ] (number) New value for pc. | ||
47 | |||
48 | 2.5. Logical NOT | ||
49 | |||
50 | Name: instr_not | ||
51 | Arguments: none | ||
52 | |||
53 | 2.6. Logical AND | ||
54 | |||
55 | Name: instr_allof | ||
56 | Arguments: [pc ] (number) Number of items to be popped from stack | ||
57 | |||
58 | |||
59 | 2.7. Logical OR | ||
60 | |||
61 | Name: instr_anyof | ||
62 | Arguments: [pc ] (number) Number of items to be popped from stack | ||
63 | |||
64 | 2.8. Action handler | ||
65 | |||
66 | Name: instr_action | ||
67 | Arguments: [pc ] (sieve_handler_t*) Pointer to the action handling function. | ||
68 | [pc+1] (list_t of sieve_value_t) A list of required arguments. | ||
69 | [pc+2] (list_t of sieve_runtime_tag_t) A list of tags. | ||
70 | [pc+3] (string) Name of the action (for debugging purposes). | ||
71 | |||
72 | 2.9. Test handler | ||
73 | |||
74 | Name: instr_test | ||
75 | Arguments: [pc ] (sieve_handler_t*) Pointer to the test handling function. | ||
76 | [pc+1] (list_t of sieve_value_t) A list of required arguments. | ||
77 | [pc+2] (list_t of sieve_runtime_tag_t) A list of tags. | ||
78 | [pc+3] (string) Name of the test (for debugging purposes). | ||
79 | |||
80 | 3. Conditional statement branching | ||
81 | |||
82 | A simple statement | ||
83 | |||
84 | IF cond list1 ELSE list2 | ||
85 | |||
86 | is translated into the following program | ||
87 | |||
88 | # Compute the condition | ||
89 | . | ||
90 | . | ||
91 | . | ||
92 | brnz L_ELSE | ||
93 | # Evaluate list1 | ||
94 | . | ||
95 | . | ||
96 | . | ||
97 | br L_END | ||
98 | L_ELSE: | ||
99 | # Evaluate list2 | ||
100 | . | ||
101 | . | ||
102 | . | ||
103 | L_END: | ||
104 | |||
105 | A more complex statement in the form: | ||
106 | |||
107 | IF cond1 list1 ELSIF cond2 list2 ELSE list3 | ||
108 | |||
109 | is translated into the following program | ||
110 | |||
111 | # Compute the condition 1 | ||
112 | . | ||
113 | . | ||
114 | . | ||
115 | brnz L_ELSIF | ||
116 | # Evaluate list1 | ||
117 | . | ||
118 | . | ||
119 | . | ||
120 | br L_END | ||
121 | L_ELSIF: | ||
122 | # Compute the condition 2 | ||
123 | . | ||
124 | . | ||
125 | . | ||
126 | brnz L_ELSE | ||
127 | # Evaluate list 2 | ||
128 | . | ||
129 | . | ||
130 | . | ||
131 | br L_END | ||
132 | L_ELSE: | ||
133 | # Evaluate list 3 | ||
134 | . | ||
135 | . | ||
136 | . | ||
137 | L_END: | ||
138 | |||
139 | Generally speaking, each ELSIF branch generates a code, similar to usual | ||
140 | IF ... ELSE sequence. | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or sign in to post a comment