bytecode: allow interpreter to return any type
[lttng-ust.git] / liblttng-ust / lttng-filter-validator.c
index c1fed3ed3290ad79342f0567f74264cc40f8f548..e6982369bdc1d8c8e90c4c9d8ff29c6f9b20c16a 100644 (file)
@@ -160,6 +160,7 @@ int bin_op_compare_check(struct vstack *stack, filter_opcode_t opcode,
                        }
                        break;
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                        goto error_mismatch;
                }
@@ -178,11 +179,13 @@ int bin_op_compare_check(struct vstack *stack, filter_opcode_t opcode,
                        break;
                case REG_STAR_GLOB_STRING:
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                        goto error_mismatch;
                }
                break;
        case REG_S64:
+       case REG_U64:
        case REG_DOUBLE:
                switch (vstack_bx(stack)->type) {
                default:
@@ -194,6 +197,7 @@ int bin_op_compare_check(struct vstack *stack, filter_opcode_t opcode,
                case REG_STAR_GLOB_STRING:
                        goto error_mismatch;
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                        break;
                }
@@ -236,6 +240,7 @@ int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode,
        case REG_UNKNOWN:
                goto unknown;
        case REG_S64:
+       case REG_U64:
                switch (vstack_bx(stack)->type) {
                default:
                        goto error_type;
@@ -243,6 +248,7 @@ int bin_op_bitwise_check(struct vstack *stack, filter_opcode_t opcode,
                case REG_UNKNOWN:
                        goto unknown;
                case REG_S64:
+               case REG_U64:
                        break;
                }
                break;
@@ -695,8 +701,20 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64
-                               || vstack_bx(stack)->type != REG_S64) {
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
+                       ERR("Unexpected register type for s64 comparator\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_bx(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
                        ERR("Unexpected register type for s64 comparator\n");
                        ret = -EINVAL;
                        goto end;
@@ -736,7 +754,19 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64 && vstack_bx(stack)->type != REG_DOUBLE) {
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
+                       ERR("Double-S64 operator has unexpected register types\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_bx(stack)->type) {
+               case REG_DOUBLE:
+                       break;
+               default:
                        ERR("Double-S64 operator has unexpected register types\n");
                        ret = -EINVAL;
                        goto end;
@@ -756,7 +786,19 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_DOUBLE && vstack_bx(stack)->type != REG_S64) {
+               switch (vstack_ax(stack)->type) {
+               case REG_DOUBLE:
+                       break;
+               default:
+                       ERR("S64-Double operator has unexpected register types\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_bx(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+                       break;
+               default:
                        ERR("S64-Double operator has unexpected register types\n");
                        ret = -EINVAL;
                        goto end;
@@ -813,6 +855,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        goto end;
                case REG_S64:
                        break;
+               case REG_U64:
+                       break;
                case REG_DOUBLE:
                        break;
                case REG_UNKNOWN:
@@ -841,6 +885,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        goto end;
                case REG_S64:
                        break;
+               case REG_U64:
+                       break;
                case REG_UNKNOWN:
                        break;
                }
@@ -856,7 +902,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               if (vstack_ax(stack)->type != REG_S64) {
+               if (vstack_ax(stack)->type != REG_S64 &&
+                               vstack_ax(stack)->type != REG_U64) {
                        ERR("Invalid register type\n");
                        ret = -EINVAL;
                        goto end;
@@ -893,8 +940,9 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        goto end;
                }
                if (vstack_ax(stack)->type != REG_S64
+                               && vstack_ax(stack)->type != REG_U64
                                && vstack_ax(stack)->type != REG_UNKNOWN) {
-                       ERR("Logical comparator expects S64 or dynamic register\n");
+                       ERR("Logical comparator expects S64, U64 or dynamic register\n");
                        ret = -EINVAL;
                        goto end;
                }
@@ -985,6 +1033,8 @@ int validate_instruction_context(struct bytecode_runtime *bytecode,
                        goto end;
                case REG_S64:
                        break;
+               case REG_U64:
+                       break;
                case REG_DOUBLE:
                        break;
                case REG_UNKNOWN:
@@ -1250,6 +1300,10 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
+               case REG_DOUBLE:
+               case REG_STRING:
+               case REG_PTR:
                case REG_UNKNOWN:
                        break;
                default:
@@ -1271,6 +1325,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                case REG_UNKNOWN:
@@ -1335,6 +1390,37 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LT_S64_DOUBLE:
        case FILTER_OP_GE_S64_DOUBLE:
        case FILTER_OP_LE_S64_DOUBLE:
+       {
+               /* Pop 2, push 1 */
+               if (vstack_pop(stack)) {
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (!vstack_ax(stack)) {
+                       ERR("Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               switch (vstack_ax(stack)->type) {
+               case REG_S64:
+               case REG_U64:
+               case REG_DOUBLE:
+               case REG_STRING:
+               case REG_STAR_GLOB_STRING:
+               case REG_UNKNOWN:
+                       break;
+               default:
+                       ERR("Unexpected register type %d for operation\n",
+                               (int) vstack_ax(stack)->type);
+                       ret = -EINVAL;
+                       goto end;
+               }
+
+               vstack_ax(stack)->type = REG_S64;
+               next_pc += sizeof(struct binary_op);
+               break;
+       }
+
        case FILTER_OP_BIT_RSHIFT:
        case FILTER_OP_BIT_LSHIFT:
        case FILTER_OP_BIT_AND:
@@ -1353,6 +1439,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                case REG_STRING:
                case REG_STAR_GLOB_STRING:
@@ -1365,7 +1452,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct binary_op);
                break;
        }
@@ -1384,6 +1471,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                case REG_UNKNOWN:
                case REG_DOUBLE:
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        ERR("Unexpected register type %d for operation\n",
@@ -1408,6 +1496,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        ERR("Unexpected register type %d for operation\n",
@@ -1416,7 +1505,6 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1433,6 +1521,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                case REG_UNKNOWN:
                case REG_DOUBLE:
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        ERR("Unexpected register type %d for operation\n",
@@ -1441,7 +1530,6 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1457,6 +1545,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                switch (vstack_ax(stack)->type) {
                case REG_UNKNOWN:
                case REG_S64:
+               case REG_U64:
                        break;
                case REG_DOUBLE:
                default:
@@ -1466,7 +1555,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        goto end;
                }
 
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct unary_op);
                break;
        }
@@ -1541,6 +1630,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                /* There is always a cast-to-s64 operation before a or/and op. */
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                        break;
                default:
                        ERR("Incorrect register type %d for operation\n",
@@ -1674,6 +1764,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                }
                switch (vstack_ax(stack)->type) {
                case REG_S64:
+               case REG_U64:
                case REG_DOUBLE:
                case REG_UNKNOWN:
                        break;
@@ -1731,6 +1822,23 @@ int exec_insn(struct bytecode_runtime *bytecode,
        case FILTER_OP_LOAD_FIELD_S16:
        case FILTER_OP_LOAD_FIELD_S32:
        case FILTER_OP_LOAD_FIELD_S64:
+       {
+               /* Pop 1, push 1 */
+               if (!vstack_ax(stack)) {
+                       ERR("Empty stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               if (vstack_ax(stack)->type != REG_PTR) {
+                       ERR("Expecting pointer on top of stack\n");
+                       ret = -EINVAL;
+                       goto end;
+               }
+               vstack_ax(stack)->type = REG_S64;
+               next_pc += sizeof(struct load_op);
+               break;
+       }
+
        case FILTER_OP_LOAD_FIELD_U8:
        case FILTER_OP_LOAD_FIELD_U16:
        case FILTER_OP_LOAD_FIELD_U32:
@@ -1747,7 +1855,7 @@ int exec_insn(struct bytecode_runtime *bytecode,
                        ret = -EINVAL;
                        goto end;
                }
-               vstack_ax(stack)->type = REG_S64;
+               vstack_ax(stack)->type = REG_U64;
                next_pc += sizeof(struct load_op);
                break;
        }
This page took 0.031868 seconds and 4 git commands to generate.