boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

350-large-aggregate-flow.c (2986B)


      1 /* Exercise the large-aggregate path Kit's ApiSValue stack uses: construct a
      2  * 64-byte value, pass it by value into a stack push, return it indirectly from
      3  * a pop, and initialize another local from that return value. */
      4 struct Value {
      5     unsigned long a;
      6     unsigned long b;
      7     unsigned long c;
      8     unsigned long d;
      9     unsigned long e;
     10     unsigned long f;
     11     unsigned long g;
     12     unsigned long h;
     13 };
     14 
     15 struct Stack {
     16     struct Value values[2];
     17     unsigned n;
     18 };
     19 
     20 struct Operand {
     21     unsigned long x;
     22     unsigned long y;
     23     unsigned long z;
     24 };
     25 
     26 struct Wrapped {
     27     struct Operand operand;
     28     unsigned long d;
     29     unsigned long e;
     30     unsigned long f;
     31     unsigned long g;
     32     unsigned long h;
     33 };
     34 
     35 static struct Operand make_operand(unsigned long base)
     36 {
     37     struct Operand operand;
     38     operand.x = base;
     39     operand.y = base + 1;
     40     operand.z = base + 2;
     41     return operand;
     42 }
     43 
     44 static struct Wrapped wrap_operand(struct Operand operand,
     45                                    unsigned long tail)
     46 {
     47     return (struct Wrapped){
     48         .operand = operand,
     49         .d = tail,
     50         .e = tail + 1,
     51         .f = tail + 2,
     52         .g = tail + 3,
     53         .h = tail + 4,
     54     };
     55 }
     56 
     57 static struct Value make_value(unsigned long base)
     58 {
     59     struct Value value;
     60     value.a = base + 0;
     61     value.b = base + 1;
     62     value.c = base + 2;
     63     value.d = base + 3;
     64     value.e = base + 4;
     65     value.f = base + 5;
     66     value.g = base + 6;
     67     value.h = base + 7;
     68     return value;
     69 }
     70 
     71 static struct Value make_value_from_operand(struct Operand operand,
     72                                             unsigned long tail)
     73 {
     74     struct Value value;
     75     value.a = operand.x;
     76     value.b = operand.y;
     77     value.c = operand.z;
     78     value.d = tail;
     79     value.e = tail + 1;
     80     value.f = tail + 2;
     81     value.g = tail + 3;
     82     value.h = tail + 4;
     83     return value;
     84 }
     85 
     86 static void push(struct Stack *stack, struct Value value)
     87 {
     88     stack->values[stack->n++] = value;
     89 }
     90 
     91 static struct Value pop(struct Stack *stack)
     92 {
     93     return stack->values[--stack->n];
     94 }
     95 
     96 int main(void)
     97 {
     98     struct Stack stack = {0};
     99     struct Value value;
    100     struct Wrapped wrapped = wrap_operand(make_operand(80), 83);
    101     if (wrapped.operand.x != 80) return 11;
    102     if (wrapped.operand.y != 81) return 12;
    103     if (wrapped.operand.z != 82) return 13;
    104     if (wrapped.d != 83 || wrapped.h != 87) return 14;
    105     push(&stack, make_value(32));
    106     push(&stack, make_value_from_operand(make_operand(64), 67));
    107     {
    108         struct Value tmp = stack.values[0];
    109         stack.values[0] = stack.values[1];
    110         stack.values[1] = tmp;
    111     }
    112     value = pop(&stack);
    113     if (value.a != 32) return 1;
    114     if (value.b != 33) return 2;
    115     if (value.c != 34) return 3;
    116     if (value.d != 35) return 4;
    117     if (value.e != 36) return 5;
    118     if (value.f != 37) return 6;
    119     if (value.g != 38) return 7;
    120     if (value.h != 39) return 8;
    121     value = pop(&stack);
    122     if (value.a != 64) return 9;
    123     if (value.h != 71) return 10;
    124     return 0;
    125 }