kj_internal void vm_op_unm(vm_t *vm, value_t *dest, value_t const *val) { switch (val->type) { case KJ_TYPE_INT: value_set_integer(dest, vm->allocator, -val->integer); break; case KJ_TYPE_REAL: value_set_real(dest, vm->allocator, -val->real); break; default: vm_throw(vm, "cannot apply unary minus operation to a %s value.", VALUE_TYPE_STRING[val->type]); } }
static value_ptr extract_real(bplist_info_ptr bplist, uint64_t offset) { value_ptr value = value_create(); uint32_t size; assert(bplist->data_bytes != NULL && offset < bplist->length); size = 1 << (bplist->data_bytes[offset] & 0x0F); // FIXME: what to do if faced with other sizes for float/double? assert (sizeof (float) == sizeof (uint32_t) && sizeof (double) == sizeof (uint64_t)); if (offset + 1 + size > bplist->length) { bplist_log("Bad binary plist: %s object overlaps end of container.\n", "floating-point number"); free(value); return NULL; } if (size == sizeof (float)) { // cast is ok because we know size is 4 bytes uint32_t i = (uint32_t) read_sized_int(bplist, offset + 1, size); // Note that this handles byte swapping. value_set_real(value, *(float *)&i); return value; } else if (size == sizeof (double)) { uint64_t i = read_sized_int(bplist, offset + 1, size); // Note that this handles byte swapping. value_set_real(value, *(double *)&i); return value; } else { // Can't handle floats of other sizes. bplist_log("Bad binary plist: can't handle %u-byte float.\n", size); free(value); return NULL; } }