Implement instanceof checks. (#23)
This commit is contained in:
@@ -74,11 +74,31 @@ void* AllocInstance(const TypeInfo* type_info, PlacementHint hint) {
|
|||||||
return ObjectContainer(type_info).GetPlace();
|
return ObjectContainer(type_info).GetPlace();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* AllocArrayInstance(const TypeInfo* type_info, PlacementHint hint, uint32_t elements) {
|
void* AllocArrayInstance(
|
||||||
|
const TypeInfo* type_info, PlacementHint hint, uint32_t elements) {
|
||||||
RuntimeAssert(type_info->instanceSize_ < 0, "must be an array");
|
RuntimeAssert(type_info->instanceSize_ < 0, "must be an array");
|
||||||
return ArrayContainer(type_info, elements).GetPlace();
|
return ArrayContainer(type_info, elements).GetPlace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IsInstance(const ObjHeader* obj, const TypeInfo* type_info) {
|
||||||
|
// We assume null check is handled by caller.
|
||||||
|
RuntimeAssert(obj != nullptr, "must not be null");
|
||||||
|
const TypeInfo* obj_type_info = obj->type_info();
|
||||||
|
// If it is an interface - check in list of implemented interfaces.
|
||||||
|
if (type_info->fieldsCount_ < 0) {
|
||||||
|
for (int i = 0; i < obj_type_info->implementedInterfacesCount_; ++i) {
|
||||||
|
if (obj_type_info->implementedInterfaces_[i] == type_info) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (obj_type_info != nullptr && obj_type_info != type_info) {
|
||||||
|
obj_type_info = obj_type_info->superType_;
|
||||||
|
}
|
||||||
|
return obj_type_info != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ extern "C" {
|
|||||||
void InitMemory();
|
void InitMemory();
|
||||||
void* AllocInstance(const TypeInfo* type_info, PlacementHint hint);
|
void* AllocInstance(const TypeInfo* type_info, PlacementHint hint);
|
||||||
void* AllocArrayInstance(const TypeInfo* type_info, PlacementHint hint, uint32_t elements);
|
void* AllocArrayInstance(const TypeInfo* type_info, PlacementHint hint, uint32_t elements);
|
||||||
|
int IsInstance(const ObjHeader* obj, const TypeInfo* type_info);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,17 @@ struct TypeInfo {
|
|||||||
// Must be pointer to Any for array classes, and null for Any.
|
// Must be pointer to Any for array classes, and null for Any.
|
||||||
const TypeInfo* superType_;
|
const TypeInfo* superType_;
|
||||||
// All object references inside this object.
|
// All object references inside this object.
|
||||||
const int* objOffsets_;
|
const int32_t* objOffsets_;
|
||||||
int objOffsetsCount_;
|
int32_t objOffsetsCount_;
|
||||||
const TypeInfo* const* implementedInterfaces_;
|
const TypeInfo* const* implementedInterfaces_;
|
||||||
int implementedInterfacesCount_;
|
int32_t implementedInterfacesCount_;
|
||||||
void* const* vtable_; // TODO: place vtable at the end of TypeInfo to eliminate the indirection
|
// TODO: place vtable at the end of TypeInfo to eliminate the indirection.
|
||||||
|
void* const* vtable_;
|
||||||
const MethodTableRecord* openMethods_;
|
const MethodTableRecord* openMethods_;
|
||||||
uint32_t openMethodsCount_;
|
uint32_t openMethodsCount_;
|
||||||
const FieldTableRecord* fields_;
|
const FieldTableRecord* fields_;
|
||||||
uint32_t fieldsCount_;
|
// Is negative to mark an interface.
|
||||||
|
int32_t fieldsCount_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Reference in New Issue
Block a user