From 8d2c0edd6b8c3215bcf0eb7dac18290cdb171669 Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Mon, 31 Oct 2016 08:14:04 +0300 Subject: [PATCH] Implement instanceof checks. (#23) --- runtime/src/main/cpp/Memory.cpp | 22 +++++++++++++++++++++- runtime/src/main/cpp/Memory.h | 1 + runtime/src/main/cpp/TypeInfo.h | 12 +++++++----- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/runtime/src/main/cpp/Memory.cpp b/runtime/src/main/cpp/Memory.cpp index f10c33a85da..140f2ef332c 100644 --- a/runtime/src/main/cpp/Memory.cpp +++ b/runtime/src/main/cpp/Memory.cpp @@ -74,11 +74,31 @@ void* AllocInstance(const TypeInfo* type_info, PlacementHint hint) { 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"); 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 } #endif diff --git a/runtime/src/main/cpp/Memory.h b/runtime/src/main/cpp/Memory.h index 93646898739..0308a636292 100644 --- a/runtime/src/main/cpp/Memory.h +++ b/runtime/src/main/cpp/Memory.h @@ -260,6 +260,7 @@ extern "C" { void InitMemory(); void* AllocInstance(const TypeInfo* type_info, PlacementHint hint); void* AllocArrayInstance(const TypeInfo* type_info, PlacementHint hint, uint32_t elements); +int IsInstance(const ObjHeader* obj, const TypeInfo* type_info); #ifdef __cplusplus } diff --git a/runtime/src/main/cpp/TypeInfo.h b/runtime/src/main/cpp/TypeInfo.h index ecfae72bb60..836268b158f 100644 --- a/runtime/src/main/cpp/TypeInfo.h +++ b/runtime/src/main/cpp/TypeInfo.h @@ -28,15 +28,17 @@ struct TypeInfo { // Must be pointer to Any for array classes, and null for Any. const TypeInfo* superType_; // All object references inside this object. - const int* objOffsets_; - int objOffsetsCount_; + const int32_t* objOffsets_; + int32_t objOffsetsCount_; const TypeInfo* const* implementedInterfaces_; - int implementedInterfacesCount_; - void* const* vtable_; // TODO: place vtable at the end of TypeInfo to eliminate the indirection + int32_t implementedInterfacesCount_; + // TODO: place vtable at the end of TypeInfo to eliminate the indirection. + void* const* vtable_; const MethodTableRecord* openMethods_; uint32_t openMethodsCount_; const FieldTableRecord* fields_; - uint32_t fieldsCount_; + // Is negative to mark an interface. + int32_t fieldsCount_; }; #ifdef __cplusplus