Пример #1
0
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));
}
Пример #2
0
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;
    }
Пример #3
0
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);
}
Пример #4
0
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;
    }
Пример #5
0
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;
}