summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/prebuilt/wasm-flex-lexer.c700
-rw-r--r--src/sexpr-wasm.c2
-rw-r--r--src/wasm-flex-lexer.l238
-rw-r--r--src/wasm-lexer.h7
-rw-r--r--src/wasm-parser-lexer-shared.c103
-rw-r--r--src/wasm-parser-lexer-shared.h9
6 files changed, 696 insertions, 363 deletions
diff --git a/src/prebuilt/wasm-flex-lexer.c b/src/prebuilt/wasm-flex-lexer.c
index efc1cdc6..17f68e20 100644
--- a/src/prebuilt/wasm-flex-lexer.c
+++ b/src/prebuilt/wasm-flex-lexer.c
@@ -1205,9 +1205,22 @@ static yyconst flex_int32_t yy_rule_can_match_eol[223] =
typedef size_t WasmLineOffset;
WASM_DEFINE_VECTOR(line_offset, WasmLineOffset);
+typedef enum WasmLexerType {
+ WASM_LEXER_TYPE_FILE,
+ WASM_LEXER_TYPE_BUFFER,
+} WasmLexerType;
+
typedef struct WasmLexerExtra {
WasmAllocator* allocator;
- FILE* file;
+ WasmLexerType type;
+ union {
+ FILE* file;
+ struct {
+ const void* data;
+ size_t size;
+ size_t read_offset;
+ } buffer;
+ };
const char* filename;
size_t offset;
WasmLineOffsetVector line_offsets;
@@ -1215,11 +1228,22 @@ typedef struct WasmLexerExtra {
int comment_nesting;
} WasmLexerExtra;
+static void read_input(WasmLexer, char* buffer, size_t* result,
+ size_t max_size);
+
#define YY_DECL \
int wasm_lexer_lex(WASM_PARSER_STYPE* yylval_param, \
WASM_PARSER_LTYPE* yylloc_param, yyscan_t yyscanner, \
WasmParser* parser)
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ do { \
+ size_t my_result = 0; \
+ read_input(yyscanner, buf, &my_result, max_size); \
+ result = my_result; \
+ } while (0)
+
#define COMMENT_NESTING (yyextra->comment_nesting)
#define RESET_COLUMN \
do { \
@@ -1260,7 +1284,7 @@ typedef struct WasmLexerExtra {
-#line 1264 "src/prebuilt/wasm-flex-lexer.c"
+#line 1288 "src/prebuilt/wasm-flex-lexer.c"
#define INITIAL 0
#define LINE_COMMENT 1
@@ -1542,10 +1566,10 @@ YY_DECL
}
{
-#line 143 "src/wasm-flex-lexer.l"
+#line 167 "src/wasm-flex-lexer.l"
-#line 1549 "src/prebuilt/wasm-flex-lexer.c"
+#line 1573 "src/prebuilt/wasm-flex-lexer.c"
while ( 1 ) /* loops until end-of-file is reached */
{
@@ -1616,1149 +1640,1149 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
-#line 145 "src/wasm-flex-lexer.l"
+#line 169 "src/wasm-flex-lexer.l"
{ return TOK(LPAR); }
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 146 "src/wasm-flex-lexer.l"
+#line 170 "src/wasm-flex-lexer.l"
{ return TOK(RPAR); }
YY_BREAK
case 3:
YY_RULE_SETUP
-#line 147 "src/wasm-flex-lexer.l"
+#line 171 "src/wasm-flex-lexer.l"
{ LITERAL(INT); return TOK(INT); }
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 148 "src/wasm-flex-lexer.l"
+#line 172 "src/wasm-flex-lexer.l"
{ LITERAL(FLOAT); return TOK(FLOAT); }
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 149 "src/wasm-flex-lexer.l"
+#line 173 "src/wasm-flex-lexer.l"
{ LITERAL(HEXFLOAT); return TOK(FLOAT); }
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 150 "src/wasm-flex-lexer.l"
+#line 174 "src/wasm-flex-lexer.l"
{ LITERAL(INFINITY); return TOK(FLOAT); }
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 151 "src/wasm-flex-lexer.l"
+#line 175 "src/wasm-flex-lexer.l"
{ LITERAL(NAN); return TOK(FLOAT); }
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 152 "src/wasm-flex-lexer.l"
+#line 176 "src/wasm-flex-lexer.l"
{ TEXT; return TOK(TEXT); }
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 153 "src/wasm-flex-lexer.l"
+#line 177 "src/wasm-flex-lexer.l"
{ BEGIN(BAD_TEXT); }
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 154 "src/wasm-flex-lexer.l"
+#line 178 "src/wasm-flex-lexer.l"
{}
YY_BREAK
case 11:
/* rule 11 can match eol */
YY_RULE_SETUP
-#line 155 "src/wasm-flex-lexer.l"
+#line 179 "src/wasm-flex-lexer.l"
{ BEGIN(INITIAL);
RESET_COLUMN;
wasm_parser_error(yylloc, yyscanner, parser,
"newline in string"); }
YY_BREAK
case YY_STATE_EOF(BAD_TEXT):
-#line 159 "src/wasm-flex-lexer.l"
+#line 183 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"unexpected EOF");
return TOK(EOF); }
YY_BREAK
case 12:
YY_RULE_SETUP
-#line 162 "src/wasm-flex-lexer.l"
+#line 186 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"bad escape \"%.*s\"", yyleng,
yytext); }
YY_BREAK
case 13:
YY_RULE_SETUP
-#line 165 "src/wasm-flex-lexer.l"
+#line 189 "src/wasm-flex-lexer.l"
{ BEGIN(INITIAL); TEXT; return TOK(TEXT); }
YY_BREAK
case 14:
/* rule 14 can match eol */
YY_RULE_SETUP
-#line 166 "src/wasm-flex-lexer.l"
+#line 190 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"illegal character in string"); }
YY_BREAK
case 15:
YY_RULE_SETUP
-#line 168 "src/wasm-flex-lexer.l"
+#line 192 "src/wasm-flex-lexer.l"
{ TYPE(I32); return TOK(VALUE_TYPE); }
YY_BREAK
case 16:
YY_RULE_SETUP
-#line 169 "src/wasm-flex-lexer.l"
+#line 193 "src/wasm-flex-lexer.l"
{ TYPE(I64); return TOK(VALUE_TYPE); }
YY_BREAK
case 17:
YY_RULE_SETUP
-#line 170 "src/wasm-flex-lexer.l"
+#line 194 "src/wasm-flex-lexer.l"
{ TYPE(F32); return TOK(VALUE_TYPE); }
YY_BREAK
case 18:
YY_RULE_SETUP
-#line 171 "src/wasm-flex-lexer.l"
+#line 195 "src/wasm-flex-lexer.l"
{ TYPE(F64); return TOK(VALUE_TYPE); }
YY_BREAK
case 19:
YY_RULE_SETUP
-#line 172 "src/wasm-flex-lexer.l"
+#line 196 "src/wasm-flex-lexer.l"
{ return TOK(NOP); }
YY_BREAK
case 20:
YY_RULE_SETUP
-#line 173 "src/wasm-flex-lexer.l"
+#line 197 "src/wasm-flex-lexer.l"
{ return TOK(BLOCK); }
YY_BREAK
case 21:
YY_RULE_SETUP
-#line 174 "src/wasm-flex-lexer.l"
+#line 198 "src/wasm-flex-lexer.l"
{ return TOK(IF); }
YY_BREAK
case 22:
YY_RULE_SETUP
-#line 175 "src/wasm-flex-lexer.l"
+#line 199 "src/wasm-flex-lexer.l"
{ return TOK(IF); /* TODO(binji): remove */ }
YY_BREAK
case 23:
YY_RULE_SETUP
-#line 176 "src/wasm-flex-lexer.l"
+#line 200 "src/wasm-flex-lexer.l"
{ return TOK(THEN); }
YY_BREAK
case 24:
YY_RULE_SETUP
-#line 177 "src/wasm-flex-lexer.l"
+#line 201 "src/wasm-flex-lexer.l"
{ return TOK(ELSE); }
YY_BREAK
case 25:
YY_RULE_SETUP
-#line 178 "src/wasm-flex-lexer.l"
+#line 202 "src/wasm-flex-lexer.l"
{ return TOK(LOOP); }
YY_BREAK
case 26:
YY_RULE_SETUP
-#line 179 "src/wasm-flex-lexer.l"
+#line 203 "src/wasm-flex-lexer.l"
{ return TOK(BR); }
YY_BREAK
case 27:
YY_RULE_SETUP
-#line 180 "src/wasm-flex-lexer.l"
+#line 204 "src/wasm-flex-lexer.l"
{ return TOK(BR_IF); }
YY_BREAK
case 28:
YY_RULE_SETUP
-#line 181 "src/wasm-flex-lexer.l"
+#line 205 "src/wasm-flex-lexer.l"
{ return TOK(BR_TABLE); }
YY_BREAK
case 29:
YY_RULE_SETUP
-#line 182 "src/wasm-flex-lexer.l"
+#line 206 "src/wasm-flex-lexer.l"
{ return TOK(CASE); }
YY_BREAK
case 30:
YY_RULE_SETUP
-#line 183 "src/wasm-flex-lexer.l"
+#line 207 "src/wasm-flex-lexer.l"
{ return TOK(CALL); }
YY_BREAK
case 31:
YY_RULE_SETUP
-#line 184 "src/wasm-flex-lexer.l"
+#line 208 "src/wasm-flex-lexer.l"
{ return TOK(CALL_IMPORT); }
YY_BREAK
case 32:
YY_RULE_SETUP
-#line 185 "src/wasm-flex-lexer.l"
+#line 209 "src/wasm-flex-lexer.l"
{ return TOK(CALL_INDIRECT); }
YY_BREAK
case 33:
YY_RULE_SETUP
-#line 186 "src/wasm-flex-lexer.l"
+#line 210 "src/wasm-flex-lexer.l"
{ return TOK(RETURN); }
YY_BREAK
case 34:
YY_RULE_SETUP
-#line 187 "src/wasm-flex-lexer.l"
+#line 211 "src/wasm-flex-lexer.l"
{ return TOK(GET_LOCAL); }
YY_BREAK
case 35:
YY_RULE_SETUP
-#line 188 "src/wasm-flex-lexer.l"
+#line 212 "src/wasm-flex-lexer.l"
{ return TOK(SET_LOCAL); }
YY_BREAK
case 36:
YY_RULE_SETUP
-#line 189 "src/wasm-flex-lexer.l"
+#line 213 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LOAD); return TOK(LOAD); }
YY_BREAK
case 37:
YY_RULE_SETUP
-#line 190 "src/wasm-flex-lexer.l"
+#line 214 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD); return TOK(LOAD); }
YY_BREAK
case 38:
YY_RULE_SETUP
-#line 191 "src/wasm-flex-lexer.l"
+#line 215 "src/wasm-flex-lexer.l"
{ OPCODE(F32_LOAD); return TOK(LOAD); }
YY_BREAK
case 39:
YY_RULE_SETUP
-#line 192 "src/wasm-flex-lexer.l"
+#line 216 "src/wasm-flex-lexer.l"
{ OPCODE(F64_LOAD); return TOK(LOAD); }
YY_BREAK
case 40:
YY_RULE_SETUP
-#line 193 "src/wasm-flex-lexer.l"
+#line 217 "src/wasm-flex-lexer.l"
{ OPCODE(I32_STORE); return TOK(STORE); }
YY_BREAK
case 41:
YY_RULE_SETUP
-#line 194 "src/wasm-flex-lexer.l"
+#line 218 "src/wasm-flex-lexer.l"
{ OPCODE(I64_STORE); return TOK(STORE); }
YY_BREAK
case 42:
YY_RULE_SETUP
-#line 195 "src/wasm-flex-lexer.l"
+#line 219 "src/wasm-flex-lexer.l"
{ OPCODE(F32_STORE); return TOK(STORE); }
YY_BREAK
case 43:
YY_RULE_SETUP
-#line 196 "src/wasm-flex-lexer.l"
+#line 220 "src/wasm-flex-lexer.l"
{ OPCODE(F64_STORE); return TOK(STORE); }
YY_BREAK
case 44:
YY_RULE_SETUP
-#line 197 "src/wasm-flex-lexer.l"
+#line 221 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LOAD8_S); return TOK(LOAD); }
YY_BREAK
case 45:
YY_RULE_SETUP
-#line 198 "src/wasm-flex-lexer.l"
+#line 222 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD8_S); return TOK(LOAD); }
YY_BREAK
case 46:
YY_RULE_SETUP
-#line 199 "src/wasm-flex-lexer.l"
+#line 223 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LOAD8_U); return TOK(LOAD); }
YY_BREAK
case 47:
YY_RULE_SETUP
-#line 200 "src/wasm-flex-lexer.l"
+#line 224 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD8_U); return TOK(LOAD); }
YY_BREAK
case 48:
YY_RULE_SETUP
-#line 201 "src/wasm-flex-lexer.l"
+#line 225 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LOAD16_S); return TOK(LOAD); }
YY_BREAK
case 49:
YY_RULE_SETUP
-#line 202 "src/wasm-flex-lexer.l"
+#line 226 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD16_S); return TOK(LOAD); }
YY_BREAK
case 50:
YY_RULE_SETUP
-#line 203 "src/wasm-flex-lexer.l"
+#line 227 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LOAD16_U); return TOK(LOAD); }
YY_BREAK
case 51:
YY_RULE_SETUP
-#line 204 "src/wasm-flex-lexer.l"
+#line 228 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD16_U); return TOK(LOAD); }
YY_BREAK
case 52:
YY_RULE_SETUP
-#line 205 "src/wasm-flex-lexer.l"
+#line 229 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD32_S); return TOK(LOAD); }
YY_BREAK
case 53:
YY_RULE_SETUP
-#line 206 "src/wasm-flex-lexer.l"
+#line 230 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LOAD32_U); return TOK(LOAD); }
YY_BREAK
case 54:
YY_RULE_SETUP
-#line 207 "src/wasm-flex-lexer.l"
+#line 231 "src/wasm-flex-lexer.l"
{ OPCODE(I32_STORE8); return TOK(STORE); }
YY_BREAK
case 55:
YY_RULE_SETUP
-#line 208 "src/wasm-flex-lexer.l"
+#line 232 "src/wasm-flex-lexer.l"
{ OPCODE(I64_STORE8); return TOK(STORE); }
YY_BREAK
case 56:
YY_RULE_SETUP
-#line 209 "src/wasm-flex-lexer.l"
+#line 233 "src/wasm-flex-lexer.l"
{ OPCODE(I32_STORE16); return TOK(STORE); }
YY_BREAK
case 57:
YY_RULE_SETUP
-#line 210 "src/wasm-flex-lexer.l"
+#line 234 "src/wasm-flex-lexer.l"
{ OPCODE(I64_STORE16); return TOK(STORE); }
YY_BREAK
case 58:
YY_RULE_SETUP
-#line 211 "src/wasm-flex-lexer.l"
+#line 235 "src/wasm-flex-lexer.l"
{ OPCODE(I64_STORE32); return TOK(STORE); }
YY_BREAK
case 59:
YY_RULE_SETUP
-#line 212 "src/wasm-flex-lexer.l"
+#line 236 "src/wasm-flex-lexer.l"
{ TEXT_AT(7); return TOK(OFFSET); }
YY_BREAK
case 60:
YY_RULE_SETUP
-#line 213 "src/wasm-flex-lexer.l"
+#line 237 "src/wasm-flex-lexer.l"
{ TEXT_AT(6); return TOK(ALIGN); }
YY_BREAK
case 61:
YY_RULE_SETUP
-#line 214 "src/wasm-flex-lexer.l"
+#line 238 "src/wasm-flex-lexer.l"
{ TYPE(I32); return TOK(CONST); }
YY_BREAK
case 62:
YY_RULE_SETUP
-#line 215 "src/wasm-flex-lexer.l"
+#line 239 "src/wasm-flex-lexer.l"
{ TYPE(I64); return TOK(CONST); }
YY_BREAK
case 63:
YY_RULE_SETUP
-#line 216 "src/wasm-flex-lexer.l"
+#line 240 "src/wasm-flex-lexer.l"
{ TYPE(F32); return TOK(CONST); }
YY_BREAK
case 64:
YY_RULE_SETUP
-#line 217 "src/wasm-flex-lexer.l"
+#line 241 "src/wasm-flex-lexer.l"
{ TYPE(F64); return TOK(CONST); }
YY_BREAK
case 65:
YY_RULE_SETUP
-#line 218 "src/wasm-flex-lexer.l"
+#line 242 "src/wasm-flex-lexer.l"
{ OPCODE(I32_EQZ); return TOK(CONVERT); }
YY_BREAK
case 66:
YY_RULE_SETUP
-#line 219 "src/wasm-flex-lexer.l"
+#line 243 "src/wasm-flex-lexer.l"
{ OPCODE(I64_EQZ); return TOK(CONVERT); }
YY_BREAK
case 67:
YY_RULE_SETUP
-#line 220 "src/wasm-flex-lexer.l"
+#line 244 "src/wasm-flex-lexer.l"
{ OPCODE(I32_CLZ); return TOK(UNARY); }
YY_BREAK
case 68:
YY_RULE_SETUP
-#line 221 "src/wasm-flex-lexer.l"
+#line 245 "src/wasm-flex-lexer.l"
{ OPCODE(I64_CLZ); return TOK(UNARY); }
YY_BREAK
case 69:
YY_RULE_SETUP
-#line 222 "src/wasm-flex-lexer.l"
+#line 246 "src/wasm-flex-lexer.l"
{ OPCODE(I32_CTZ); return TOK(UNARY); }
YY_BREAK
case 70:
YY_RULE_SETUP
-#line 223 "src/wasm-flex-lexer.l"
+#line 247 "src/wasm-flex-lexer.l"
{ OPCODE(I64_CTZ); return TOK(UNARY); }
YY_BREAK
case 71:
YY_RULE_SETUP
-#line 224 "src/wasm-flex-lexer.l"
+#line 248 "src/wasm-flex-lexer.l"
{ OPCODE(I32_POPCNT); return TOK(UNARY); }
YY_BREAK
case 72:
YY_RULE_SETUP
-#line 225 "src/wasm-flex-lexer.l"
+#line 249 "src/wasm-flex-lexer.l"
{ OPCODE(I64_POPCNT); return TOK(UNARY); }
YY_BREAK
case 73:
YY_RULE_SETUP
-#line 226 "src/wasm-flex-lexer.l"
+#line 250 "src/wasm-flex-lexer.l"
{ OPCODE(F32_NEG); return TOK(UNARY); }
YY_BREAK
case 74:
YY_RULE_SETUP
-#line 227 "src/wasm-flex-lexer.l"
+#line 251 "src/wasm-flex-lexer.l"
{ OPCODE(F64_NEG); return TOK(UNARY); }
YY_BREAK
case 75:
YY_RULE_SETUP
-#line 228 "src/wasm-flex-lexer.l"
+#line 252 "src/wasm-flex-lexer.l"
{ OPCODE(F32_ABS); return TOK(UNARY); }
YY_BREAK
case 76:
YY_RULE_SETUP
-#line 229 "src/wasm-flex-lexer.l"
+#line 253 "src/wasm-flex-lexer.l"
{ OPCODE(F64_ABS); return TOK(UNARY); }
YY_BREAK
case 77:
YY_RULE_SETUP
-#line 230 "src/wasm-flex-lexer.l"
+#line 254 "src/wasm-flex-lexer.l"
{ OPCODE(F32_SQRT); return TOK(UNARY); }
YY_BREAK
case 78:
YY_RULE_SETUP
-#line 231 "src/wasm-flex-lexer.l"
+#line 255 "src/wasm-flex-lexer.l"
{ OPCODE(F64_SQRT); return TOK(UNARY); }
YY_BREAK
case 79:
YY_RULE_SETUP
-#line 232 "src/wasm-flex-lexer.l"
+#line 256 "src/wasm-flex-lexer.l"
{ OPCODE(F32_CEIL); return TOK(UNARY); }
YY_BREAK
case 80:
YY_RULE_SETUP
-#line 233 "src/wasm-flex-lexer.l"
+#line 257 "src/wasm-flex-lexer.l"
{ OPCODE(F64_CEIL); return TOK(UNARY); }
YY_BREAK
case 81:
YY_RULE_SETUP
-#line 234 "src/wasm-flex-lexer.l"
+#line 258 "src/wasm-flex-lexer.l"
{ OPCODE(F32_FLOOR); return TOK(UNARY); }
YY_BREAK
case 82:
YY_RULE_SETUP
-#line 235 "src/wasm-flex-lexer.l"
+#line 259 "src/wasm-flex-lexer.l"
{ OPCODE(F64_FLOOR); return TOK(UNARY); }
YY_BREAK
case 83:
YY_RULE_SETUP
-#line 236 "src/wasm-flex-lexer.l"
+#line 260 "src/wasm-flex-lexer.l"
{ OPCODE(F32_TRUNC); return TOK(UNARY); }
YY_BREAK
case 84:
YY_RULE_SETUP
-#line 237 "src/wasm-flex-lexer.l"
+#line 261 "src/wasm-flex-lexer.l"
{ OPCODE(F64_TRUNC); return TOK(UNARY); }
YY_BREAK
case 85:
YY_RULE_SETUP
-#line 238 "src/wasm-flex-lexer.l"
+#line 262 "src/wasm-flex-lexer.l"
{ OPCODE(F32_NEAREST); return TOK(UNARY); }
YY_BREAK
case 86:
YY_RULE_SETUP
-#line 239 "src/wasm-flex-lexer.l"
+#line 263 "src/wasm-flex-lexer.l"
{ OPCODE(F64_NEAREST); return TOK(UNARY); }
YY_BREAK
case 87:
YY_RULE_SETUP
-#line 240 "src/wasm-flex-lexer.l"
+#line 264 "src/wasm-flex-lexer.l"
{ OPCODE(I32_ADD); return TOK(BINARY); }
YY_BREAK
case 88:
YY_RULE_SETUP
-#line 241 "src/wasm-flex-lexer.l"
+#line 265 "src/wasm-flex-lexer.l"
{ OPCODE(I64_ADD); return TOK(BINARY); }
YY_BREAK
case 89:
YY_RULE_SETUP
-#line 242 "src/wasm-flex-lexer.l"
+#line 266 "src/wasm-flex-lexer.l"
{ OPCODE(I32_SUB); return TOK(BINARY); }
YY_BREAK
case 90:
YY_RULE_SETUP
-#line 243 "src/wasm-flex-lexer.l"
+#line 267 "src/wasm-flex-lexer.l"
{ OPCODE(I64_SUB); return TOK(BINARY); }
YY_BREAK
case 91:
YY_RULE_SETUP
-#line 244 "src/wasm-flex-lexer.l"
+#line 268 "src/wasm-flex-lexer.l"
{ OPCODE(I32_MUL); return TOK(BINARY); }
YY_BREAK
case 92:
YY_RULE_SETUP
-#line 245 "src/wasm-flex-lexer.l"
+#line 269 "src/wasm-flex-lexer.l"
{ OPCODE(I64_MUL); return TOK(BINARY); }
YY_BREAK
case 93:
YY_RULE_SETUP
-#line 246 "src/wasm-flex-lexer.l"
+#line 270 "src/wasm-flex-lexer.l"
{ OPCODE(I32_DIV_S); return TOK(BINARY); }
YY_BREAK
case 94:
YY_RULE_SETUP
-#line 247 "src/wasm-flex-lexer.l"
+#line 271 "src/wasm-flex-lexer.l"
{ OPCODE(I64_DIV_S); return TOK(BINARY); }
YY_BREAK
case 95:
YY_RULE_SETUP
-#line 248 "src/wasm-flex-lexer.l"
+#line 272 "src/wasm-flex-lexer.l"
{ OPCODE(I32_DIV_U); return TOK(BINARY); }
YY_BREAK
case 96:
YY_RULE_SETUP
-#line 249 "src/wasm-flex-lexer.l"
+#line 273 "src/wasm-flex-lexer.l"
{ OPCODE(I64_DIV_U); return TOK(BINARY); }
YY_BREAK
case 97:
YY_RULE_SETUP
-#line 250 "src/wasm-flex-lexer.l"
+#line 274 "src/wasm-flex-lexer.l"
{ OPCODE(I32_REM_S); return TOK(BINARY); }
YY_BREAK
case 98:
YY_RULE_SETUP
-#line 251 "src/wasm-flex-lexer.l"
+#line 275 "src/wasm-flex-lexer.l"
{ OPCODE(I64_REM_S); return TOK(BINARY); }
YY_BREAK
case 99:
YY_RULE_SETUP
-#line 252 "src/wasm-flex-lexer.l"
+#line 276 "src/wasm-flex-lexer.l"
{ OPCODE(I32_REM_U); return TOK(BINARY); }
YY_BREAK
case 100:
YY_RULE_SETUP
-#line 253 "src/wasm-flex-lexer.l"
+#line 277 "src/wasm-flex-lexer.l"
{ OPCODE(I64_REM_U); return TOK(BINARY); }
YY_BREAK
case 101:
YY_RULE_SETUP
-#line 254 "src/wasm-flex-lexer.l"
+#line 278 "src/wasm-flex-lexer.l"
{ OPCODE(I32_AND); return TOK(BINARY); }
YY_BREAK
case 102:
YY_RULE_SETUP
-#line 255 "src/wasm-flex-lexer.l"
+#line 279 "src/wasm-flex-lexer.l"
{ OPCODE(I64_AND); return TOK(BINARY); }
YY_BREAK
case 103:
YY_RULE_SETUP
-#line 256 "src/wasm-flex-lexer.l"
+#line 280 "src/wasm-flex-lexer.l"
{ OPCODE(I32_OR); return TOK(BINARY); }
YY_BREAK
case 104:
YY_RULE_SETUP
-#line 257 "src/wasm-flex-lexer.l"
+#line 281 "src/wasm-flex-lexer.l"
{ OPCODE(I64_OR); return TOK(BINARY); }
YY_BREAK
case 105:
YY_RULE_SETUP
-#line 258 "src/wasm-flex-lexer.l"
+#line 282 "src/wasm-flex-lexer.l"
{ OPCODE(I32_XOR); return TOK(BINARY); }
YY_BREAK
case 106:
YY_RULE_SETUP
-#line 259 "src/wasm-flex-lexer.l"
+#line 283 "src/wasm-flex-lexer.l"
{ OPCODE(I64_XOR); return TOK(BINARY); }
YY_BREAK
case 107:
YY_RULE_SETUP
-#line 260 "src/wasm-flex-lexer.l"
+#line 284 "src/wasm-flex-lexer.l"
{ OPCODE(I32_SHL); return TOK(BINARY); }
YY_BREAK
case 108:
YY_RULE_SETUP
-#line 261 "src/wasm-flex-lexer.l"
+#line 285 "src/wasm-flex-lexer.l"
{ OPCODE(I64_SHL); return TOK(BINARY); }
YY_BREAK
case 109:
YY_RULE_SETUP
-#line 262 "src/wasm-flex-lexer.l"
+#line 286 "src/wasm-flex-lexer.l"
{ OPCODE(I32_SHR_S); return TOK(BINARY); }
YY_BREAK
case 110:
YY_RULE_SETUP
-#line 263 "src/wasm-flex-lexer.l"
+#line 287 "src/wasm-flex-lexer.l"
{ OPCODE(I64_SHR_S); return TOK(BINARY); }
YY_BREAK
case 111:
YY_RULE_SETUP
-#line 264 "src/wasm-flex-lexer.l"
+#line 288 "src/wasm-flex-lexer.l"
{ OPCODE(I32_SHR_U); return TOK(BINARY); }
YY_BREAK
case 112:
YY_RULE_SETUP
-#line 265 "src/wasm-flex-lexer.l"
+#line 289 "src/wasm-flex-lexer.l"
{ OPCODE(I64_SHR_U); return TOK(BINARY); }
YY_BREAK
case 113:
YY_RULE_SETUP
-#line 266 "src/wasm-flex-lexer.l"
+#line 290 "src/wasm-flex-lexer.l"
{ OPCODE(I32_ROTL); return TOK(BINARY); }
YY_BREAK
case 114:
YY_RULE_SETUP
-#line 267 "src/wasm-flex-lexer.l"
+#line 291 "src/wasm-flex-lexer.l"
{ OPCODE(I64_ROTL); return TOK(BINARY); }
YY_BREAK
case 115:
YY_RULE_SETUP
-#line 268 "src/wasm-flex-lexer.l"
+#line 292 "src/wasm-flex-lexer.l"
{ OPCODE(I32_ROTR); return TOK(BINARY); }
YY_BREAK
case 116:
YY_RULE_SETUP
-#line 269 "src/wasm-flex-lexer.l"
+#line 293 "src/wasm-flex-lexer.l"
{ OPCODE(I64_ROTR); return TOK(BINARY); }
YY_BREAK
case 117:
YY_RULE_SETUP
-#line 270 "src/wasm-flex-lexer.l"
+#line 294 "src/wasm-flex-lexer.l"
{ OPCODE(F32_ADD); return TOK(BINARY); }
YY_BREAK
case 118:
YY_RULE_SETUP
-#line 271 "src/wasm-flex-lexer.l"
+#line 295 "src/wasm-flex-lexer.l"
{ OPCODE(F64_ADD); return TOK(BINARY); }
YY_BREAK
case 119:
YY_RULE_SETUP
-#line 272 "src/wasm-flex-lexer.l"
+#line 296 "src/wasm-flex-lexer.l"
{ OPCODE(F32_SUB); return TOK(BINARY); }
YY_BREAK
case 120:
YY_RULE_SETUP
-#line 273 "src/wasm-flex-lexer.l"
+#line 297 "src/wasm-flex-lexer.l"
{ OPCODE(F64_SUB); return TOK(BINARY); }
YY_BREAK
case 121:
YY_RULE_SETUP
-#line 274 "src/wasm-flex-lexer.l"
+#line 298 "src/wasm-flex-lexer.l"
{ OPCODE(F32_MUL); return TOK(BINARY); }
YY_BREAK
case 122:
YY_RULE_SETUP
-#line 275 "src/wasm-flex-lexer.l"
+#line 299 "src/wasm-flex-lexer.l"
{ OPCODE(F64_MUL); return TOK(BINARY); }
YY_BREAK
case 123:
YY_RULE_SETUP
-#line 276 "src/wasm-flex-lexer.l"
+#line 300 "src/wasm-flex-lexer.l"
{ OPCODE(F32_DIV); return TOK(BINARY); }
YY_BREAK
case 124:
YY_RULE_SETUP
-#line 277 "src/wasm-flex-lexer.l"
+#line 301 "src/wasm-flex-lexer.l"
{ OPCODE(F64_DIV); return TOK(BINARY); }
YY_BREAK
case 125:
YY_RULE_SETUP
-#line 278 "src/wasm-flex-lexer.l"
+#line 302 "src/wasm-flex-lexer.l"
{ OPCODE(F32_MIN); return TOK(BINARY); }
YY_BREAK
case 126:
YY_RULE_SETUP
-#line 279 "src/wasm-flex-lexer.l"
+#line 303 "src/wasm-flex-lexer.l"
{ OPCODE(F64_MIN); return TOK(BINARY); }
YY_BREAK
case 127:
YY_RULE_SETUP
-#line 280 "src/wasm-flex-lexer.l"
+#line 304 "src/wasm-flex-lexer.l"
{ OPCODE(F32_MAX); return TOK(BINARY); }
YY_BREAK
case 128:
YY_RULE_SETUP
-#line 281 "src/wasm-flex-lexer.l"
+#line 305 "src/wasm-flex-lexer.l"
{ OPCODE(F64_MAX); return TOK(BINARY); }
YY_BREAK
case 129:
YY_RULE_SETUP
-#line 282 "src/wasm-flex-lexer.l"
+#line 306 "src/wasm-flex-lexer.l"
{ OPCODE(F32_COPYSIGN); return TOK(BINARY); }
YY_BREAK
case 130:
YY_RULE_SETUP
-#line 283 "src/wasm-flex-lexer.l"
+#line 307 "src/wasm-flex-lexer.l"
{ OPCODE(F64_COPYSIGN); return TOK(BINARY); }
YY_BREAK
case 131:
YY_RULE_SETUP
-#line 284 "src/wasm-flex-lexer.l"
+#line 308 "src/wasm-flex-lexer.l"
{ OPCODE(I32_EQ); return TOK(COMPARE); }
YY_BREAK
case 132:
YY_RULE_SETUP
-#line 285 "src/wasm-flex-lexer.l"
+#line 309 "src/wasm-flex-lexer.l"
{ OPCODE(I64_EQ); return TOK(COMPARE); }
YY_BREAK
case 133:
YY_RULE_SETUP
-#line 286 "src/wasm-flex-lexer.l"
+#line 310 "src/wasm-flex-lexer.l"
{ OPCODE(I32_NE); return TOK(COMPARE); }
YY_BREAK
case 134:
YY_RULE_SETUP
-#line 287 "src/wasm-flex-lexer.l"
+#line 311 "src/wasm-flex-lexer.l"
{ OPCODE(I64_NE); return TOK(COMPARE); }
YY_BREAK
case 135:
YY_RULE_SETUP
-#line 288 "src/wasm-flex-lexer.l"
+#line 312 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LT_S); return TOK(COMPARE); }
YY_BREAK
case 136:
YY_RULE_SETUP
-#line 289 "src/wasm-flex-lexer.l"
+#line 313 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LT_S); return TOK(COMPARE); }
YY_BREAK
case 137:
YY_RULE_SETUP
-#line 290 "src/wasm-flex-lexer.l"
+#line 314 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LT_U); return TOK(COMPARE); }
YY_BREAK
case 138:
YY_RULE_SETUP
-#line 291 "src/wasm-flex-lexer.l"
+#line 315 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LT_U); return TOK(COMPARE); }
YY_BREAK
case 139:
YY_RULE_SETUP
-#line 292 "src/wasm-flex-lexer.l"
+#line 316 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LE_S); return TOK(COMPARE); }
YY_BREAK
case 140:
YY_RULE_SETUP
-#line 293 "src/wasm-flex-lexer.l"
+#line 317 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LE_S); return TOK(COMPARE); }
YY_BREAK
case 141:
YY_RULE_SETUP
-#line 294 "src/wasm-flex-lexer.l"
+#line 318 "src/wasm-flex-lexer.l"
{ OPCODE(I32_LE_U); return TOK(COMPARE); }
YY_BREAK
case 142:
YY_RULE_SETUP
-#line 295 "src/wasm-flex-lexer.l"
+#line 319 "src/wasm-flex-lexer.l"
{ OPCODE(I64_LE_U); return TOK(COMPARE); }
YY_BREAK
case 143:
YY_RULE_SETUP
-#line 296 "src/wasm-flex-lexer.l"
+#line 320 "src/wasm-flex-lexer.l"
{ OPCODE(I32_GT_S); return TOK(COMPARE); }
YY_BREAK
case 144:
YY_RULE_SETUP
-#line 297 "src/wasm-flex-lexer.l"
+#line 321 "src/wasm-flex-lexer.l"
{ OPCODE(I64_GT_S); return TOK(COMPARE); }
YY_BREAK
case 145:
YY_RULE_SETUP
-#line 298 "src/wasm-flex-lexer.l"
+#line 322 "src/wasm-flex-lexer.l"
{ OPCODE(I32_GT_U); return TOK(COMPARE); }
YY_BREAK
case 146:
YY_RULE_SETUP
-#line 299 "src/wasm-flex-lexer.l"
+#line 323 "src/wasm-flex-lexer.l"
{ OPCODE(I64_GT_U); return TOK(COMPARE); }
YY_BREAK
case 147:
YY_RULE_SETUP
-#line 300 "src/wasm-flex-lexer.l"
+#line 324 "src/wasm-flex-lexer.l"
{ OPCODE(I32_GE_S); return TOK(COMPARE); }
YY_BREAK
case 148:
YY_RULE_SETUP
-#line 301 "src/wasm-flex-lexer.l"
+#line 325 "src/wasm-flex-lexer.l"
{ OPCODE(I64_GE_S); return TOK(COMPARE); }
YY_BREAK
case 149:
YY_RULE_SETUP
-#line 302 "src/wasm-flex-lexer.l"
+#line 326 "src/wasm-flex-lexer.l"
{ OPCODE(I32_GE_U); return TOK(COMPARE); }
YY_BREAK
case 150:
YY_RULE_SETUP
-#line 303 "src/wasm-flex-lexer.l"
+#line 327 "src/wasm-flex-lexer.l"
{ OPCODE(I64_GE_U); return TOK(COMPARE); }
YY_BREAK
case 151:
YY_RULE_SETUP
-#line 304 "src/wasm-flex-lexer.l"
+#line 328 "src/wasm-flex-lexer.l"
{ OPCODE(F32_EQ); return TOK(COMPARE); }
YY_BREAK
case 152:
YY_RULE_SETUP
-#line 305 "src/wasm-flex-lexer.l"
+#line 329 "src/wasm-flex-lexer.l"
{ OPCODE(F64_EQ); return TOK(COMPARE); }
YY_BREAK
case 153:
YY_RULE_SETUP
-#line 306 "src/wasm-flex-lexer.l"
+#line 330 "src/wasm-flex-lexer.l"
{ OPCODE(F32_NE); return TOK(COMPARE); }
YY_BREAK
case 154:
YY_RULE_SETUP
-#line 307 "src/wasm-flex-lexer.l"
+#line 331 "src/wasm-flex-lexer.l"
{ OPCODE(F64_NE); return TOK(COMPARE); }
YY_BREAK
case 155:
YY_RULE_SETUP
-#line 308 "src/wasm-flex-lexer.l"
+#line 332 "src/wasm-flex-lexer.l"
{ OPCODE(F32_LT); return TOK(COMPARE); }
YY_BREAK
case 156:
YY_RULE_SETUP
-#line 309 "src/wasm-flex-lexer.l"
+#line 333 "src/wasm-flex-lexer.l"
{ OPCODE(F64_LT); return TOK(COMPARE); }
YY_BREAK
case 157:
YY_RULE_SETUP
-#line 310 "src/wasm-flex-lexer.l"
+#line 334 "src/wasm-flex-lexer.l"
{ OPCODE(F32_LE); return TOK(COMPARE); }
YY_BREAK
case 158:
YY_RULE_SETUP
-#line 311 "src/wasm-flex-lexer.l"
+#line 335 "src/wasm-flex-lexer.l"
{ OPCODE(F64_LE); return TOK(COMPARE); }
YY_BREAK
case 159:
YY_RULE_SETUP
-#line 312 "src/wasm-flex-lexer.l"
+#line 336 "src/wasm-flex-lexer.l"
{ OPCODE(F32_GT); return TOK(COMPARE); }
YY_BREAK
case 160:
YY_RULE_SETUP
-#line 313 "src/wasm-flex-lexer.l"
+#line 337 "src/wasm-flex-lexer.l"
{ OPCODE(F64_GT); return TOK(COMPARE); }
YY_BREAK
case 161:
YY_RULE_SETUP
-#line 314 "src/wasm-flex-lexer.l"
+#line 338 "src/wasm-flex-lexer.l"
{ OPCODE(F32_GE); return TOK(COMPARE); }
YY_BREAK
case 162:
YY_RULE_SETUP
-#line 315 "src/wasm-flex-lexer.l"
+#line 339 "src/wasm-flex-lexer.l"
{ OPCODE(F64_GE); return TOK(COMPARE); }
YY_BREAK
case 163:
YY_RULE_SETUP
-#line 316 "src/wasm-flex-lexer.l"
+#line 340 "src/wasm-flex-lexer.l"
{ OPCODE(I64_EXTEND_S_I32); return TOK(CONVERT); }
YY_BREAK
case 164:
YY_RULE_SETUP
-#line 317 "src/wasm-flex-lexer.l"
+#line 341 "src/wasm-flex-lexer.l"
{ OPCODE(I64_EXTEND_U_I32); return TOK(CONVERT); }
YY_BREAK
case 165:
YY_RULE_SETUP
-#line 318 "src/wasm-flex-lexer.l"
+#line 342 "src/wasm-flex-lexer.l"
{ OPCODE(I32_WRAP_I64); return TOK(CONVERT); }
YY_BREAK
case 166:
YY_RULE_SETUP
-#line 319 "src/wasm-flex-lexer.l"
+#line 343 "src/wasm-flex-lexer.l"
{ OPCODE(I32_TRUNC_S_F32); return TOK(CONVERT); }
YY_BREAK
case 167:
YY_RULE_SETUP
-#line 320 "src/wasm-flex-lexer.l"
+#line 344 "src/wasm-flex-lexer.l"
{ OPCODE(I64_TRUNC_S_F32); return TOK(CONVERT); }
YY_BREAK
case 168:
YY_RULE_SETUP
-#line 321 "src/wasm-flex-lexer.l"
+#line 345 "src/wasm-flex-lexer.l"
{ OPCODE(I32_TRUNC_S_F64); return TOK(CONVERT); }
YY_BREAK
case 169:
YY_RULE_SETUP
-#line 322 "src/wasm-flex-lexer.l"
+#line 346 "src/wasm-flex-lexer.l"
{ OPCODE(I64_TRUNC_S_F64); return TOK(CONVERT); }
YY_BREAK
case 170:
YY_RULE_SETUP
-#line 323 "src/wasm-flex-lexer.l"
+#line 347 "src/wasm-flex-lexer.l"
{ OPCODE(I32_TRUNC_U_F32); return TOK(CONVERT); }
YY_BREAK
case 171:
YY_RULE_SETUP
-#line 324 "src/wasm-flex-lexer.l"
+#line 348 "src/wasm-flex-lexer.l"
{ OPCODE(I64_TRUNC_U_F32); return TOK(CONVERT); }
YY_BREAK
case 172:
YY_RULE_SETUP
-#line 325 "src/wasm-flex-lexer.l"
+#line 349 "src/wasm-flex-lexer.l"
{ OPCODE(I32_TRUNC_U_F64); return TOK(CONVERT); }
YY_BREAK
case 173:
YY_RULE_SETUP
-#line 326 "src/wasm-flex-lexer.l"
+#line 350 "src/wasm-flex-lexer.l"
{ OPCODE(I64_TRUNC_U_F64); return TOK(CONVERT); }
YY_BREAK
case 174:
YY_RULE_SETUP
-#line 327 "src/wasm-flex-lexer.l"
+#line 351 "src/wasm-flex-lexer.l"
{ OPCODE(F32_CONVERT_S_I32); return TOK(CONVERT); }
YY_BREAK
case 175:
YY_RULE_SETUP
-#line 328 "src/wasm-flex-lexer.l"
+#line 352 "src/wasm-flex-lexer.l"
{ OPCODE(F64_CONVERT_S_I32); return TOK(CONVERT); }
YY_BREAK
case 176:
YY_RULE_SETUP
-#line 329 "src/wasm-flex-lexer.l"
+#line 353 "src/wasm-flex-lexer.l"
{ OPCODE(F32_CONVERT_S_I64); return TOK(CONVERT); }
YY_BREAK
case 177:
YY_RULE_SETUP
-#line 330 "src/wasm-flex-lexer.l"
+#line 354 "src/wasm-flex-lexer.l"
{ OPCODE(F64_CONVERT_S_I64); return TOK(CONVERT); }
YY_BREAK
case 178:
YY_RULE_SETUP
-#line 331 "src/wasm-flex-lexer.l"
+#line 355 "src/wasm-flex-lexer.l"
{ OPCODE(F32_CONVERT_U_I32); return TOK(CONVERT); }
YY_BREAK
case 179:
YY_RULE_SETUP
-#line 332 "src/wasm-flex-lexer.l"
+#line 356 "src/wasm-flex-lexer.l"
{ OPCODE(F64_CONVERT_U_I32); return TOK(CONVERT); }
YY_BREAK
case 180:
YY_RULE_SETUP
-#line 333 "src/wasm-flex-lexer.l"
+#line 357 "src/wasm-flex-lexer.l"
{ OPCODE(F32_CONVERT_U_I64); return TOK(CONVERT); }
YY_BREAK
case 181:
YY_RULE_SETUP
-#line 334 "src/wasm-flex-lexer.l"
+#line 358 "src/wasm-flex-lexer.l"
{ OPCODE(F64_CONVERT_U_I64); return TOK(CONVERT); }
YY_BREAK
case 182:
YY_RULE_SETUP
-#line 335 "src/wasm-flex-lexer.l"
+#line 359 "src/wasm-flex-lexer.l"
{ OPCODE(F64_PROMOTE_F32); return TOK(CONVERT); }
YY_BREAK
case 183:
YY_RULE_SETUP
-#line 336 "src/wasm-flex-lexer.l"
+#line 360 "src/wasm-flex-lexer.l"
{ OPCODE(F32_DEMOTE_F64); return TOK(CONVERT); }
YY_BREAK
case 184:
YY_RULE_SETUP
-#line 337 "src/wasm-flex-lexer.l"
+#line 361 "src/wasm-flex-lexer.l"
{ OPCODE(F32_REINTERPRET_I32); return TOK(CONVERT); }
YY_BREAK
case 185:
YY_RULE_SETUP
-#line 338 "src/wasm-flex-lexer.l"
+#line 362 "src/wasm-flex-lexer.l"
{ OPCODE(I32_REINTERPRET_F32); return TOK(CONVERT); }
YY_BREAK
case 186:
YY_RULE_SETUP
-#line 339 "src/wasm-flex-lexer.l"
+#line 363 "src/wasm-flex-lexer.l"
{ OPCODE(F64_REINTERPRET_I64); return TOK(CONVERT); }
YY_BREAK
case 187:
YY_RULE_SETUP
-#line 340 "src/wasm-flex-lexer.l"
+#line 364 "src/wasm-flex-lexer.l"
{ OPCODE(I64_REINTERPRET_F64); return TOK(CONVERT); }
YY_BREAK
case 188:
YY_RULE_SETUP
-#line 341 "src/wasm-flex-lexer.l"
+#line 365 "src/wasm-flex-lexer.l"
{ return TOK(SELECT); }
YY_BREAK
case 189:
YY_RULE_SETUP
-#line 342 "src/wasm-flex-lexer.l"
+#line 366 "src/wasm-flex-lexer.l"
{ return TOK(UNREACHABLE); }
YY_BREAK
case 190:
YY_RULE_SETUP
-#line 343 "src/wasm-flex-lexer.l"
+#line 367 "src/wasm-flex-lexer.l"
{ return TOK(MEMORY_SIZE); }
YY_BREAK
case 191:
YY_RULE_SETUP
-#line 344 "src/wasm-flex-lexer.l"
+#line 368 "src/wasm-flex-lexer.l"
{ return TOK(GROW_MEMORY); }
YY_BREAK
case 192:
YY_RULE_SETUP
-#line 345 "src/wasm-flex-lexer.l"
+#line 369 "src/wasm-flex-lexer.l"
{ return TOK(TYPE); }
YY_BREAK
case 193:
YY_RULE_SETUP
-#line 346 "src/wasm-flex-lexer.l"
+#line 370 "src/wasm-flex-lexer.l"
{ return TOK(FUNC); }
YY_BREAK
case 194:
YY_RULE_SETUP
-#line 347 "src/wasm-flex-lexer.l"
+#line 371 "src/wasm-flex-lexer.l"
{ return TOK(PARAM); }
YY_BREAK
case 195:
YY_RULE_SETUP
-#line 348 "src/wasm-flex-lexer.l"
+#line 372 "src/wasm-flex-lexer.l"
{ return TOK(RESULT); }
YY_BREAK
case 196:
YY_RULE_SETUP
-#line 349 "src/wasm-flex-lexer.l"
+#line 373 "src/wasm-flex-lexer.l"
{ return TOK(LOCAL); }
YY_BREAK
case 197:
YY_RULE_SETUP
-#line 350 "src/wasm-flex-lexer.l"
+#line 374 "src/wasm-flex-lexer.l"
{ return TOK(MODULE); }
YY_BREAK
case 198:
YY_RULE_SETUP
-#line 351 "src/wasm-flex-lexer.l"
+#line 375 "src/wasm-flex-lexer.l"
{ return TOK(MEMORY); }
YY_BREAK
case 199:
YY_RULE_SETUP
-#line 352 "src/wasm-flex-lexer.l"
+#line 376 "src/wasm-flex-lexer.l"
{ return TOK(SEGMENT); }
YY_BREAK
case 200:
YY_RULE_SETUP
-#line 353 "src/wasm-flex-lexer.l"
+#line 377 "src/wasm-flex-lexer.l"
{ return TOK(START); }
YY_BREAK
case 201:
YY_RULE_SETUP
-#line 354 "src/wasm-flex-lexer.l"
+#line 378 "src/wasm-flex-lexer.l"
{ return TOK(IMPORT); }
YY_BREAK
case 202:
YY_RULE_SETUP
-#line 355 "src/wasm-flex-lexer.l"
+#line 379 "src/wasm-flex-lexer.l"
{ return TOK(EXPORT); }
YY_BREAK
case 203:
YY_RULE_SETUP
-#line 356 "src/wasm-flex-lexer.l"
+#line 380 "src/wasm-flex-lexer.l"
{ return TOK(TABLE); }
YY_BREAK
case 204:
YY_RULE_SETUP
-#line 357 "src/wasm-flex-lexer.l"
+#line 381 "src/wasm-flex-lexer.l"
{ return TOK(ASSERT_INVALID); }
YY_BREAK
case 205:
YY_RULE_SETUP
-#line 358 "src/wasm-flex-lexer.l"
+#line 382 "src/wasm-flex-lexer.l"
{ return TOK(ASSERT_RETURN); }
YY_BREAK
case 206:
YY_RULE_SETUP
-#line 359 "src/wasm-flex-lexer.l"
+#line 383 "src/wasm-flex-lexer.l"
{ return TOK(ASSERT_RETURN_NAN); }
YY_BREAK
case 207:
YY_RULE_SETUP
-#line 360 "src/wasm-flex-lexer.l"
+#line 384 "src/wasm-flex-lexer.l"
{ return TOK(ASSERT_TRAP); }
YY_BREAK
case 208:
YY_RULE_SETUP
-#line 361 "src/wasm-flex-lexer.l"
+#line 385 "src/wasm-flex-lexer.l"
{ return TOK(INVOKE); }
YY_BREAK
case 209:
YY_RULE_SETUP
-#line 362 "src/wasm-flex-lexer.l"
+#line 386 "src/wasm-flex-lexer.l"
{ TEXT; return TOK(VAR); }
YY_BREAK
case 210:
YY_RULE_SETUP
-#line 364 "src/wasm-flex-lexer.l"
+#line 388 "src/wasm-flex-lexer.l"
{ BEGIN(LINE_COMMENT); }
YY_BREAK
case 211:
/* rule 211 can match eol */
YY_RULE_SETUP
-#line 365 "src/wasm-flex-lexer.l"
+#line 389 "src/wasm-flex-lexer.l"
{ RESET_COLUMN; BEGIN(INITIAL); }
YY_BREAK
case YY_STATE_EOF(LINE_COMMENT):
-#line 366 "src/wasm-flex-lexer.l"
+#line 390 "src/wasm-flex-lexer.l"
{ return TOK(EOF); }
YY_BREAK
case 212:
YY_RULE_SETUP
-#line 367 "src/wasm-flex-lexer.l"
+#line 391 "src/wasm-flex-lexer.l"
YY_BREAK
case 213:
YY_RULE_SETUP
-#line 368 "src/wasm-flex-lexer.l"
+#line 392 "src/wasm-flex-lexer.l"
{ BEGIN(BLOCK_COMMENT); COMMENT_NESTING = 1; }
YY_BREAK
case 214:
YY_RULE_SETUP
-#line 369 "src/wasm-flex-lexer.l"
+#line 393 "src/wasm-flex-lexer.l"
{ COMMENT_NESTING++; }
YY_BREAK
case 215:
YY_RULE_SETUP
-#line 370 "src/wasm-flex-lexer.l"
+#line 394 "src/wasm-flex-lexer.l"
{ if (--COMMENT_NESTING == 0) BEGIN(INITIAL); }
YY_BREAK
case 216:
/* rule 216 can match eol */
YY_RULE_SETUP
-#line 371 "src/wasm-flex-lexer.l"
+#line 395 "src/wasm-flex-lexer.l"
{ RESET_COLUMN; }
YY_BREAK
case YY_STATE_EOF(BLOCK_COMMENT):
-#line 372 "src/wasm-flex-lexer.l"
+#line 396 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"unexpected EOF");
return TOK(EOF); }
YY_BREAK
case 217:
YY_RULE_SETUP
-#line 375 "src/wasm-flex-lexer.l"
+#line 399 "src/wasm-flex-lexer.l"
YY_BREAK
case 218:
/* rule 218 can match eol */
YY_RULE_SETUP
-#line 376 "src/wasm-flex-lexer.l"
+#line 400 "src/wasm-flex-lexer.l"
{ RESET_COLUMN; }
YY_BREAK
case 219:
YY_RULE_SETUP
-#line 377 "src/wasm-flex-lexer.l"
+#line 401 "src/wasm-flex-lexer.l"
YY_BREAK
case YY_STATE_EOF(INITIAL):
-#line 378 "src/wasm-flex-lexer.l"
+#line 402 "src/wasm-flex-lexer.l"
{ return TOK(EOF); }
YY_BREAK
case 220:
YY_RULE_SETUP
-#line 379 "src/wasm-flex-lexer.l"
+#line 403 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"unexpected token \"%.*s\"", yyleng,
yytext); }
YY_BREAK
case 221:
YY_RULE_SETUP
-#line 382 "src/wasm-flex-lexer.l"
+#line 406 "src/wasm-flex-lexer.l"
{ wasm_parser_error(yylloc, yyscanner, parser,
"unexpected char"); }
YY_BREAK
case 222:
YY_RULE_SETUP
-#line 385 "src/wasm-flex-lexer.l"
+#line 409 "src/wasm-flex-lexer.l"
ECHO;
YY_BREAK
-#line 2762 "src/prebuilt/wasm-flex-lexer.c"
+#line 2786 "src/prebuilt/wasm-flex-lexer.c"
case YY_END_OF_BUFFER:
{
@@ -3922,7 +3946,7 @@ static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
-#line 384 "src/wasm-flex-lexer.l"
+#line 408 "src/wasm-flex-lexer.l"
@@ -3932,7 +3956,9 @@ int wasm_lexer_wrap(yyscan_t yyscanner) {
static WasmAllocator* s_lexer_allocator;
-WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
+static WasmLexer wasm_new_lexer(WasmAllocator* allocator,
+ WasmLexerType type,
+ const char* filename) {
WasmLexerExtra* extra =
wasm_alloc_zero(allocator, sizeof(WasmLexerExtra), WASM_DEFAULT_ALIGN);
if (!extra)
@@ -3940,16 +3966,10 @@ WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
extra->allocator = allocator;
extra->column = 1;
extra->filename = filename;
- extra->file = fopen(filename, "r");
-
- if (!extra->file) {
- wasm_free(allocator, extra);
- return NULL;
- }
+ extra->type = type;
if (WASM_FAILED(wasm_reserve_line_offsets(allocator, &extra->line_offsets,
WASM_INITIAL_LINE_OFFSETS))) {
- fclose(extra->file);
wasm_free(allocator, extra);
return NULL;
}
@@ -3964,15 +3984,56 @@ WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
s_lexer_allocator = allocator;
yyscan_t lexer;
wasm_lexer_lex_init(&lexer);
- wasm_lexer_set_in(extra->file,lexer);
wasm_lexer_set_extra(extra,lexer);
s_lexer_allocator = NULL;
return lexer;
}
+WasmLexer wasm_new_file_lexer(WasmAllocator* allocator, const char* filename) {
+ WasmLexer lexer = wasm_new_lexer(allocator, WASM_LEXER_TYPE_FILE, filename);
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ extra->file = fopen(filename, "r");
+ if (!extra->file) {
+ wasm_destroy_lexer(lexer);
+ wasm_free(allocator, extra);
+ return NULL;
+ }
+ wasm_lexer_set_in(extra->file,lexer);
+ return lexer;
+}
+
+WasmLexer wasm_new_buffer_lexer(WasmAllocator* allocator, const char* filename,
+ const void* data, size_t size) {
+ WasmLexer lexer = wasm_new_lexer(allocator, WASM_LEXER_TYPE_BUFFER, filename);
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ extra->buffer.data = data;
+ extra->buffer.size = size;
+ extra->buffer.read_offset = 0;
+ return lexer;
+}
+
+static void read_input(WasmLexer lexer, char* buffer, size_t* result,
+ size_t max_size) {
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_FILE) {
+ *result = fread(buffer, 1, max_size, extra->file);
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_BUFFER);
+ size_t read_size = max_size;
+ size_t offset = extra->buffer.read_offset;
+ size_t bytes_left = extra->buffer.size - offset;
+ if (read_size > bytes_left)
+ read_size = bytes_left;
+ memcpy(buffer, (char*)extra->buffer.data + offset, read_size);
+ extra->buffer.read_offset += read_size;
+ *result = read_size;
+ }
+}
+
void wasm_destroy_lexer(WasmLexer lexer) {
WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
- fclose(extra->file);
+ if (extra->type == WASM_LEXER_TYPE_FILE && extra->file)
+ fclose(extra->file);
wasm_destroy_line_offset_vector(extra->allocator, &extra->line_offsets);
wasm_lexer_lex_destroy((yyscan_t)lexer);
wasm_free(extra->allocator, extra);
@@ -3999,12 +4060,7 @@ WasmAllocator* wasm_lexer_get_allocator(WasmLexer lexer) {
return extra->allocator;
}
-FILE* wasm_lexer_get_file(WasmLexer lexer) {
- WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
- return extra->file;
-}
-
-size_t wasm_lexer_get_file_offset_from_line(WasmLexer lexer, int line) {
+static size_t lexer_get_offset_from_line(WasmLexer lexer, int line) {
WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
if (line < 0 || (size_t)line >= extra->line_offsets.size)
return WASM_INVALID_LINE_OFFSET;
@@ -4012,3 +4068,151 @@ size_t wasm_lexer_get_file_offset_from_line(WasmLexer lexer, int line) {
return extra->line_offsets.data[line];
}
+static WasmResult lexer_get_offsets_from_line(WasmLexer lexer,
+ int line,
+ size_t* out_line_start,
+ size_t* out_line_end) {
+ size_t line_start = lexer_get_offset_from_line(lexer, line);
+ size_t line_end = lexer_get_offset_from_line(lexer, line + 1);
+ if (line_end == WASM_INVALID_LINE_OFFSET) {
+ /* we haven't gotten to the next line yet. scan ahead to find it. */
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_BUFFER) {
+ const char* buffer_start = extra->buffer.data;
+ const char* buffer_line_start = buffer_start + line_start;
+ const char* buffer_end = buffer_start + extra->buffer.size;
+
+ const char* newline =
+ memchr(buffer_line_start, '\n', buffer_end - buffer_line_start);
+ line_end = (newline ? newline : buffer_end) - buffer_start;
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_FILE);
+ FILE* lexer_file = extra->file;
+ long old_offset = ftell(lexer_file);
+ if (old_offset == -1)
+ return WASM_ERROR;
+
+ /* we haven't gotten to the next line yet. read the file to find it. */
+ size_t offset = line_start;
+ line_end = offset;
+ if (fseek(lexer_file, offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+
+ char buffer[256];
+ while (1) {
+ size_t bytes_read = fread(buffer, 1, sizeof(buffer), lexer_file);
+ if (bytes_read == 0)
+ break;
+
+ char* newline = memchr(buffer, '\n', bytes_read);
+ if (newline) {
+ line_end += (newline - buffer);
+ break;
+ } else {
+ line_end += bytes_read;
+ }
+ }
+ if (fseek(lexer_file, old_offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+ }
+ } else {
+ /* don't include the newline */
+ line_end--;
+ }
+
+ *out_line_start = line_start;
+ *out_line_end = line_end;
+ return WASM_OK;
+}
+
+static void clamp_source_line_offsets_to_location(size_t line_start,
+ size_t line_end,
+ int first_column,
+ int last_column,
+ size_t max_line_length,
+ size_t* out_new_line_start,
+ size_t* out_new_line_end) {
+ size_t line_length = line_end - line_start;
+ if (line_length > max_line_length) {
+ size_t column_range = last_column - first_column;
+ size_t center_on;
+ if (column_range > max_line_length) {
+ /* the column range doesn't fit, just center on first_column */
+ center_on = first_column - 1;
+ } else {
+ /* the entire range fits, display it all in the center */
+ center_on = (first_column + last_column) / 2 - 1;
+ }
+ if (center_on > max_line_length / 2)
+ line_start += center_on - max_line_length / 2;
+ if (line_start > line_end - max_line_length)
+ line_start = line_end - max_line_length;
+ line_end = line_start + max_line_length;
+ }
+
+ *out_new_line_start = line_start;
+ *out_new_line_end = line_end;
+}
+
+WasmResult wasm_lexer_get_source_line(WasmLexer lexer,
+ const WasmLocation* loc,
+ size_t line_max_length,
+ char* line,
+ size_t* out_line_length,
+ int* out_column_offset) {
+ WasmResult result;
+ size_t line_start;
+ size_t line_end;
+ result =
+ lexer_get_offsets_from_line(lexer, loc->line, &line_start, &line_end);
+ if (WASM_FAILED(result))
+ return result;
+
+ size_t new_line_start;
+ size_t new_line_end;
+ clamp_source_line_offsets_to_location(
+ line_start, line_end, loc->first_column, loc->last_column,
+ line_max_length, &new_line_start, &new_line_end);
+ WasmBool has_start_ellipsis = line_start != new_line_start;
+ WasmBool has_end_ellipsis = line_end != new_line_end;
+
+ char* write_start = line;
+ size_t line_length = new_line_end - new_line_start;
+ size_t read_start = new_line_start;
+ size_t read_length = line_length;
+ if (has_start_ellipsis) {
+ memcpy(line, "...", 3);
+ read_start += 3;
+ write_start += 3;
+ read_length -= 3;
+ }
+ if (has_end_ellipsis) {
+ memcpy(line + line_length - 3, "...", 3);
+ read_length -= 3;
+ }
+
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_BUFFER) {
+ char* buffer_read_start = (char*)extra->buffer.data + read_start;
+ memcpy(write_start, buffer_read_start, read_length);
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_FILE);
+ FILE* lexer_file = extra->file;
+ long old_offset = ftell(lexer_file);
+ if (old_offset == -1)
+ return WASM_ERROR;
+ if (fseek(lexer_file, read_start, SEEK_SET) == -1)
+ return WASM_ERROR;
+ if (fread(write_start, 1, read_length, lexer_file) < read_length)
+ return WASM_ERROR;
+ if (fseek(lexer_file, old_offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+ }
+
+ line[line_length] = '\0';
+
+ *out_line_length = line_length;
+ *out_column_offset = new_line_start - line_start;
+ return WASM_OK;
+}
+
diff --git a/src/sexpr-wasm.c b/src/sexpr-wasm.c
index 2895f3a9..4e2147ff 100644
--- a/src/sexpr-wasm.c
+++ b/src/sexpr-wasm.c
@@ -402,7 +402,7 @@ int main(int argc, char** argv) {
allocator = &stack_allocator.allocator;
}
- WasmLexer lexer = wasm_new_lexer(allocator, s_infile);
+ WasmLexer lexer = wasm_new_file_lexer(allocator, s_infile);
if (!lexer)
WASM_FATAL("unable to read %s\n", s_infile);
diff --git a/src/wasm-flex-lexer.l b/src/wasm-flex-lexer.l
index bd9ddf4a..4d911545 100644
--- a/src/wasm-flex-lexer.l
+++ b/src/wasm-flex-lexer.l
@@ -49,9 +49,22 @@
typedef size_t WasmLineOffset;
WASM_DEFINE_VECTOR(line_offset, WasmLineOffset);
+typedef enum WasmLexerType {
+ WASM_LEXER_TYPE_FILE,
+ WASM_LEXER_TYPE_BUFFER,
+} WasmLexerType;
+
typedef struct WasmLexerExtra {
WasmAllocator* allocator;
- FILE* file;
+ WasmLexerType type;
+ union {
+ FILE* file;
+ struct {
+ const void* data;
+ size_t size;
+ size_t read_offset;
+ } buffer;
+ };
const char* filename;
size_t offset;
WasmLineOffsetVector line_offsets;
@@ -59,11 +72,22 @@ typedef struct WasmLexerExtra {
int comment_nesting;
} WasmLexerExtra;
+static void read_input(WasmLexer, char* buffer, size_t* result,
+ size_t max_size);
+
#define YY_DECL \
int wasm_lexer_lex(WASM_PARSER_STYPE* yylval_param, \
WASM_PARSER_LTYPE* yylloc_param, yyscan_t yyscanner, \
WasmParser* parser)
+#undef YY_INPUT
+#define YY_INPUT(buf, result, max_size) \
+ do { \
+ size_t my_result = 0; \
+ read_input(yyscanner, buf, &my_result, max_size); \
+ result = my_result; \
+ } while (0)
+
#define COMMENT_NESTING (yyextra->comment_nesting)
#define RESET_COLUMN \
do { \
@@ -390,7 +414,9 @@ int wasm_lexer_wrap(yyscan_t yyscanner) {
static WasmAllocator* s_lexer_allocator;
-WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
+static WasmLexer wasm_new_lexer(WasmAllocator* allocator,
+ WasmLexerType type,
+ const char* filename) {
WasmLexerExtra* extra =
wasm_alloc_zero(allocator, sizeof(WasmLexerExtra), WASM_DEFAULT_ALIGN);
if (!extra)
@@ -398,16 +424,10 @@ WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
extra->allocator = allocator;
extra->column = 1;
extra->filename = filename;
- extra->file = fopen(filename, "r");
-
- if (!extra->file) {
- wasm_free(allocator, extra);
- return NULL;
- }
+ extra->type = type;
if (WASM_FAILED(wasm_reserve_line_offsets(allocator, &extra->line_offsets,
WASM_INITIAL_LINE_OFFSETS))) {
- fclose(extra->file);
wasm_free(allocator, extra);
return NULL;
}
@@ -422,15 +442,56 @@ WasmLexer wasm_new_lexer(WasmAllocator* allocator, const char* filename) {
s_lexer_allocator = allocator;
yyscan_t lexer;
yylex_init(&lexer);
- yyset_in(extra->file, lexer);
yyset_extra(extra, lexer);
s_lexer_allocator = NULL;
return lexer;
}
+WasmLexer wasm_new_file_lexer(WasmAllocator* allocator, const char* filename) {
+ WasmLexer lexer = wasm_new_lexer(allocator, WASM_LEXER_TYPE_FILE, filename);
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ extra->file = fopen(filename, "r");
+ if (!extra->file) {
+ wasm_destroy_lexer(lexer);
+ wasm_free(allocator, extra);
+ return NULL;
+ }
+ yyset_in(extra->file, lexer);
+ return lexer;
+}
+
+WasmLexer wasm_new_buffer_lexer(WasmAllocator* allocator, const char* filename,
+ const void* data, size_t size) {
+ WasmLexer lexer = wasm_new_lexer(allocator, WASM_LEXER_TYPE_BUFFER, filename);
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ extra->buffer.data = data;
+ extra->buffer.size = size;
+ extra->buffer.read_offset = 0;
+ return lexer;
+}
+
+static void read_input(WasmLexer lexer, char* buffer, size_t* result,
+ size_t max_size) {
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_FILE) {
+ *result = fread(buffer, 1, max_size, extra->file);
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_BUFFER);
+ size_t read_size = max_size;
+ size_t offset = extra->buffer.read_offset;
+ size_t bytes_left = extra->buffer.size - offset;
+ if (read_size > bytes_left)
+ read_size = bytes_left;
+ memcpy(buffer, (char*)extra->buffer.data + offset, read_size);
+ extra->buffer.read_offset += read_size;
+ *result = read_size;
+ }
+}
+
void wasm_destroy_lexer(WasmLexer lexer) {
WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
- fclose(extra->file);
+ if (extra->type == WASM_LEXER_TYPE_FILE && extra->file)
+ fclose(extra->file);
wasm_destroy_line_offset_vector(extra->allocator, &extra->line_offsets);
wasm_lexer_lex_destroy((yyscan_t)lexer);
wasm_free(extra->allocator, extra);
@@ -457,15 +518,158 @@ WasmAllocator* wasm_lexer_get_allocator(WasmLexer lexer) {
return extra->allocator;
}
-FILE* wasm_lexer_get_file(WasmLexer lexer) {
- WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
- return extra->file;
-}
-
-size_t wasm_lexer_get_file_offset_from_line(WasmLexer lexer, int line) {
+static size_t lexer_get_offset_from_line(WasmLexer lexer, int line) {
WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
if (line < 0 || (size_t)line >= extra->line_offsets.size)
return WASM_INVALID_LINE_OFFSET;
return extra->line_offsets.data[line];
}
+
+static WasmResult lexer_get_offsets_from_line(WasmLexer lexer,
+ int line,
+ size_t* out_line_start,
+ size_t* out_line_end) {
+ size_t line_start = lexer_get_offset_from_line(lexer, line);
+ size_t line_end = lexer_get_offset_from_line(lexer, line + 1);
+ if (line_end == WASM_INVALID_LINE_OFFSET) {
+ /* we haven't gotten to the next line yet. scan ahead to find it. */
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_BUFFER) {
+ const char* buffer_start = extra->buffer.data;
+ const char* buffer_line_start = buffer_start + line_start;
+ const char* buffer_end = buffer_start + extra->buffer.size;
+
+ const char* newline =
+ memchr(buffer_line_start, '\n', buffer_end - buffer_line_start);
+ line_end = (newline ? newline : buffer_end) - buffer_start;
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_FILE);
+ FILE* lexer_file = extra->file;
+ long old_offset = ftell(lexer_file);
+ if (old_offset == -1)
+ return WASM_ERROR;
+
+ /* we haven't gotten to the next line yet. read the file to find it. */
+ size_t offset = line_start;
+ line_end = offset;
+ if (fseek(lexer_file, offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+
+ char buffer[256];
+ while (1) {
+ size_t bytes_read = fread(buffer, 1, sizeof(buffer), lexer_file);
+ if (bytes_read == 0)
+ break;
+
+ char* newline = memchr(buffer, '\n', bytes_read);
+ if (newline) {
+ line_end += (newline - buffer);
+ break;
+ } else {
+ line_end += bytes_read;
+ }
+ }
+ if (fseek(lexer_file, old_offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+ }
+ } else {
+ /* don't include the newline */
+ line_end--;
+ }
+
+ *out_line_start = line_start;
+ *out_line_end = line_end;
+ return WASM_OK;
+}
+
+static void clamp_source_line_offsets_to_location(size_t line_start,
+ size_t line_end,
+ int first_column,
+ int last_column,
+ size_t max_line_length,
+ size_t* out_new_line_start,
+ size_t* out_new_line_end) {
+ size_t line_length = line_end - line_start;
+ if (line_length > max_line_length) {
+ size_t column_range = last_column - first_column;
+ size_t center_on;
+ if (column_range > max_line_length) {
+ /* the column range doesn't fit, just center on first_column */
+ center_on = first_column - 1;
+ } else {
+ /* the entire range fits, display it all in the center */
+ center_on = (first_column + last_column) / 2 - 1;
+ }
+ if (center_on > max_line_length / 2)
+ line_start += center_on - max_line_length / 2;
+ if (line_start > line_end - max_line_length)
+ line_start = line_end - max_line_length;
+ line_end = line_start + max_line_length;
+ }
+
+ *out_new_line_start = line_start;
+ *out_new_line_end = line_end;
+}
+
+WasmResult wasm_lexer_get_source_line(WasmLexer lexer,
+ const WasmLocation* loc,
+ size_t line_max_length,
+ char* line,
+ size_t* out_line_length,
+ int* out_column_offset) {
+ WasmResult result;
+ size_t line_start;
+ size_t line_end;
+ result =
+ lexer_get_offsets_from_line(lexer, loc->line, &line_start, &line_end);
+ if (WASM_FAILED(result))
+ return result;
+
+ size_t new_line_start;
+ size_t new_line_end;
+ clamp_source_line_offsets_to_location(
+ line_start, line_end, loc->first_column, loc->last_column,
+ line_max_length, &new_line_start, &new_line_end);
+ WasmBool has_start_ellipsis = line_start != new_line_start;
+ WasmBool has_end_ellipsis = line_end != new_line_end;
+
+ char* write_start = line;
+ size_t line_length = new_line_end - new_line_start;
+ size_t read_start = new_line_start;
+ size_t read_length = line_length;
+ if (has_start_ellipsis) {
+ memcpy(line, "...", 3);
+ read_start += 3;
+ write_start += 3;
+ read_length -= 3;
+ }
+ if (has_end_ellipsis) {
+ memcpy(line + line_length - 3, "...", 3);
+ read_length -= 3;
+ }
+
+ WasmLexerExtra* extra = wasm_lexer_get_extra(lexer);
+ if (extra->type == WASM_LEXER_TYPE_BUFFER) {
+ char* buffer_read_start = (char*)extra->buffer.data + read_start;
+ memcpy(write_start, buffer_read_start, read_length);
+ } else {
+ assert(extra->type == WASM_LEXER_TYPE_FILE);
+ FILE* lexer_file = extra->file;
+ long old_offset = ftell(lexer_file);
+ if (old_offset == -1)
+ return WASM_ERROR;
+ if (fseek(lexer_file, read_start, SEEK_SET) == -1)
+ return WASM_ERROR;
+ if (fread(write_start, 1, read_length, lexer_file) < read_length)
+ return WASM_ERROR;
+ if (fseek(lexer_file, old_offset, SEEK_SET) == -1)
+ return WASM_ERROR;
+ }
+
+ line[line_length] = '\0';
+
+ *out_line_length = line_length;
+ *out_column_offset = new_line_start - line_start;
+ return WASM_OK;
+}
diff --git a/src/wasm-lexer.h b/src/wasm-lexer.h
index 0fde9c2f..acec82f8 100644
--- a/src/wasm-lexer.h
+++ b/src/wasm-lexer.h
@@ -25,7 +25,12 @@ struct WasmAllocator;
typedef void* WasmLexer;
WASM_EXTERN_C_BEGIN
-WasmLexer wasm_new_lexer(struct WasmAllocator*, const char* filename);
+
+WasmLexer wasm_new_file_lexer(struct WasmAllocator*, const char* filename);
+WasmLexer wasm_new_buffer_lexer(struct WasmAllocator*,
+ const char* filename,
+ const void* data,
+ size_t size);
void wasm_destroy_lexer(WasmLexer);
WASM_EXTERN_C_END
diff --git a/src/wasm-parser-lexer-shared.c b/src/wasm-parser-lexer-shared.c
index 7cc10057..599f7c2b 100644
--- a/src/wasm-parser-lexer-shared.c
+++ b/src/wasm-parser-lexer-shared.c
@@ -49,107 +49,24 @@ void wasm_format_error(WasmSourceErrorHandler* error_handler,
char* source_line = NULL;
size_t source_line_length = 0;
- size_t source_line_column_offset = 0;
+ int source_line_column_offset = 0;
size_t source_line_max_length = error_handler->source_line_max_length;
if (loc) {
source_line = alloca(source_line_max_length + 1);
-
- size_t line_offset = wasm_lexer_get_file_offset_from_line(lexer, loc->line);
- FILE* lexer_file = wasm_lexer_get_file(lexer);
- long old_offset = ftell(lexer_file);
- if (old_offset != -1) {
- size_t next_line_offset =
- wasm_lexer_get_file_offset_from_line(lexer, loc->line + 1);
- if (next_line_offset == WASM_INVALID_LINE_OFFSET) {
- /* we haven't gotten to the next line yet. read the file to find it. - 1
- because columns are 1-based */
- size_t offset = line_offset + (loc->last_column - 1);
- next_line_offset = offset;
- if (fseek(lexer_file, offset, SEEK_SET) != -1) {
- char buffer[256];
- while (1) {
- size_t bytes_read = fread(buffer, 1, sizeof(buffer), lexer_file);
- if (bytes_read <= 0)
- break;
-
- char* newline = memchr(buffer, '\n', bytes_read);
- if (newline) {
- next_line_offset += (newline - buffer);
- break;
- } else {
- next_line_offset += bytes_read;
- }
- }
- }
- } else {
- /* don't include the newline */
- next_line_offset--;
- }
-
- source_line_length = next_line_offset - line_offset;
- size_t column_range = loc->last_column - loc->first_column;
- size_t start_offset = line_offset;
- if (source_line_length > source_line_max_length) {
- source_line_length = source_line_max_length;
- size_t center_on;
- if (column_range > source_line_max_length) {
- /* the column range doesn't fit, just center on first_column */
- center_on = loc->first_column - 1;
- } else {
- /* the entire range fits, display it all in the center */
- center_on = (loc->first_column + loc->last_column) / 2 - 1;
- }
- if (center_on > source_line_max_length / 2)
- start_offset = line_offset + center_on - source_line_max_length / 2;
- if (start_offset > next_line_offset - source_line_max_length)
- start_offset = next_line_offset - source_line_max_length;
- }
-
- source_line_column_offset = start_offset - line_offset;
-
- char* p = source_line;
- size_t read_start = start_offset;
- size_t read_length = source_line_length;
- WasmBool has_start_ellipsis = start_offset != line_offset;
- WasmBool has_end_ellipsis =
- start_offset + source_line_length != next_line_offset;
-
- if (has_start_ellipsis) {
- memcpy(p, "...", 3);
- p += 3;
- read_start += 3;
- read_length -= 3;
- }
-
- if (has_end_ellipsis) {
- read_length -= 3;
- }
-
- if (fseek(lexer_file, read_start, SEEK_SET) != -1) {
- size_t bytes_read = fread(p, 1, read_length, lexer_file);
- if (bytes_read > 0)
- p += bytes_read;
- }
-
- if (has_end_ellipsis) {
- memcpy(p, "...", 3);
- p += 3;
- }
-
- source_line_length = p - source_line;
-
- *p = '\0';
-
- if (fseek(lexer_file, old_offset, SEEK_SET) == -1) {
- /* we're screwed now, blow up. */
- WASM_FATAL("failed to seek.");
- }
+ WasmResult result = wasm_lexer_get_source_line(
+ lexer, loc, source_line_max_length, source_line,
+ &source_line_length, &source_line_column_offset);
+ if (WASM_FAILED(result)) {
+ /* if this fails, it means that we've probably screwed up the lexer. blow
+ * up. */
+ WASM_FATAL("error getting the source line.");
}
}
if (error_handler->on_error) {
error_handler->on_error(loc, buffer, source_line, source_line_length,
- source_line_column_offset, error_handler->user_data);
+ source_line_column_offset,
+ error_handler->user_data);
}
va_end(args_copy);
}
diff --git a/src/wasm-parser-lexer-shared.h b/src/wasm-parser-lexer-shared.h
index 3acd1222..00d586b2 100644
--- a/src/wasm-parser-lexer-shared.h
+++ b/src/wasm-parser-lexer-shared.h
@@ -18,7 +18,6 @@
#define WASM_PARSER_LEXER_SHARED_H_
#include <stdarg.h>
-#include <stdio.h>
#include "wasm-ast.h"
#include "wasm-common.h"
@@ -77,12 +76,16 @@ typedef struct WasmParser {
WASM_EXTERN_C_BEGIN
struct WasmAllocator* wasm_lexer_get_allocator(WasmLexer lexer);
-FILE* wasm_lexer_get_file(WasmLexer);
-size_t wasm_lexer_get_file_offset_from_line(WasmLexer, int line);
int wasm_lexer_lex(union WasmToken*,
struct WasmLocation*,
WasmLexer,
struct WasmParser*);
+WasmResult wasm_lexer_get_source_line(WasmLexer,
+ const struct WasmLocation*,
+ size_t line_max_length,
+ char* line,
+ size_t* out_line_length,
+ int* out_column_offset);
void wasm_parser_error(struct WasmLocation*,
WasmLexer,
struct WasmParser*,