in benchmarks/JetStream2/wasm/TSF/tsf_gpc_code_gen.c [223:459]
static tsf_bool_t generate_generator(gpc_proto_t *proto,
tsf_type_t *type,
gpc_cell_t offset,
gpc_cell_t label) {
uint32_t i;
uint32_t bit = 0;
gpc_cell_t done_label, really_done_label;
switch (type->kind_code) {
case TSF_TK_VOID:
break;
case TSF_TK_INT8:
case TSF_TK_UINT8:
C(append(proto,
GPC_I_COPY_HTONC_INCDST,
offset));
break;
case TSF_TK_INT16:
case TSF_TK_UINT16:
C(append(proto,
GPC_I_COPY_HTONS_INCDST,
offset));
break;
case TSF_TK_INT32:
case TSF_TK_UINT32:
C(append(proto,
GPC_I_COPY_HTONL_INCDST,
offset));
break;
case TSF_TK_INT64:
case TSF_TK_UINT64:
C(append(proto,
GPC_I_COPY_HTONLL_INCDST,
offset));
break;
case TSF_TK_FLOAT:
C(append(proto,
GPC_I_COPY_HTONF_INCDST,
offset));
break;
case TSF_TK_DOUBLE:
C(append(proto,
GPC_I_COPY_HTOND_INCDST,
offset));
break;
case TSF_TK_BIT:
C(append(proto,
GPC_I_BIT_WRITE,
offset));
break;
case TSF_TK_INTEGER:
C(append(proto, GPC_I_TSF_INTEGER_WRITE, offset));
break;
case TSF_TK_LONG:
C(append(proto, GPC_I_TSF_LONG_WRITE, offset));
break;
case TSF_TK_STRUCT:
for (i = 0; i < tsf_struct_type_get_num_elements(type); ++i) {
tsf_named_type_t *n = tsf_struct_type_get_element(type, i);
if (n->type->kind_code == TSF_TK_BIT) {
continue;
}
C(generate_generator(proto,
n->type,
offset + n->offset,
label));
}
for (i = 0; i < tsf_struct_type_get_num_elements(type); ++i) {
tsf_named_type_t *n = tsf_struct_type_get_element(type, i);
if (n->type->kind_code != TSF_TK_BIT) {
continue;
}
C(append(proto,
GPC_I_BIT_MASK_WRITE,
bit,
offset + n->offset));
++bit;
if (bit == 8) {
bit = 0;
C(append(proto, GPC_I_SKIP, 1));
}
}
if (bit) {
C(append(proto, GPC_I_SKIP, 1));
}
break;
case TSF_TK_ARRAY:
if (type->u.a.element_type->kind_code == TSF_TK_VOID) {
C(append(proto,
GPC_I_ARRAY_LEN_WRITE_FIELD,
offset + tsf_offsetof(tsf_native_void_array_t,
len)));
} else if (type->u.a.element_type->kind_code == TSF_TK_BIT) {
C(append(proto,
GPC_I_BITVECTOR_WRITE,
offset));
} else if (type->u.a.element_type->kind_code == TSF_TK_UINT8 ||
type->u.a.element_type->kind_code == TSF_TK_INT8
#ifndef NEED_INT_CONVERSION
|| tsf_type_kind_is_int(
type->u.a.element_type->kind_code)
#endif
#ifndef NEED_FLOAT_CONVERSION
|| tsf_type_kind_is_float(
type->u.a.element_type->kind_code)
#endif
) {
C(append(proto,
GPC_I_BYTE_ARRAY_WRITE,
offset,
tsf_native_type_get_size(
type->u.a.element_type)));
} else {
gpc_cell_t loop_label = label++;
done_label = label++;
C(append(proto,
GPC_I_ARRAY_LEN_WRITE_FIELD,
offset + tsf_offsetof(tsf_native_array_t,
len)));
C(append(proto,
GPC_I_PUSH_PTR,
offset + tsf_offsetof(tsf_native_array_t,
data)));
C(append(proto,
GPC_I_REPUSH_MULADD_PTR,
offset + tsf_offsetof(tsf_native_array_t,
len),
tsf_native_type_get_size(
type->u.a.element_type)));
C(append(proto,
GPC_I_COMPFAILJUMP,
done_label));
C(append(proto,
GPC_I_LABEL,
loop_label));
C(generate_generator(proto,
type->u.a.element_type,
0,
label));
C(append(proto,
GPC_I_ADDCOMPJUMP,
tsf_native_type_get_size(
type->u.a.element_type),
loop_label));
C(append(proto,
GPC_I_LABEL,
done_label));
C(append(proto,GPC_I_TWO_POP));
}
break;
case TSF_TK_CHOICE:
if (tsf_choice_type_get_num_elements(type) >= 256) {
if (type->u.h.choice_as_full_word) {
C(append(proto,
GPC_I_COPY_HTONL_INCDST,
offset + type->u.h.value_offset));
} else {
C(append(proto,
GPC_I_TSF_UNSIGNED_PLUS1_WRITE,
offset + type->u.h.value_offset));
}
} else {
C(append(proto,
GPC_I_COPY_HTONCHOICE_TO_UI8_INCDST,
offset + type->u.h.value_offset));
}
if (tsf_choice_type_has_non_void(type)) {
gpc_cell_t *targets;
gpc_cell_t label_offset;
tsf_bool_t result;
label_offset = label;
label += tsf_choice_type_get_num_elements(type);
done_label = label++;
really_done_label = label++;
targets = malloc(sizeof(gpc_cell_t) *
tsf_choice_type_get_num_elements(type));
if (targets == NULL) {
tsf_set_errno("Could not malloc array of gpc_cell_t");
return tsf_false;
}
for (i = 0; i < tsf_choice_type_get_num_elements(type); ++i) {
targets[i] = label_offset + i;
}
result = append_tablejump_field(
proto,
offset + type->u.h.value_offset,
tsf_choice_type_get_num_elements(type),
targets);
free(targets);
if (!result) {
return tsf_false;
}
/* for unknown values */
C(append(proto, GPC_I_JUMP, really_done_label));
for (i = 0; i < tsf_choice_type_get_num_elements(type); ++i) {
tsf_named_type_t *n = tsf_choice_type_get_element(type, i);
C(append(proto, GPC_I_LABEL, label_offset + i));
if (tsf_native_choice_type_is_in_place(type)) {
C(generate_generator(proto,
n->type,
offset + type->u.h.data_offset,
label));
} else {
C(append(proto, GPC_I_PUSH_PTR,
offset + type->u.h.data_offset));
C(generate_generator(proto,
n->type,
0,
label));
}
C(append(proto, GPC_I_JUMP, done_label));
}
C(append(proto, GPC_I_LABEL, done_label));
if (!tsf_native_choice_type_is_in_place(type)) {
C(append(proto, GPC_I_POP));
}
C(append(proto, GPC_I_LABEL, really_done_label));
}
break;
case TSF_TK_STRING:
C(append(proto, GPC_I_STRING_WRITE, offset));
break;
case TSF_TK_ANY:
C(append(proto, GPC_I_ANY_WRITE, offset));
break;
default:
tsf_abort("Bad kind code!");
break;
}
return tsf_true;
}