about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-08-12 21:04:14 -0700
committerKartik Agaram <vc@akkartik.com>2018-08-12 22:38:36 -0700
commitf3901d906901e80588f2e3e56bbe3052e47e4d64 (patch)
tree71ad9f7fe200ea8e54ab68f1c2b5ebd61180c1be
parent521ff2f19332d048c4b658d64ed5a552045f5ea5 (diff)
downloadmu-f3901d906901e80588f2e3e56bbe3052e47e4d64.tar.gz
4512 - divide labels into two categories
Targets you can jump to and ones you can call are conceptually disjoint
sets.

I'm highlighting these in Vim, but it's a pretty complex pattern.
Arguably errors shouldn't be highlighted. Only warnings that are easy to
be accidentally deployed.
-rw-r--r--subx/035labels.cc19
-rw-r--r--subx/037label_types.cc45
-rw-r--r--subx/ex3.subx8
-rw-r--r--subx/ex7.subx4
-rw-r--r--subx/subx.vim7
-rw-r--r--subx/vim_errors.subx34
6 files changed, 101 insertions, 16 deletions
diff --git a/subx/035labels.cc b/subx/035labels.cc
index db54d329..c7274613 100644
--- a/subx/035labels.cc
+++ b/subx/035labels.cc
@@ -53,7 +53,6 @@ loop:
 
 :(before "End Level-2 Transforms")
 Transform.push_back(rewrite_labels);
-
 :(code)
 void rewrite_labels(program& p) {
   trace(99, "transform") << "-- rewrite labels" << end();
@@ -190,19 +189,19 @@ string drop_last(const string& s) {
           # op          subop               mod             rm32          base        index         scale       r32
           # 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
 # address 1
-loop:
-loop2:
+ $loop:
+ $loop2:
 # address 1 (labels take up no space)
             05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
 # address 6
-            eb                                                                                                              loop2/disp8
+            eb                                                                                                              $loop2/disp8
 # address 8
-            eb                                                                                                              loop3/disp8
+            eb                                                                                                              $loop3/disp8
 # address 10
-loop3:
-+transform: label 'loop' is at address 1
-+transform: label 'loop2' is at address 1
-+transform: label 'loop3' is at address 10
+ $loop3:
++transform: label '$loop' is at address 1
++transform: label '$loop2' is at address 1
++transform: label '$loop3' is at address 10
 # first jump is to -7
 +transform: instruction after transform: 'eb f9'
 # second jump is to 0 (fall through)
@@ -234,6 +233,6 @@ xz:
           # instruction                     effective address                                                   operand     displacement    immediate
           # op          subop               mod             rm32          base        index         scale       r32
           # 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
- -a:  # indent to avoid looking like a trace_should_not_contain command
+ -a:  # indent to avoid looking like a trace_should_not_contain command for this scenario
             05                                                                                                                              0x0d0c0b0a/imm32  # add to EAX
 +error: '-a' starts with '-', which can be confused with a negative number; use a different name
diff --git a/subx/037label_types.cc b/subx/037label_types.cc
new file mode 100644
index 00000000..b80db732
--- /dev/null
+++ b/subx/037label_types.cc
@@ -0,0 +1,45 @@
+//: Distinguish between labels marking the start of a function, and labels
+//: inside functions.
+//:
+//: - Labels within functions start with a '$', and are only permitted in
+//:   'jump' instructions.
+//:
+//: - Labels marking the start of functions lack the '$' sigil, and are only
+//:   permitted in 'call' instructions.
+
+:(before "Rewrite Labels(segment code)")
+check_label_types(code);
+if (trace_contains_errors()) return;
+:(code)
+void check_label_types(const segment& code) {
+  trace(99, "transform") << "-- check label types" << end();
+  for (int i = 0;  i < SIZE(code.lines);  ++i)
+    check_label_types(code.lines.at(i));
+}
+
+void check_label_types(const line& inst) {
+  int idx = first_operand(inst);
+  if (idx >= SIZE(inst.words)) return;
+  const word& target = inst.words.at(idx);
+  if (is_number(target.data)) return;  // handled elsewhere
+  if (is_jump(inst) && target.data.at(0) != '$')
+    raise << "'" << inst.original << "': jumps should always be to internal labels starting with '$'\n" << end();
+  if (is_call(inst) && target.data.at(0) == '$')
+    raise << "'" << inst.original << "': calls should always be to function labels (not starting with '$')\n" << end();
+}
+
+:(scenario catch_jump_to_function)
+% Hide_errors = true;
+== 0x1
+main:
+7e/jump-if foo/disp8
+foo:
++error: '7e/jump-if foo/disp8': jumps should always be to internal labels starting with '$'
+
+:(scenario catch_call_to_internal_label)
+% Hide_errors = true;
+== 0x1
+main:
+e8/call $foo/disp32
+ $foo:  # indent to avoid looking like a trace_count command for this scenario
++error: 'e8/call $foo/disp32': calls should always be to function labels (not starting with '$')
diff --git a/subx/ex3.subx b/subx/ex3.subx
index eb66f1bf..41d2b94e 100644
--- a/subx/ex3.subx
+++ b/subx/ex3.subx
@@ -16,18 +16,18 @@
   # counter: ECX = 1
   b9/copy                                                                                                                         1/imm32           # copy 1 to ECX
 
-loop:
+$loop:
   # while (counter <= 10)
   81          7/subop/compare     3/mod/direct    1/rm32/ecx                                                                      0xa/imm32         # compare ECX, 10/imm
-  7f/jump-if                                                                                                      exit/disp8                        # jump-if-greater exit
+  7f/jump-if                                                                                                      $exit/disp8                       # jump-if-greater $exit
   # result += counter
   01/add                          3/mod/direct    3/rm32/ebx                                          1/r32/ecx                                     # add ECX to EBX
   # ++counter
   81          0/subop/add         3/mod/direct    1/rm32/ecx                                                                      1/imm32           # add 1 to ECX
   # loop
-  eb/jump                                                                                                         loop/disp8                        # jump loop
+  eb/jump                                                                                                         $loop/disp8                       # jump $loop
 
-exit:
+$exit:
   # exit(EBX)
   b8/copy                                                                                                                         1/imm32           # copy 1 to EAX
   cd/syscall                                                                                                                      0x80/imm8         # int 80h
diff --git a/subx/ex7.subx b/subx/ex7.subx
index 07b2e016..b386df82 100644
--- a/subx/ex7.subx
+++ b/subx/ex7.subx
@@ -38,7 +38,7 @@ factorial:
   b8/copy                         .               .             .           .             .           .           .               1/imm32           # copy 1 to EAX
   # if (n <= 1) jump exit
   81          7/subop/compare     3/mod/direct    2/rm32/EDX    .           .             .           .           .               1/imm32           # compare EDX with 1
-  7e/jump-if-<=                   .               .             .           .             .           .           factorial:exit/disp8              # jump if <= to exit
+  7e/jump-if-<=                   .               .             .           .             .           .           $exit/disp8                       # jump if <= to $exit
   # EBX: n-1
   89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           2/r32/EDX   .               .                 # copy EDX to EBX
   81          5/subop/subtract    3/mod/direct    3/rm32/EBX    .           .             .           .           .               1/imm32           # subtract 1 from EBX
@@ -58,7 +58,7 @@ factorial:
   # return n * factorial(n-1)
   0f af/multiply                  3/mod/direct    2/rm32/EDX    .           .             .           0/r32/EAX   .               .                 # multiply EDX (n) into EAX (factorial(n-1))
   # TODO: check for overflow
-factorial:exit:
+$exit:
   c3/return
 
 # vim:ft=subx:nowrap:so=0
diff --git a/subx/subx.vim b/subx/subx.vim
index 17d63932..e6825c72 100644
--- a/subx/subx.vim
+++ b/subx/subx.vim
@@ -35,4 +35,11 @@ call matchadd("Warn", '\c^\s*7[45cdef].*\<\(0x\)\?[0-9a-f]\+/disp8')  " conditio
 call matchadd("Warn", '\c^\s*eb.*\<\(0x\)\?[0-9a-f]\+/disp16')  " unconditional jump disp16
 call matchadd("Warn", '\c^\s*0f[^\s]*\s*8[45cdef].*\<\(0x\)\?[0-9a-f]\+/disp16')  " conditional jump disp16
 
+" Mismatch in label type
+call matchadd("Error", '\c^\s*e8.*\$')  " call
+call matchadd("Error", '\c^\s*e9\(/[^ ]*\)\?\s*\(\.\s*\)\+[^\$\. ]\([ \$0-9a-fA-F-]\+\>\)\@!')  " unconditional jump disp8
+call matchadd("Error", '\c^\s*7[45cdef]\(/[^ ]*\)\?\s*\(\.\s*\)\+[^\$\. ]\([ \$0-9a-fA-F-]\+\>\)\@!')  " conditional jump disp8
+call matchadd("Error", '\c^\s*eb\(/[^ ]*\)\?\s*\(\.\s*\)\+[^\$\. ]\([ \$0-9a-fA-F-]\+\>\)\@!')  " unconditional jump disp16
+call matchadd("Error", '\c^\s*0f[^\s]*\s*8[45cdef]\(/[^ ]*\)\?\s*\(\.\s*\)\+[^\$\. ]\([ \$0-9a-fA-F-]\+\>\)\@!')  " conditional jump disp16
+
 let &cpo = s:save_cpo
diff --git a/subx/vim_errors.subx b/subx/vim_errors.subx
new file mode 100644
index 00000000..02a82f25
--- /dev/null
+++ b/subx/vim_errors.subx
@@ -0,0 +1,34 @@
+# test file for Vim highlighting
+
+## unindented lines below should all get Warn highlighting in .subx files
+# indented lines should get no highlighting
+
+# raw displacement in jump/call instructions
+e8 10/disp32
+e8 . 10/disp32
+e8/call . -10/disp32
+e8/call . 0x10/disp32
+e9/jump . 10/disp8
+e9/jump . -10/disp8
+e9/jump . f0/disp8
+7c/jump . 10/disp8
+7c/jump . -10/disp8
+eb/jump . 10/disp16
+eb/jump . -10/disp16
+0f/foo 8e/jump . 10/disp16
+0f/foo 8e/jump . -10/disp16
+
+## unindented lines below should all get Error highlighting in .subx files
+# indented lines should get no highlighting
+
+# mismatch in label type (call to '$' or jump to non-'$')
+e8 $foo/disp32
+e8 . $foo/disp32
+e8/call . $foo/disp32
+e8/call . $foo/disp32
+e9/jump . foo/disp8
+  e9/jump . $foo/disp8
+  e9/jump . . $foo/disp8
+7c/jump . foo/disp8
+eb/jump . foo/disp16
+0f/foo 8e/jump . foo/disp16
com> 2016-05-19 21:35:34 -0700 2983 - migrate buttons over to sandbox/' href='/akkartik/mu/commit/sandbox/010-sandbox-trace.mu?h=hlt&id=607ddf3391dba72725a368e047169004ada0fcbe'>607ddf33 ^
fa94f4d9 ^
294b2ab3 ^


fa94f4d9 ^
294b2ab3 ^
6d12a8c4 ^
fa94f4d9 ^


294b2ab3 ^
fa94f4d9 ^
607ddf33 ^

ceeb92d4 ^
607ddf33 ^



ceeb92d4 ^
607ddf33 ^
fa94f4d9 ^





294b2ab3 ^
fa94f4d9 ^


607ddf33 ^

ceeb92d4 ^
607ddf33 ^



c31209c6 ^
607ddf33 ^
ceeb92d4 ^
fa94f4d9 ^


7aef0b24 ^
6f65d591 ^
7aef0b24 ^

294b2ab3 ^


6d12a8c4 ^
7aef0b24 ^
7aef0b24 ^



294b2ab3 ^
7aef0b24 ^


ceeb92d4 ^
7aef0b24 ^


7aef0b24 ^





294b2ab3 ^
7aef0b24 ^




ceeb92d4 ^
7aef0b24 ^


7aef0b24 ^


2d91279b ^
e2b367dc ^
3d8b137c ^
fa94f4d9 ^


2d91279b ^
fa94f4d9 ^
4a48bedc ^
ea19d0dc ^
3d8b137c ^
d31037ff ^


fa94f4d9 ^





3d8b137c ^


fa94f4d9 ^
2d91279b ^
fa94f4d9 ^
3d8b137c ^


fa94f4d9 ^

2d91279b ^
fa94f4d9 ^

3d8b137c ^
d31037ff ^

29cc15d6 ^
aaf61a53 ^
ada5eb55 ^
fa94f4d9 ^


2d91279b ^
fa94f4d9 ^
4a48bedc ^
fa94f4d9 ^
be422222 ^
3d8b137c ^

fa94f4d9 ^


2d91279b ^
fa94f4d9 ^
3d8b137c ^

fa94f4d9 ^




3d8b137c ^




fa94f4d9 ^

01ce563d ^
fa94f4d9 ^
1ead3562 ^
fa94f4d9 ^




3d8b137c ^
fa94f4d9 ^
ea19d0dc ^
fa94f4d9 ^
afdda1ea ^
fa94f4d9 ^


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
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
239
240
241
242
243