static void store_array(void) { struct number *inumber; struct value *value; struct stack *stack; u_long idx; int reg; reg = readreg(); if (reg >= 0) { inumber = pop_number(); if (inumber == NULL) return; value = pop(); if (value == NULL) { free_number(inumber); return; } idx = get_ulong(inumber); if (BN_is_negative(inumber->number)) { warnx("negative idx"); stack_free_value(value); } else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX) { warnx("idx too big"); stack_free_value(value); } else { stack = &bmachine.reg[reg]; frame_assign(stack, idx, value); } free_number(inumber); } }
static void store_array(void) { int reg; struct number *inumber; u_long index; struct value *value; struct stack *stack; reg = readreg(); if (reg >= 0) { inumber = pop_number(); if (inumber == NULL) return; value = pop(); if (value == NULL) { free_number(inumber); return; } index = get_ulong(inumber); if (BN_cmp(inumber->number, &zero) < 0) { warnx("negative index"); stack_free_value(value); } else if (index == BN_MASK2 || index > MAX_ARRAY_INDEX) { warnx("index too big"); stack_free_value(value); } else { stack = &bmachine.reg[reg]; frame_assign(stack, index, value); } free_number(inumber); } }
static void to_ascii(void) { struct number *n; struct value *value; char str[2]; value = pop(); if (value != NULL) { str[1] = '\0'; switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: n = value->u.num; normalize(n, 0); if (BN_num_bits(n->number) > 8) bn_check(BN_mask_bits(n->number, 8)); str[0] = (char)BN_get_word(n->number); break; case BCODE_STRING: str[0] = value->u.string[0]; break; } stack_free_value(value); push_string(bstrdup(str)); } }
static void num_digits(void) { struct number *n = NULL; struct value *value; size_t digits; value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: digits = count_digits(value->u.num); n = new_number(); bn_check(BN_set_word(n->number, digits)); break; case BCODE_STRING: digits = strlen(value->u.string); n = new_number(); bn_check(BN_set_word(n->number, digits)); break; } stack_free_value(value); push_number(n); } }
static void drop(void) { struct value *v = pop(); if (v != NULL) stack_free_value(v); }
static void push_scale(void) { struct value *value; u_int scale = 0; struct number *n; value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: scale = value->u.num->scale; break; case BCODE_STRING: break; } stack_free_value(value); n = new_number(); bn_check(BN_set_word(n->number, scale)); push_number(n); } }
static __inline void array_assign(struct array *array, size_t index, const struct value *v) { if (index >= array->size) array_grow(array, index+1); stack_free_value(&array->data[index]); array->data[index] = *v; }
void stack_clear(struct stack *stack) { while (stack->sp >= 0) stack_free_value(&stack->stack[stack->sp--]); free(stack->stack); stack_init(stack); }
static void pop_printn(void) { struct value *value = pop(); if (value != NULL) { print_value(stdout, value, "", bmachine.obase); fflush(stdout); stack_free_value(value); } }
static __inline void array_free(struct array *a) { u_int i; if (a == NULL) return; for (i = 0; i < a->size; i++) stack_free_value(&a->data[i]); free(a->data); free(a); }
void stack_set_tos(struct stack *stack, struct value *v) { if (stack->sp == -1) stack_push(stack, v); else { stack_free_value(&stack->stack[stack->sp]); stack->stack[stack->sp] = *v; stack->stack[stack->sp].array = v->array == NULL ? NULL : array_dup(v->array); } }
static void pop_print(void) { struct value *value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: break; case BCODE_NUMBER: normalize(value->u.num, 0); print_ascii(stdout, value->u.num); fflush(stdout); break; case BCODE_STRING: fputs(value->u.string, stdout); fflush(stdout); break; } stack_free_value(value); } }