8
8
((code ? memmove(code + at + num, code + at, pc - at) : 0), pc += num)
9
9
#define REL (at , to ) (to - at - 2)
10
10
#define EMIT (at , byte ) (code ? (code[at] = byte) : (at))
11
+ #define EMIT_CHECKED (at , byte ) (_emit_checked(at, code, byte, &err))
11
12
#define PC (prog->bytelen)
12
13
13
-
14
14
static char unescape (char c ) {
15
15
switch (c ) {
16
16
case 'a' :
@@ -33,9 +33,17 @@ static char unescape(char c) {
33
33
}
34
34
35
35
36
+ static void _emit_checked (int at , char * code , int val , bool * err ) {
37
+ * err |= val != (int8_t )val ;
38
+ if (code ) {
39
+ code [at ] = val ;
40
+ }
41
+ }
42
+
36
43
static const char * _compilecode (const char * re , ByteProg * prog , int sizecode )
37
44
{
38
45
char * code = sizecode ? NULL : prog -> insts ;
46
+ bool err = false;
39
47
int start = PC ;
40
48
int term = PC ;
41
49
int alt_label = 0 ;
@@ -96,7 +104,7 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
96
104
EMIT (PC ++ , * re );
97
105
}
98
106
}
99
- EMIT (term + 1 , cnt );
107
+ EMIT_CHECKED (term + 1 , cnt );
100
108
break ;
101
109
}
102
110
case '(' : {
@@ -107,7 +115,7 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
107
115
if (capture ) {
108
116
sub = ++ prog -> sub ;
109
117
EMIT (PC ++ , Save );
110
- EMIT (PC ++ , 2 * sub );
118
+ EMIT_CHECKED (PC ++ , 2 * sub );
111
119
prog -> len ++ ;
112
120
} else {
113
121
re += 2 ;
@@ -118,7 +126,7 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
118
126
119
127
if (capture ) {
120
128
EMIT (PC ++ , Save );
121
- EMIT (PC ++ , 2 * sub + 1 );
129
+ EMIT_CHECKED (PC ++ , 2 * sub + 1 );
122
130
prog -> len ++ ;
123
131
}
124
132
@@ -133,23 +141,23 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
133
141
} else {
134
142
EMIT (term , Split );
135
143
}
136
- EMIT (term + 1 , REL (term , PC ));
144
+ EMIT_CHECKED (term + 1 , REL (term , PC ));
137
145
prog -> len ++ ;
138
146
term = PC ;
139
147
break ;
140
148
case '*' :
141
149
if (PC == term ) return NULL ; // nothing to repeat
142
150
INSERT_CODE (term , 2 , PC );
143
151
EMIT (PC , Jmp );
144
- EMIT (PC + 1 , REL (PC , term ));
152
+ EMIT_CHECKED (PC + 1 , REL (PC , term ));
145
153
PC += 2 ;
146
154
if (re [1 ] == '?' ) {
147
155
EMIT (term , RSplit );
148
156
re ++ ;
149
157
} else {
150
158
EMIT (term , Split );
151
159
}
152
- EMIT (term + 1 , REL (term , PC ));
160
+ EMIT_CHECKED (term + 1 , REL (term , PC ));
153
161
prog -> len += 2 ;
154
162
term = PC ;
155
163
break ;
@@ -161,20 +169,20 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
161
169
} else {
162
170
EMIT (PC , RSplit );
163
171
}
164
- EMIT (PC + 1 , REL (PC , term ));
172
+ EMIT_CHECKED (PC + 1 , REL (PC , term ));
165
173
PC += 2 ;
166
174
prog -> len ++ ;
167
175
term = PC ;
168
176
break ;
169
177
case '|' :
170
178
if (alt_label ) {
171
- EMIT (alt_label , REL (alt_label , PC ) + 1 );
179
+ EMIT_CHECKED (alt_label , REL (alt_label , PC ) + 1 );
172
180
}
173
181
INSERT_CODE (start , 2 , PC );
174
182
EMIT (PC ++ , Jmp );
175
183
alt_label = PC ++ ;
176
184
EMIT (start , Split );
177
- EMIT (start + 1 , REL (start , PC ));
185
+ EMIT_CHECKED (start + 1 , REL (start , PC ));
178
186
prog -> len += 2 ;
179
187
term = PC ;
180
188
break ;
@@ -192,9 +200,9 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
192
200
}
193
201
194
202
if (alt_label ) {
195
- EMIT (alt_label , REL (alt_label , PC ) + 1 );
203
+ EMIT_CHECKED (alt_label , REL (alt_label , PC ) + 1 );
196
204
}
197
- return re ;
205
+ return err ? NULL : re ;
198
206
}
199
207
200
208
int re1_5_sizecode (const char * re )
0 commit comments