Value ffi_pointer_read(VMState *state, Object *type, void *ptr) { ValueCache *vcache = &state->shared->vcache; Object *string_base = vcache->string_base; FFIObject *ffi = (FFIObject*) vcache->ffi_obj; if (type == ffi->float_obj) { float f = *(float*) ptr; return FLOAT2VAL(f); } else if (type == ffi->int_obj) { int i = *(int*) ptr; return INT2VAL(i); } else if (type == ffi->uint_obj) { unsigned int i = *(unsigned int*) ptr; return INT2VAL(i); } else { bool has_pointer = false; OBJECT_LOOKUP_P(type, pointer, &has_pointer); if (!has_pointer) { Object *c_type_obj = OBJ_OR_NULL(OBJECT_LOOKUP(type, c_type)); StringObject *c_type = (StringObject*) obj_instance_of(c_type_obj, string_base); VM_ASSERT(c_type, "internal type error") VNULL; VM_ASSERT(false, "unhandled pointer read type: %s", c_type->value) VNULL; } Value res = make_object(state, type, false); char *error = OBJECT_SET(state, AS_OBJ(res), pointer, make_ffi_pointer(state, ptr)); VM_ASSERT(!error, error) VNULL; return res; } }
static void ffi_ptr_dereference(VMState *state, CallInfo *info) { VM_ASSERT(info->args_len == 2, "wrong arity: expected 2, got %i", info->args_len); Object *root = state->root; Object *pointer_base = state->shared->vcache.pointer_base; FFIObject *ffi = (FFIObject*) AS_OBJ(OBJECT_LOOKUP(root, ffi)); Object *ffi_type = AS_OBJ(OBJECT_LOOKUP((Object*) ffi, type)); Object *thisptr = AS_OBJ(load_arg(state->frame, info->this_arg)); VM_ASSERT(thisptr->parent == pointer_base, "internal error"); PointerObject *thisptr_obj = (PointerObject*) thisptr; Object *ffi_type_obj = obj_instance_of(OBJ_OR_NULL(load_arg(state->frame, INFO_ARGS_PTR(info)[0])), ffi_type); Value offs_val = load_arg(state->frame, INFO_ARGS_PTR(info)[1]); VM_ASSERT(IS_INT(offs_val), "offset must be integer"); int offs = AS_INT(offs_val); VM_ASSERT(ffi_type_obj, "type is not a FFI type"); char *offset_ptr = (char*) thisptr_obj->ptr + offs; if (ffi_type_obj == ffi->short_obj) { short s = *(short*) offset_ptr; vm_return(state, info, INT2VAL(s)); } else if (ffi_type_obj == ffi->ushort_obj) { unsigned short us = *(unsigned short*) offset_ptr; vm_return(state, info, INT2VAL(us)); } else if (ffi_type_obj == ffi->int_obj) { int i = *(int*) offset_ptr; vm_return(state, info, INT2VAL(i)); } else if (ffi_type_obj == ffi->uint_obj) { unsigned int u = *(unsigned int*) offset_ptr; vm_return(state, info, INT2VAL(u)); } else if (ffi_type_obj == ffi->int8_obj) { int8_t i8 = *(int8_t*) offset_ptr; vm_return(state, info, INT2VAL(i8)); } else if (ffi_type_obj == ffi->uint8_obj) { uint8_t u8 = *(uint8_t*) offset_ptr; vm_return(state, info, INT2VAL(u8)); } else if (ffi_type_obj == ffi->int32_obj) { int32_t i32 = *(int32_t*) offset_ptr; vm_return(state, info, INT2VAL(i32)); } else if (ffi_type_obj == ffi->uint32_obj) { uint32_t u32 = *(uint32_t*) offset_ptr; vm_return(state, info, INT2VAL(u32)); } else if (ffi_type_obj == ffi->pointer_obj) { void *ptr = *(void**) offset_ptr; vm_return(state, info, make_ffi_pointer(state, ptr)); } else if (ffi_type_obj == ffi->char_pointer_obj) { char *ptr = *(char**) offset_ptr; vm_return(state, info, make_string_static(state, ptr)); } else if (ffi_type_obj == ffi->long_obj) { long l = *(long*) offset_ptr; if (l < INT_MIN || l > INT_MAX) { VM_ASSERT(false, "value exceeds bounds of my int type"); } vm_return(state, info, INT2VAL((int) l)); } else { fprintf(stderr, "TODO\n"); abort(); } }
static VALUE ErrorGetNum(VALUE self) { return INT2VAL(MqErrorGetNum(MQCTX)); }
static VALUE Size (VALUE self) { return INT2VAL(MqDumpSize(DUMP)); }
static PHP_METHOD(MsgqueForPhp_MqDumpS, Size) { SETUP_dump; INT2VAL(return_value, MqDumpSize(dump)); }