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 }