Validate operand types

This commit is contained in:
Dmitry Stogov 2022-06-03 11:23:05 +03:00
parent 30e11861dd
commit c28fe2734d
3 changed files with 14 additions and 10 deletions

16
ir.g
View File

@ -161,12 +161,12 @@ ir_insn(ir_parser_ctx *p):
{if (count.i32 < 0 || count.i32 > 255) yy_error("bad bumber of operands");} {if (count.i32 < 0 || count.i32 > 255) yy_error("bad bumber of operands");}
{ref = ir_emit_N(p->ctx, IR_OPT(op, t), count.i32);} {ref = ir_emit_N(p->ctx, IR_OPT(op, t), count.i32);}
( "(" ( "("
( val(p, 1, &op1) ( val(p, op, 1, &op1)
{n = 1;} {n = 1;}
{if (n > count.i32) yy_error("too many operands");} {if (n > count.i32) yy_error("too many operands");}
{ir_set_op(p->ctx, ref, n, op1);} {ir_set_op(p->ctx, ref, n, op1);}
( "," ( ","
val(p, n, &op1) val(p, op, n, &op1)
{n++;} {n++;}
{if (n > count.i32) yy_error("too many operands");} {if (n > count.i32) yy_error("too many operands");}
{ir_set_op(p->ctx, ref, n, op1);} {ir_set_op(p->ctx, ref, n, op1);}
@ -176,11 +176,11 @@ ir_insn(ir_parser_ctx *p):
)? )?
| |
( "(" ( "("
( val(p, 1, &op1) ( val(p, op, 1, &op1)
( "," ( ","
val(p, 2, &op2) val(p, op, 2, &op2)
( "," ( ","
val(p, 3, &op3) val(p, op, 3, &op3)
)? )?
)? )?
)? )?
@ -222,15 +222,19 @@ func(uint8_t *op):
{*op = ref - 1;} {*op = ref - 1;}
; ;
val(ir_parser_ctx *p, uint32_t n, ir_ref *ref): val(ir_parser_ctx *p, uint8_t op, uint32_t n, ir_ref *ref):
{const char *str;} {const char *str;}
{size_t len;} {size_t len;}
{ir_val val;} {ir_val val;}
{uint32_t kind = IR_OPND_KIND(ir_op_flags[op], n);}
( ID(&str, &len) ( ID(&str, &len)
{if (kind < IR_OPND_DATA || kind > IR_OPND_VAR) yy_error("unexpected reference");}
{*ref = ir_use_var(p, n, str, len);} {*ref = ir_use_var(p, n, str, len);}
| STRING(&str, &len) | STRING(&str, &len)
{if (kind != IR_OPND_STR) yy_error("unexpected string");}
{*ref = ir_strl(p->ctx, str, len);} {*ref = ir_strl(p->ctx, str, len);}
| DECNUMBER(IR_I32, &val) | DECNUMBER(IR_I32, &val)
{if (kind != IR_OPND_NUM && kind != IR_OPND_PROB) yy_error("unexpected number");}
{if (val.u64 < 0 && val.u64 >= 0x7ffffff) yy_error("number out of range");} {if (val.u64 < 0 && val.u64 >= 0x7ffffff) yy_error("number out of range");}
{*ref = val.u64;} {*ref = val.u64;}
) )

View File

@ -555,9 +555,9 @@ extern const char *ir_op_name[IR_LAST_OP];
#define IR_OPND_CONTROL 0x2 #define IR_OPND_CONTROL 0x2
#define IR_OPND_CONTROL_DEP 0x3 #define IR_OPND_CONTROL_DEP 0x3
#define IR_OPND_CONTROL_REF 0x4 #define IR_OPND_CONTROL_REF 0x4
#define IR_OPND_STR 0x5 #define IR_OPND_VAR 0x5
#define IR_OPND_NUM 0x6 #define IR_OPND_STR 0x6
#define IR_OPND_VAR 0x7 #define IR_OPND_NUM 0x7
#define IR_OPND_PROB 0x8 #define IR_OPND_PROB 0x8
#define IR_OP_FLAGS(op_flags, op1_flags, op2_flags, op3_flags) \ #define IR_OP_FLAGS(op_flags, op1_flags, op2_flags, op3_flags) \

View File

@ -12,7 +12,7 @@ x86_64
int32_t v = VAR(l_1, "_spill_"); int32_t v = VAR(l_1, "_spill_");
l_2 = VSTORE(l_1, v, y); l_2 = VSTORE(l_1, v, y);
int32_t z, l_3 = VLOAD(l_2, v); int32_t z, l_3 = VLOAD(l_2, v);
int32_t y2 = ADD(y, 2); int32_t y2 = ADD(y, y);
int32_t ret = AND(y2, z); int32_t ret = AND(y2, z);
l_4 = VSTORE(l_3, v, ret); l_4 = VSTORE(l_3, v, ret);
l_5 = RETURN(l_4); l_5 = RETURN(l_4);