rsmmr / hilti

**NOTE**: This is outdated and no longer maintained. There's a new version at https://github.com/zeek/spicy.
Other
40 stars 22 forks source link

&convert in a bitfield #12

Open FrozenCaribou opened 8 years ago

FrozenCaribou commented 8 years ago

Hello ! It seems that "&convert" in a bitfield is not well supported.

type Foo = enum{BAR1=0, BAR2=1};

export type test = unit{
    f1 : bitfield(8){
            b1 : 0..3 &convert(Foo($$));
            b2 : 4..7;
    }; 
    on f1{
        print self.f1.b1;
        if (self.f1.b1 == Foo::BAR1){
            print "f1.b1 BAR1";
        }
    }
};

Through an error because of the if between self.f1.b1 and Foo::BAR1

target: bool
op1 : Foo
op2: int<64>
op3 : (null)
internal error, llvmInstruction: 0 matches for mnemo equal [codegen]

I also noticed that $$ type is bitfield

However the print self.f1.b1 shows the good value. (Corresponds to the unit test https://github.com/rsmmr/hilti/blob/master/tests/binpac/enum/parse-bitfield-enum.pac2 )

Demaskatus commented 7 years ago

Hi, I also have faced the same problem, where I had defined a bitfield within i was using the operator &convert to translate a specific range of bits to a predefined enum. The spicy-code had the following abstract structur:


module Module_name;

export type Enum_name = enum {
      var_1 = 1,
      ...
      var_n = n
};

export type Unit_name = unit {
            Bitfield_name : bitfield (m) {
                  var_2_1 : 0..m-k &convert=Enum_name($$);
                  ...
                  var_2_k : m;
            };
};

the event-handler code had this form:

grammar Spicy_name.spicy

[...]

on Module_name::Unit_name -> event Event_name::events ($conn, self.Bitfield_name.var_2_1);

I faced many errors while trying this with bro, like for example:

return.result __tmp_bits

<no location>:: error, returned type does not match function

      Type given:        Module_name::Enum_name

      Type expected:  int<8> &hostapp_type(37) [pass::hilti::Validator]

I also tried to rewrite the code so that the types can be matched. I added in the spicy-code under Unit_name:

tuple <uint8>

return_var_2_1 (unit_name : Unit_name) {

      return (unit_name.var_2_1);
}

and changed the args from the events in evt-code to:

on Module_name::Unit_name -> event Event_name::events ($conn, Module_name::return_var_2_1);

and got this error:


internal error, coercion failed in CodeGen::hiltiCoerce(); cannot coerce HILTI expression of Spicy type uint<8> to type uint<8>  (__tmp_bits / <no location>:)

Aborted (core dumped)

With some help from Robin I could solve my problem with a work-around: I used a helper unit variable and assigned the value there first. Like this:

type Unit_name = unit {
     Bitfield_name : bitfield (m) {
         var_2_1 : 0..m-k;
         ...
         var_2_k : m;
      };

     on Bitfield_name {
         self.var_2_1_enum = Enum_name(self.Bitfield_name.var_2_1);
     }
     
     var var_2_1_enum: Enum_name;
};

Then used that helper variable instead of the bitfield attribute.