0

I am writing a compiler that compiles a language that has similar concepts to C to byte code which should then be interpreted by a corresponding stack-based VM. I am stuck at the moment when it comes how to compile structs, e.g.

struct my_struct_s {
   int    anInt;
   char*  aString;
} my_struct_t;

/* ... */
my_struct_t my_struct_var;

Where should I best put the my_struct_var in the byte code? How do C compilers handle such stuff? Later on, the VM also must handle the memory needed to represent this struct var, since it should be write- and reabable.

Where would you put this kind of variable? Onto the stack? Just put the memory address of this var onto the stack?

Thanks, Jonas

Seki
  • 11,135
  • 7
  • 46
  • 70
Jonas
  • 2,974
  • 4
  • 24
  • 23

2 Answers2

0

When compiling C to higher level languages, the hard part is handling pointers.

If you aren't concerned with that, things are much easier. I'd just compile the struct to a class with the given fields. This will work as long as you use the struct 'normally', i.e. getting and setting the fields explicitly. You don't need to worry about allocating memory or where the address is placed, the JVM handles all that automatically.

If you take a pointer to members of the field, things are much more problematic. The two approaches I can think of are representing memory as a giant byte array and manually interpreting the values at runtime (very slow) or replacing pointers with code to get or set the appropriate field (hopefully not too slow, especially since invokedynamic lets you do something similar).

Edit: I was assuming you're targeting the JVM above. CIL is nicer because it has explicit struct variables and support for unsafe memory access.

Antimony
  • 37,781
  • 10
  • 100
  • 107
0

I would regard a structure as being a collection of variables stuck together with duct tape. If struct foo has fields x and y, then declaring a variable, field, or parameter of type foo should essentially declare variables, fields, or parameters called foo___x and foo___y. The only place where things will become tricky is with arrays or byrefs. If one wishes to handle those, one will have to be able to create array elements of arbitrary size, access array elements and byrefs with displacements. Handling those will require the ability to have the elements of an array be arbitrary sizes, and will require the ability to apply a displacement when dereferencing an array element or byref. Further, if code takes a byref to a structure, one must ensure that its storage locations will always be arranged the same way; most likely that would meant that if some parameters are passed as registers, structures must always be passed entirely as registers or entirely on the stack. If a value parameter is passed in one or more registers to code that later passes it as a byref, that value must be copied onto the stack; that will be necessary whether the parameter is a struct or primitive.

supercat
  • 77,689
  • 9
  • 166
  • 211