const VirtualScope& find_virtual_scope(const SignatureMap& sig_map, const DexMethod* meth) { const auto& protos = sig_map.find(meth->get_name()); always_assert(protos != sig_map.end()); const auto& scopes = protos->second.find(meth->get_proto()); always_assert(scopes != protos->second.end()); const auto meth_type = meth->get_class(); for (const auto& scope : scopes->second) { if (scope.type == get_object_type()) return scope; if (is_subclass(scope.type, meth_type)) return scope; } always_assert_log(false, "unreachable. Scope not found for %s\n", SHOW(meth)); }
static int is_subclass(lua_State *L, int arg, int mt_index) { int ok; if(luaL_getmetafield(L, arg, "__index") == LUA_TNIL) return 0; if(lua_rawequal(L, mt_index, lua_gettop(L))) { lua_pop(L, 1); return 1; } ok = is_subclass(L, lua_gettop(L), mt_index); lua_pop(L, 1); return ok; }
Instance_Ref::Instance_Ref(const Meta_Class* mc, const Instance_Ref& x) { if (!is_subclass(mc, x._inst->meta_class)) { _inst = 0; String to_class = mc->name; String from_class = x._inst->meta_class->name; to_class.append("_Ref"); from_class.append("_Ref"); throw Exception( Exception::BAD_CAST, "while casting from from %s to %s", from_class.c_str(), to_class.c_str()); } ref(_inst = x._inst); }
void *udata_test(lua_State *L, int arg, const char *mt) /* same as luaL_testudata(), but succeeds also if the userdata has not * mt as metatable but as ancestor */ { void *mem; int ok; if((mem = luaL_testudata(L, arg, mt))) return mem; if((mem = lua_touserdata(L, arg)) == NULL) return NULL; if(luaL_getmetatable(L, mt)!=LUA_TTABLE) { luaL_error(L, "cannot find metatable '%s'", mt); return NULL; } ok = is_subclass(L, arg, lua_gettop(L)); lua_pop(L, 1); return ok ? mem : NULL; }
int Value::get(Instance* instance, const Meta_Feature* mf) { if (!instance) { CIMPLE_WARN(("null instance argument")); return -1; } const Meta_Class* mc = instance->meta_class; void* field = 0; if (type_of(mf) != _type) { CIMPLE_WARN(("type mismatch: %s.%s", mc->name, mf->name)); return -1; } if (mf->flags & CIMPLE_FLAG_METHOD) { return -1; } else if (mf->flags & CIMPLE_FLAG_PROPERTY) { const Meta_Property* mp = (const Meta_Property*)mf; field = (char*)instance + mp->offset; if (_null) null_of(mp, field) = 1; else null_of(mp, field) = 0; } else if (mf->flags & CIMPLE_FLAG_REFERENCE) { const Meta_Reference* mr = (const Meta_Reference*)mf; field = (char*)instance + mr->offset; } switch (_type) { case NONE: return -1; case BOOLEAN: *((boolean*)field) = *((boolean*)_buffer); return 0; case UINT8: *((uint8*)field) = *((uint8*)_buffer); return 0; case SINT8: *((sint8*)field) = *((sint8*)_buffer); return 0; case UINT16: *((uint16*)field) = *((uint16*)_buffer); return 0; case SINT16: *((sint16*)field) = *((sint16*)_buffer); return 0; case UINT32: *((uint32*)field) = *((uint32*)_buffer); return 0; case SINT32: *((sint32*)field) = *((sint32*)_buffer); return 0; case UINT64: *((uint64*)field) = *((uint64*)_buffer); return 0; case SINT64: *((sint64*)field) = *((sint64*)_buffer); return 0; case REAL32: *((real32*)field) = *((real32*)_buffer); return 0; case REAL64: *((real64*)field) = *((real64*)_buffer); return 0; case CHAR16: *((char16*)field) = *((char16*)_buffer); return 0; case STRING: *((String*)field) = *((String*)_buffer); return 0; case DATETIME: *((Datetime*)field) = *((Datetime*)_buffer); return 0; case INSTANCE: { Instance* x = *((Instance**)_buffer); const Meta_Reference* mr = (const Meta_Reference*)mf; if (x && !is_subclass(mr->meta_class, x->meta_class)) { CIMPLE_WARN(("failed to assign instance of %s to %s.%s", x->meta_class->name, mc->name, mf->name)); return -1; } ref(x); *((Instance**)field) = x; return 0; } case BOOLEAN_ARRAY: *((Array_boolean*)field) = *((Array_boolean*)_buffer); return 0; case UINT8_ARRAY: *((Array_uint8*)field) = *((Array_uint8*)_buffer); return 0; case SINT8_ARRAY: *((Array_sint8*)field) = *((Array_sint8*)_buffer); return 0; case UINT16_ARRAY: *((Array_uint16*)field) = *((Array_uint16*)_buffer); return 0; case SINT16_ARRAY: *((Array_sint16*)field) = *((Array_sint16*)_buffer); return 0; case UINT32_ARRAY: *((Array_uint32*)field) = *((Array_uint32*)_buffer); return 0; case SINT32_ARRAY: *((Array_sint32*)field) = *((Array_sint32*)_buffer); return 0; case UINT64_ARRAY: *((Array_uint64*)field) = *((Array_uint64*)_buffer); return 0; case SINT64_ARRAY: *((Array_sint64*)field) = *((Array_sint64*)_buffer); return 0; case REAL32_ARRAY: *((Array_real32*)field) = *((Array_real32*)_buffer); return 0; case REAL64_ARRAY: *((Array_real64*)field) = *((Array_real64*)_buffer); return 0; case CHAR16_ARRAY: *((Array_char16*)field) = *((Array_char16*)_buffer); return 0; case STRING_ARRAY: *((Array_String*)field) = *((Array_String*)_buffer); return 0; case DATETIME_ARRAY: *((Array_Datetime*)field) = *((Array_Datetime*)_buffer); return 0; case INSTANCE_ARRAY: { *((Array_Instance*)field) = *((Array_Instance*)_buffer); const Array_Instance& x = *((Array_Instance*)_buffer); const Meta_Reference* mr = (const Meta_Reference*)mf; for (size_t i = 0; i < x.size(); i++) { if (x[i] && !is_subclass(mr->meta_class, x[i]->meta_class)) { CIMPLE_WARN(("failed to assign instance of %s to %s.%s", x[i]->meta_class->name, mc->name, mf->name)); return -1; } ref(x[i]); } return 0; } } return -1; }