Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of generating JS class from Metadata #1824

Merged
merged 10 commits into from
Jan 19, 2025
1 change: 1 addition & 0 deletions test-app/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -115,6 +115,7 @@ add_library(
src/main/cpp/MetadataNode.cpp
src/main/cpp/MetadataReader.cpp
src/main/cpp/MetadataTreeNode.cpp
src/main/cpp/MetadataEntry.cpp
src/main/cpp/MethodCache.cpp
src/main/cpp/ModuleBinding.cpp
src/main/cpp/ModuleInternal.cpp
21 changes: 11 additions & 10 deletions test-app/runtime/src/main/cpp/CallbackHandlers.cpp
Original file line number Diff line number Diff line change
@@ -213,7 +213,8 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string

auto isolate = args.GetIsolate();

if ((entry != nullptr) && entry->isResolved) {
if ((entry != nullptr) && entry->getIsResolved()) {
auto &entrySignature = entry->getSig();
isStatic = entry->isStatic;

if (entry->memberId == nullptr) {
@@ -236,14 +237,14 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string
if (isFromInterface) {
auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className,
methodName,
entry->sig);
entrySignature);
entry->memberId = methodAndClassPair.first;
clazz = methodAndClassPair.second;
} else {
entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetStaticMethodID(clazz, methodName, entrySignature);
}
} else {
entry->memberId = env.GetMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetMethodID(clazz, methodName, entrySignature);
}

if (entry->memberId == nullptr) {
@@ -257,14 +258,14 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string
if (isFromInterface) {
auto methodAndClassPair = env.GetInterfaceStaticMethodIDAndJClass(className,
methodName,
entry->sig);
entrySignature);
entry->memberId = methodAndClassPair.first;
clazz = methodAndClassPair.second;
} else {
entry->memberId = env.GetStaticMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetStaticMethodID(clazz, methodName, entrySignature);
}
} else {
entry->memberId = env.GetMethodID(clazz, methodName, entry->sig);
entry->memberId = env.GetMethodID(clazz, methodName, entrySignature);
}

if (entry->memberId == nullptr) {
@@ -279,9 +280,9 @@ void CallbackHandlers::CallJavaMethod(const Local<Object> &caller, const string

mid = reinterpret_cast<jmethodID>(entry->memberId);
clazz = entry->clazz;
sig = &entry->sig;
returnType = &entry->returnType;
retType = entry->retType;
sig = &entrySignature;
returnType = &entry->getReturnType();
retType = entry->getRetType();
} else {
DEBUG_WRITE("Resolving method: %s on className %s", methodName.c_str(), className.c_str());

33 changes: 19 additions & 14 deletions test-app/runtime/src/main/cpp/FieldAccessor.cpp
Original file line number Diff line number Diff line change
@@ -19,8 +19,10 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&

JniLocalRef targetJavaObject;

const auto& fieldTypeName = fieldData->signature;
auto isStatic = fieldData->isStatic;
auto &fieldMetadata = fieldData->metadata;

const auto& fieldTypeName = fieldMetadata.getSig();
auto isStatic = fieldMetadata.isStatic;

auto isPrimitiveType = fieldTypeName.size() == 1;
auto isFieldArray = fieldTypeName[0] == '[';
@@ -35,11 +37,11 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&
("L" + fieldTypeName + ";"));

if (isStatic) {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->clazz = env.FindClass(fieldMetadata.getDeclaringType());
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldMetadata.name, fieldJniSig);
} else {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->clazz = env.FindClass(fieldMetadata.getDeclaringType());
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldMetadata.name, fieldJniSig);
}
}

@@ -48,7 +50,7 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&

if (targetJavaObject.IsNull()) {
stringstream ss;
ss << "Cannot access property '" << fieldData->name.c_str() << "' because there is no corresponding Java object";
ss << "Cannot access property '" << fieldMetadata.name.c_str() << "' because there is no corresponding Java object";
throw NativeScriptException(ss.str());
}
}
@@ -186,14 +188,17 @@ Local<Value> FieldAccessor::GetJavaField(Isolate* isolate, const Local<Object>&
void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target, const Local<Value>& value, FieldCallbackData* fieldData) {
JEnv env;

auto &fieldMetadata = fieldData->metadata;

HandleScope handleScope(isolate);
auto runtime = Runtime::GetRuntime(isolate);
auto objectManager = runtime->GetObjectManager();

JniLocalRef targetJavaObject;

const auto& fieldTypeName = fieldData->signature;
auto isStatic = fieldData->isStatic;
const auto& fieldTypeName = fieldMetadata.getSig();
auto isStatic = fieldMetadata.isStatic;


auto isPrimitiveType = fieldTypeName.size() == 1;
auto isFieldArray = fieldTypeName[0] == '[';
@@ -208,14 +213,14 @@ void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target,
("L" + fieldTypeName + ";"));

if (isStatic) {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->clazz = env.FindClass(fieldMetadata.getDeclaringType());
assert(fieldData->clazz != nullptr);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->fid = env.GetStaticFieldID(fieldData->clazz, fieldMetadata.name, fieldJniSig);
assert(fieldData->fid != nullptr);
} else {
fieldData->clazz = env.FindClass(fieldData->declaringType);
fieldData->clazz = env.FindClass(fieldMetadata.getDeclaringType());
assert(fieldData->clazz != nullptr);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldData->name, fieldJniSig);
fieldData->fid = env.GetFieldID(fieldData->clazz, fieldMetadata.name, fieldJniSig);
assert(fieldData->fid != nullptr);
}
}
@@ -225,7 +230,7 @@ void FieldAccessor::SetJavaField(Isolate* isolate, const Local<Object>& target,

if (targetJavaObject.IsNull()) {
stringstream ss;
ss << "Cannot access property '" << fieldData->name.c_str() << "' because there is no corresponding Java object";
ss << "Cannot access property '" << fieldMetadata.name.c_str() << "' because there is no corresponding Java object";
throw NativeScriptException(ss.str());
}
}
27 changes: 9 additions & 18 deletions test-app/runtime/src/main/cpp/FieldCallbackData.h
Original file line number Diff line number Diff line change
@@ -5,25 +5,16 @@
#include "MetadataEntry.h"

namespace tns {
struct FieldCallbackData {
FieldCallbackData(const MetadataEntry& metadata)
:
fid(nullptr), clazz(nullptr) {
name = metadata.name;
signature = metadata.sig;
declaringType = metadata.declaringType;
isStatic = metadata.isStatic;
isFinal = metadata.isFinal;
}
struct FieldCallbackData {
FieldCallbackData(MetadataEntry metadata)
:
metadata(metadata), fid(nullptr), clazz(nullptr) {
}

std::string name;
std::string signature;
std::string declaringType;
bool isStatic;
bool isFinal;
jfieldID fid;
jclass clazz;
};
MetadataEntry metadata;
jfieldID fid;
jclass clazz;
};

}

4 changes: 2 additions & 2 deletions test-app/runtime/src/main/cpp/JsArgConverter.cpp
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ JsArgConverter::JsArgConverter(const Local<Object> &caller,
m_argsLen = 1 + v8ProvidedArgumentsLength;

if (m_argsLen > 0) {
if ((entry != nullptr) && (entry->isResolved)) {
if ((entry != nullptr) && (entry->getIsResolved())) {
if (entry->parsedSig.empty()) {
JniSignatureParser parser(m_methodSignature);
entry->parsedSig = parser.Parse();
@@ -58,7 +58,7 @@ JsArgConverter::JsArgConverter(const v8::FunctionCallbackInfo<Value> &args,
m_argsLen = !hasImplementationObject ? args.Length() : args.Length() - 1;

if (m_argsLen > 0) {
if ((entry != nullptr) && (entry->isResolved)) {
if ((entry != nullptr) && (entry->getIsResolved())) {
if (entry->parsedSig.empty()) {
JniSignatureParser parser(m_methodSignature);
entry->parsedSig = parser.Parse();
135 changes: 135 additions & 0 deletions test-app/runtime/src/main/cpp/MetadataEntry.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#include "MetadataNode.h"
#include "MetadataEntry.h"
#include "MetadataMethodInfo.h"
#include "MetadataReader.h"

using namespace tns;

MetadataEntry::MetadataEntry(MetadataTreeNode *m_treeNode, NodeType nodeType) :
treeNode(m_treeNode), type(nodeType), isExtensionFunction(false), isStatic(false),
isTypeMember(false), memberId(nullptr), clazz(nullptr), mi(nullptr),fi(nullptr), sfi(nullptr),
retType(MethodReturnType::Unknown),
paramCount(-1), isFinal(false), isResolved(false), retTypeParsed(false),
isFinalSet(false), isResolvedSet(false) {}

std::string &MetadataEntry::getName() {
if (!name.empty()) return name;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Field) {
name = reader->ReadName(fi->nameOffset);
} else if (type == NodeType::StaticField) {
name = reader->ReadName(sfi->nameOffset);
} else if (type == NodeType::Method) {
name = mi.GetName();
}

return name;
}

std::string &MetadataEntry::getSig() {
if (!sig.empty()) return sig;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Field) {
sig = reader->ReadTypeName(fi->nodeId);
} else if (type == NodeType::StaticField) {
sig = reader->ReadTypeName(sfi->nodeId);
} else if (type == NodeType::Method) {
uint8_t sigLength = mi.GetSignatureLength();
if (sigLength > 0)
sig = mi.GetSignature();

}

return sig;
}

std::string &MetadataEntry::getReturnType() {
if (!returnType.empty()) return returnType;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method) {
if (mi.GetSignatureLength() > 0) {
returnType = MetadataReader::ParseReturnType(this->getSig());
}
} else {
return returnType;
}

return returnType;
}

MethodReturnType MetadataEntry::getRetType() {
if (retTypeParsed) return retType;
auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method && !this->getReturnType().empty()) {
retType = MetadataReader::GetReturnType(this->returnType);
}

retTypeParsed = true;

return retType;
}

std::string &MetadataEntry::getDeclaringType() {
if (!declaringType.empty()) return declaringType;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::StaticField) {
declaringType = reader->ReadTypeName(sfi->declaringType);
} else if (type == NodeType::Method && isStatic) {
declaringType = mi.GetDeclaringType();
}

return declaringType;
}

int MetadataEntry::getParamCount() {
if (paramCount != -1) return paramCount;

auto reader = MetadataNode::getMetadataReader();

if (type == NodeType::Method) {
auto sigLength = mi.GetSignatureLength();
if (sigLength > 0) {
paramCount = sigLength - 1;
} else {
paramCount = 0;
}
}

return paramCount;
}

bool MetadataEntry::getIsFinal() {
if (isFinalSet) return isFinal;

if (type == NodeType::Field) {
isFinal = fi->finalModifier == MetadataTreeNode::FINAL;
} else if (type == NodeType::StaticField) {
isFinal = sfi->finalModifier == MetadataTreeNode::FINAL;
}

isFinalSet = true;

return isFinal;
}

bool MetadataEntry::getIsResolved() {
if (isResolvedSet) return isResolved;

auto reader = MetadataNode::getMetadataReader();
if (type == NodeType::Method) {
isResolved = mi.CheckIsResolved() == 1;
}

isResolvedSet = true;

return isResolved;
}
153 changes: 105 additions & 48 deletions test-app/runtime/src/main/cpp/MetadataEntry.h
Original file line number Diff line number Diff line change
@@ -4,56 +4,113 @@
#include <string>
#include "jni.h"
#include "MetadataTreeNode.h"
#include "MetadataMethodInfo.h"
#include "MetadataFieldInfo.h"

namespace tns {
enum class NodeType {
Package,
Class,
Interface,
Method,
Field,
StaticField
};

enum class MethodReturnType {
Unknown,
Void,
Byte,
Short,
Int,
Long,
Float,
Double,
Char,
Boolean,
String,
Object
};

struct MetadataEntry {
MetadataEntry()
:
isTypeMember(false), name(std::string()), treeNode(nullptr), sig(std::string()), returnType(std::string()), retType(MethodReturnType::Unknown), paramCount(0),
isStatic(false), isFinal(false), declaringType(std::string()),
isResolved(false), isExtensionFunction(false), memberId(nullptr), clazz(nullptr) {
}
MetadataTreeNode* treeNode;
NodeType type;
std::string name;
std::string sig;
std::string returnType;
MethodReturnType retType;
std::string declaringType;
int paramCount;
bool isStatic;
bool isFinal;
bool isTypeMember;
bool isResolved;
bool isExtensionFunction;
void* memberId;
jclass clazz;
std::vector<std::string> parsedSig;
};
enum class NodeType {
Package,
Class,
Interface,
Method,
Field,
StaticField
};

enum class MethodReturnType {
Unknown,
Void,
Byte,
Short,
Int,
Long,
Float,
Double,
Char,
Boolean,
String,
Object
};

class MetadataEntry {
public:

MetadataEntry(MetadataTreeNode *m_treeNode, NodeType nodeType);

MetadataEntry(const MetadataEntry &other) = default;

MetadataEntry &operator=(const MetadataEntry &other) {
if (this != &other) {
treeNode = other.treeNode;
type = other.type;
isExtensionFunction = other.isExtensionFunction;
isStatic = other.isStatic;
isTypeMember = other.isTypeMember;
memberId = other.memberId;
clazz = other.clazz;
parsedSig = other.parsedSig;
mi = other.mi;
fi = other.fi;
sfi = other.sfi;
name = other.name;
sig = other.sig;
returnType = other.returnType;
retType = other.retType;
declaringType = other.declaringType;
paramCount = other.paramCount;
isFinal = other.isFinal;
isResolved = other.isResolved;
isResolvedSet = other.isResolvedSet;
isFinalSet = other.isFinalSet;
}
return *this;
}

std::string &getName();

std::string &getSig();

std::string &getReturnType();

MethodReturnType getRetType();

std::string &getDeclaringType();

int getParamCount();

bool getIsFinal();

bool getIsResolved();

MetadataTreeNode *treeNode;
NodeType type;
bool isExtensionFunction;
bool isStatic;
bool isTypeMember;
void *memberId;
jclass clazz;
std::vector<std::string> parsedSig;

MethodInfo mi;
FieldInfo *fi;
StaticFieldInfo *sfi;

std::string name;
std::string sig;
std::string returnType;
MethodReturnType retType;
std::string declaringType;
int paramCount;
bool isFinal;
bool isResolved;

private:

bool retTypeParsed;
bool isFinalSet;
bool isResolvedSet;

};
}

#endif /* METADATAENTRY_H_ */
65 changes: 42 additions & 23 deletions test-app/runtime/src/main/cpp/MetadataMethodInfo.cpp
Original file line number Diff line number Diff line change
@@ -1,35 +1,28 @@
#include "MetadataMethodInfo.h"
#include "MetadataNode.h"


using namespace tns;

std::string MethodInfo::GetName() {
uint32_t nameOfffset = *reinterpret_cast<uint32_t*>(m_pData);
string methodName = m_reader->ReadName(nameOfffset);
m_pData += sizeof(uint32_t);

string methodName = MetadataNode::getMetadataReader()->ReadName(nameOffset);
return methodName;
}

uint8_t MethodInfo::CheckIsResolved() {
auto resolvedData = *reinterpret_cast<uint8_t*>(m_pData);
m_pData += sizeof(uint8_t);

return resolvedData;
}

uint16_t MethodInfo::GetSignatureLength() {
m_signatureLength = *reinterpret_cast<uint16_t*>(m_pData);
m_pData += sizeof(uint16_t);

return m_signatureLength;
}

std::string MethodInfo::GetSignature() { //use nodeId's to read the whole signature
uint16_t* nodeIdPtr = reinterpret_cast<uint16_t*>(m_pData);
auto m_reader = MetadataNode::getMetadataReader();
string signature = "(";
string ret;
for (int i = 0; i < m_signatureLength; i++) {
uint16_t nodeId = *nodeIdPtr++;
uint16_t nodeId = nodeIds[i];
string curArgTypeName = m_reader->ReadTypeName(nodeId);
MetadataTreeNode* node = m_reader->GetNodeById(nodeId);

@@ -58,23 +51,49 @@ std::string MethodInfo::GetSignature() { //use nodeId's to read the whole signat
}
signature += ")" + ret;

int sizeofReadNodeIds = m_signatureLength * sizeof(uint16_t);
m_pData += sizeofReadNodeIds;

return signature;
}

std::string MethodInfo::GetDeclaringType() {
uint16_t* declaringTypePtr = reinterpret_cast<uint16_t*>(m_pData);
uint16_t nodeId = *declaringTypePtr;
auto m_reader = MetadataNode::getMetadataReader();

string declTypeName = m_reader->ReadTypeName(nodeId);

m_pData += sizeof(uint16_t);

return declTypeName;
return m_reader->ReadTypeName(declaringNodeId);
}

int MethodInfo::GetSizeOfReadMethodInfo() {

if (!sizeMeasured) {
sizeMeasured = true;
// name
nameOffset = *reinterpret_cast<uint32_t*>(m_pData);
m_pData += sizeof(uint32_t);
// resolved data
resolvedData = *reinterpret_cast<uint8_t*>(m_pData);
m_pData += sizeof(uint8_t);
// sig length
m_signatureLength = *reinterpret_cast<uint16_t*>(m_pData);
m_pData += sizeof(uint16_t);

// signature
if (m_signatureLength > 0) {
uint16_t* nodeIdPtr = reinterpret_cast<uint16_t*>(m_pData);
nodeIds.resize(m_signatureLength);
for (int i = 0; i < m_signatureLength; i++) {
nodeIds[i] = *nodeIdPtr++;
}
m_pData += m_signatureLength * sizeof(uint16_t);
}

// declaring type
if (isStatic) {
auto declaringTypePtr = reinterpret_cast<uint16_t*>(m_pData);
declaringNodeId = *declaringTypePtr;
m_pData += sizeof(uint16_t);
}



}

return m_pData - m_pStartData;
}
}
49 changes: 40 additions & 9 deletions test-app/runtime/src/main/cpp/MetadataMethodInfo.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,66 @@
#ifndef METHODINFOSMARTPOINTER_H_
#define METHODINFOSMARTPOINTER_H_

#include "MetadataReader.h"

#include <iostream>
#include <string>
#include <vector>

using namespace std;

namespace tns {
class MethodInfo {
class MethodInfo {
public:
MethodInfo(uint8_t* pValue, MetadataReader* reader)
: m_pData(pValue), m_pStartData(pValue), m_reader(reader), m_signatureLength(0) {

MethodInfo(uint8_t *pValue)
: isStatic(false), m_pData(pValue), m_pStartData(pValue), m_signatureLength(0),
sizeMeasured(false), nameOffset(0), resolvedData(0),
declaringNodeId(0){
}

MethodInfo(const MethodInfo& other) = default;

MethodInfo& operator=(const MethodInfo& other) {
if (this != &other) {
isStatic = other.isStatic;
m_pData = other.m_pData;
m_pStartData = other.m_pStartData;
m_signatureLength = other.m_signatureLength;
sizeMeasured = other.sizeMeasured;
nameOffset = other.nameOffset;
resolvedData = other.resolvedData;
declaringNodeId = other.declaringNodeId;
nodeIds = other.nodeIds;
}
return *this;
}

std::string GetName();

uint8_t CheckIsResolved();

uint16_t GetSignatureLength();

std::string GetSignature();

std::string GetDeclaringType(); //used only for static methods

int GetSizeOfReadMethodInfo();

bool isStatic;

private:
uint8_t* m_pData; //where we currently read
uint8_t* m_pStartData; // pointer to the beginning
uint8_t *m_pData; //where we currently read
uint8_t *m_pStartData; // pointer to the beginning
uint16_t m_signatureLength;
MetadataReader* m_reader;
};
bool sizeMeasured;

uint32_t nameOffset;
uint8_t resolvedData;
uint16_t declaringNodeId;
std::vector<uint16_t> nodeIds;


};
}

#endif /* METHODINFOSMARTPOINTER_H_ */
356 changes: 153 additions & 203 deletions test-app/runtime/src/main/cpp/MetadataNode.cpp

Large diffs are not rendered by default.

32 changes: 18 additions & 14 deletions test-app/runtime/src/main/cpp/MetadataNode.h
Original file line number Diff line number Diff line change
@@ -60,6 +60,8 @@ class MetadataNode {
static std::string GetTypeMetadataName(v8::Isolate* isolate, v8::Local<v8::Value>& value);

static void onDisposeIsolate(v8::Isolate* isolate);

static MetadataReader* getMetadataReader();
private:
struct MethodCallbackData;

@@ -74,30 +76,30 @@ class MetadataNode {

MetadataNode(MetadataTreeNode* treeNode);

static bool IsJavascriptKeyword(std::string word);
static bool IsJavascriptKeyword(const std::string &word);
v8::Local<v8::Object> CreatePackageObject(v8::Isolate* isolate);

v8::Local<v8::Function> GetConstructorFunction(v8::Isolate* isolate);
v8::Local<v8::FunctionTemplate> GetConstructorFunctionTemplate(v8::Isolate* isolate, MetadataTreeNode* treeNode);
v8::Local<v8::FunctionTemplate> GetConstructorFunctionTemplate(v8::Isolate* isolate, MetadataTreeNode* treeNode, std::vector<MethodCallbackData*>& instanceMethodsCallbackData);
v8::Persistent<v8::Function>* GetPersistentConstructorFunction(v8::Isolate* isolate);
v8::Local<v8::ObjectTemplate> GetOrCreateArrayObjectTemplate(v8::Isolate* isolate);
static v8::Local<v8::ObjectTemplate> GetOrCreateArrayObjectTemplate(v8::Isolate* isolate);

std::vector<MethodCallbackData*> SetInstanceMembers(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate,
PrototypeTemplateFiller& protoFiller,
std::vector<MethodCallbackData*>& instanceMethodsCallbackData,
const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData,
MetadataTreeNode* treeNode);
MetadataTreeNode* treeNode, uint8_t* &curPtr);
std::vector<MethodCallbackData*> SetInstanceMethodsFromStaticMetadata(
v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate,
PrototypeTemplateFiller& protoFiller,
std::vector<MethodCallbackData*>& instanceMethodsCallbackData,
const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData,
MetadataTreeNode* treeNode);
MethodCallbackData* tryGetExtensionMethodCallbackData(
std::unordered_map<std::string, MethodCallbackData*> collectedMethodCallbackDatas,
std::string lookupName);
MetadataTreeNode* treeNode, uint8_t* &curPtr);
static MethodCallbackData* tryGetExtensionMethodCallbackData(
const robin_hood::unordered_map<std::string, MethodCallbackData *> &collectedMethodCallbackDatas,
const std::string &lookupName);
void SetInstanceFieldsFromStaticMetadata(
v8::Isolate* isolate, PrototypeTemplateFiller& protoFiller,
MetadataTreeNode* treeNode);
@@ -106,8 +108,10 @@ class MetadataNode {
std::vector<MethodCallbackData*>& instanceMethodsCallbackData,
const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData,
MetadataTreeNode* treeNode);
void SetStaticMembers(v8::Isolate* isolate, v8::Local<v8::Function>& ctorFunction, MetadataTreeNode* treeNode);
void SetInnerTypes(v8::Isolate* isolate, v8::Local<v8::Function>& ctorFunction, MetadataTreeNode* treeNode);

void SetStaticMembers(v8::Isolate* isolate, v8::Local<v8::Function>& ctorFunction, MetadataTreeNode* treeNode, uint8_t* &curPtr);
static void InnerTypeAccessorGetterCallback(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info);
static void SetInnerTypes(v8::Isolate* isolate, v8::Local<v8::Function>& ctorFunction, MetadataTreeNode* treeNode);

static void BuildMetadata(uint32_t nodesLength, uint8_t* nodeData, uint32_t nameLength, uint8_t* nameData, uint32_t valueLength, uint8_t* valueData);

@@ -117,7 +121,7 @@ class MetadataNode {

static MetadataTreeNode* GetOrCreateTreeNodeByName(const std::string& className);

static MetadataEntry GetChildMetadataForPackage(MetadataNode* node, const std::string& propName);
static MetadataEntry GetChildMetadataForPackage(MetadataNode *node, const std::string &propName);

static MetadataNode* GetInstanceMetadata(v8::Isolate* isolate, const v8::Local<v8::Object>& value);

@@ -157,13 +161,13 @@ class MetadataNode {
static bool GetExtendLocation(v8::Isolate* isolate, std::string& extendLocation, bool isTypeScriptExtend);
static ExtendedClassCacheData GetCachedExtendedClassData(v8::Isolate* isolate, const std::string& proxyClassName);

static void RegisterSymbolHasInstanceCallback(v8::Isolate* isolate, MetadataEntry entry, v8::Local<v8::Value> interface);
static void RegisterSymbolHasInstanceCallback(v8::Isolate* isolate, MetadataEntry& entry, v8::Local<v8::Value> interface);
static void SymbolHasInstanceCallback(const v8::FunctionCallbackInfo<v8::Value>& info);
static std::string GetJniClassName(MetadataEntry entry);
static std::string GetJniClassName(MetadataEntry& entry);

v8::Local<v8::Function> Wrap(v8::Isolate* isolate, const v8::Local<v8::Function>& function, const std::string& name, const std::string& origin, bool isCtorFunc);
static v8::Local<v8::Function> Wrap(v8::Isolate* isolate, const v8::Local<v8::Function>& function, const std::string& name, const std::string& origin, bool isCtorFunc);

bool CheckClassHierarchy(JEnv& env, jclass currentClass, MetadataTreeNode* curentTreeNode, MetadataTreeNode* baseTreeNode, std::vector<MetadataTreeNode*>& skippedBaseTypes);
static bool CheckClassHierarchy(JEnv& env, jclass currentClass, MetadataTreeNode* curentTreeNode, MetadataTreeNode* baseTreeNode, std::vector<MetadataTreeNode*>& skippedBaseTypes);
void SetMissingBaseMethods(v8::Isolate* isolate,
const std::vector<MetadataTreeNode*>& skippedBaseTypes,
const std::vector<MethodCallbackData*>& instanceMethodData,
173 changes: 48 additions & 125 deletions test-app/runtime/src/main/cpp/MetadataReader.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
#include "MetadataReader.h"
#include "MetadataMethodInfo.h"
#include <android/log.h>
#include "Util.h"
#include <sstream>
#include <android/log.h>

using namespace std;
using namespace tns;

MetadataReader::MetadataReader()
:
m_nodesLength(0), m_nodeData(nullptr), m_nameLength(0), m_nameData(nullptr), m_valueLength(0), m_valueData(nullptr), m_root(nullptr), m_getTypeMetadataCallback(nullptr) {
}

MetadataReader::MetadataReader(uint32_t nodesLength, uint8_t* nodeData, uint32_t nameLength, uint8_t* nameData, uint32_t valueLength, uint8_t* valueData, GetTypeMetadataCallback getTypeMetadataCallback)
:
m_nodesLength(nodesLength), m_nodeData(nodeData), m_nameLength(nameLength), m_nameData(nameData), m_valueLength(valueLength), m_valueData(valueData), m_getTypeMetadataCallback(getTypeMetadataCallback) {
MetadataReader::MetadataReader() : m_root(nullptr), m_nodesLength(0), m_nameLength(0),
m_valueLength(0),
m_nodeData(nullptr), m_nameData(nullptr), m_valueData(nullptr),
m_getTypeMetadataCallback(nullptr) {}

MetadataReader::MetadataReader(uint32_t nodesLength, uint8_t *nodeData, uint32_t nameLength,
uint8_t *nameData, uint32_t valueLength, uint8_t *valueData,
GetTypeMetadataCallback getTypeMetadataCallback)
:
m_nodesLength(nodesLength), m_nodeData(nodeData), m_nameLength(nameLength),
m_nameData(nameData), m_valueLength(valueLength), m_valueData(valueData),
m_getTypeMetadataCallback(getTypeMetadataCallback) {
m_root = BuildTree();
}



// helper debug function when need to convert a metadata node to its full name
//std::string toFullName(MetadataTreeNode* p) {
// std::string final = p->name;
@@ -87,97 +93,12 @@ MetadataTreeNode* MetadataReader::BuildTree() {
return GetNodeById(0);
}

void MetadataReader::FillEntryWithFiedldInfo(FieldInfo* fi, MetadataEntry& entry) {
entry.isTypeMember = true;
entry.name = ReadName(fi->nameOffset);
entry.sig = ReadTypeName(fi->nodeId);
entry.isFinal = fi->finalModifier == MetadataTreeNode::FINAL;
}

void MetadataReader::FillEntryWithMethodInfo(MethodInfo& mi, MetadataEntry& entry) {
entry.type = NodeType::Method;
entry.isTypeMember = true;
entry.name = mi.GetName();
entry.isResolved = mi.CheckIsResolved() == 1;
uint16_t sigLength = mi.GetSignatureLength();
assert(sigLength > 0);
entry.paramCount = sigLength - 1;
entry.sig = mi.GetSignature();
FillReturnType(entry);
}


MetadataEntry MetadataReader::ReadInstanceFieldEntry(uint8_t** data) {
FieldInfo* fi = *reinterpret_cast<FieldInfo**>(data);

MetadataEntry entry;
FillEntryWithFiedldInfo(fi, entry);
entry.isStatic = false;
entry.type = NodeType::Field;

*data += sizeof(FieldInfo);

return entry;
}

MetadataEntry MetadataReader::ReadStaticFieldEntry(uint8_t** data) {
StaticFieldInfo* sfi = *reinterpret_cast<StaticFieldInfo**>(data);

MetadataEntry entry;
FillEntryWithFiedldInfo(sfi, entry);
entry.isStatic = true;
entry.type = NodeType::StaticField;
entry.declaringType = ReadTypeName(sfi->declaringType);

*data += sizeof(StaticFieldInfo);

return entry;
}

MetadataEntry MetadataReader::ReadInstanceMethodEntry(uint8_t** data) {
MetadataEntry entry;
MethodInfo mip(*data, this); //method info pointer+

FillEntryWithMethodInfo(mip, entry);

*data += mip.GetSizeOfReadMethodInfo();

return entry;
}

MetadataTreeNode* MetadataReader::GetNodeById(uint16_t nodeId) {
MetadataTreeNode *MetadataReader::GetNodeById(uint16_t nodeId) {
return m_v[nodeId];
}

MetadataEntry MetadataReader::ReadStaticMethodEntry(uint8_t** data) {
MetadataEntry entry;
MethodInfo smip(*data, this); //static method info pointer

FillEntryWithMethodInfo(smip, entry);
entry.isStatic = true;
entry.declaringType = smip.GetDeclaringType();

*data += smip.GetSizeOfReadMethodInfo();

return entry;
}

MetadataEntry MetadataReader::ReadExtensionFunctionEntry(uint8_t** data) {
MetadataEntry entry;
MethodInfo smip(*data, this); //static method info pointer

FillEntryWithMethodInfo(smip, entry);
entry.isStatic = true;
entry.declaringType = smip.GetDeclaringType();
entry.isExtensionFunction = true;

*data += smip.GetSizeOfReadMethodInfo();

return entry;
}


string MetadataReader::ReadTypeName(MetadataTreeNode* treeNode) {
string MetadataReader::ReadTypeName(MetadataTreeNode *treeNode) {
string name;

auto itFound = m_typeNameCache.find(treeNode);
@@ -193,7 +114,7 @@ string MetadataReader::ReadTypeName(MetadataTreeNode* treeNode) {
return name;
}

string MetadataReader::ReadTypeNameInternal(MetadataTreeNode* treeNode) {
string MetadataReader::ReadTypeNameInternal(MetadataTreeNode *treeNode) {
string name;

uint8_t prevNodeType;
@@ -205,7 +126,7 @@ string MetadataReader::ReadTypeNameInternal(MetadataTreeNode* treeNode) {

if (isArrayElement) {
uint16_t forwardNodeId = treeNode->offsetValue - ARRAY_OFFSET;
MetadataTreeNode* forwardNode = GetNodeById(forwardNodeId);
MetadataTreeNode * forwardNode = GetNodeById(forwardNodeId);
name = ReadTypeName(forwardNode);
uint8_t forwardNodeType = GetNodeType(forwardNode);
if (IsNodeTypeInterface(forwardNodeType) || IsNodeTypeClass(forwardNodeType)) {
@@ -215,7 +136,7 @@ string MetadataReader::ReadTypeNameInternal(MetadataTreeNode* treeNode) {
if (!name.empty()) {
if (!IsNodeTypeArray(curNodeType)) {
if ((IsNodeTypeClass(prevNodeType) || IsNodeTypeInterface(prevNodeType))
&& (IsNodeTypeClass(curNodeType) || IsNodeTypeInterface(curNodeType))) {
&& (IsNodeTypeClass(curNodeType) || IsNodeTypeInterface(curNodeType))) {
name = "$" + name;
} else {
name = "/" + name;
@@ -234,23 +155,23 @@ string MetadataReader::ReadTypeNameInternal(MetadataTreeNode* treeNode) {
return name;
}

uint8_t* MetadataReader::GetValueData() const {
uint8_t *MetadataReader::GetValueData() const {
return m_valueData;
}

uint16_t MetadataReader::GetNodeId(MetadataTreeNode* treeNode) {
uint16_t MetadataReader::GetNodeId(MetadataTreeNode *treeNode) {
auto itFound = find(m_v.begin(), m_v.end(), treeNode);
assert(itFound != m_v.end());
uint16_t nodeId = itFound - m_v.begin();

return nodeId;
}

MetadataTreeNode* MetadataReader::GetRoot() const {
MetadataTreeNode *MetadataReader::GetRoot() const {
return m_root;
}

uint8_t MetadataReader::GetNodeType(MetadataTreeNode* treeNode) {
uint8_t MetadataReader::GetNodeType(MetadataTreeNode *treeNode) {
if (treeNode->type == MetadataTreeNode::INVALID_TYPE) {
uint8_t nodeType;

@@ -264,7 +185,7 @@ uint8_t MetadataReader::GetNodeType(MetadataTreeNode* treeNode) {
nodeType = MetadataTreeNode::ARRAY;
} else {
uint16_t nodeId = offsetValue - ARRAY_OFFSET;
MetadataTreeNode* arrElemNode = GetNodeById(nodeId);
MetadataTreeNode * arrElemNode = GetNodeById(nodeId);
nodeType = *(m_valueData + arrElemNode->offsetValue);
}

@@ -274,19 +195,19 @@ uint8_t MetadataReader::GetNodeType(MetadataTreeNode* treeNode) {
return treeNode->type;
}

MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& className) {
MetadataTreeNode* treeNode = GetRoot();
MetadataTreeNode *MetadataReader::GetOrCreateTreeNodeByName(const string &className) {
MetadataTreeNode * treeNode = GetRoot();

int arrayIdx = -1;
string arrayName = "[";

while (className[++arrayIdx] == '[') {
MetadataTreeNode* child = treeNode->GetChild(arrayName);
MetadataTreeNode * child = treeNode->GetChild(arrayName);

if (child == nullptr) {
vector<MetadataTreeNode*>* children = treeNode->children;
vector<MetadataTreeNode *> *children = treeNode->children;
if (children == nullptr) {
children = treeNode->children = new vector<MetadataTreeNode*>;
children = treeNode->children = new vector<MetadataTreeNode *>;
}

child = new MetadataTreeNode;
@@ -310,19 +231,19 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN
}
}

vector < string > names;
vector<string> names;
Util::SplitString(cn, "/$", names);

if (arrayIdx > 0) {
bool found = false;
MetadataTreeNode* forwardedNode = GetOrCreateTreeNodeByName(cn);
MetadataTreeNode * forwardedNode = GetOrCreateTreeNodeByName(cn);

uint16_t forwardedNodeId = GetNodeId(forwardedNode);
if (treeNode->children == nullptr) {
treeNode->children = new vector<MetadataTreeNode*>();
treeNode->children = new vector<MetadataTreeNode *>();
}
vector<MetadataTreeNode*>& children = *treeNode->children;
for (auto childNode : children) {
vector<MetadataTreeNode *> &children = *treeNode->children;
for (auto childNode: children) {
uint32_t childNodeId = (childNode->offsetValue >= ARRAY_OFFSET)
? (childNode->offsetValue - ARRAY_OFFSET)
:
@@ -336,7 +257,7 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN
}

if (!found) {
MetadataTreeNode* forwardNode = new MetadataTreeNode;
MetadataTreeNode * forwardNode = new MetadataTreeNode;
forwardNode->offsetValue = forwardedNodeId + ARRAY_OFFSET;
forwardNode->parent = treeNode;

@@ -351,15 +272,15 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN

int curIdx = 0;
for (auto it = names.begin(); it != names.end(); ++it) {
MetadataTreeNode* child = treeNode->GetChild(*it);
MetadataTreeNode * child = treeNode->GetChild(*it);

if (child == nullptr) {
vector < string > api = m_getTypeMetadataCallback(cn, curIdx);
vector<string> api = m_getTypeMetadataCallback(cn, curIdx);

for (const auto& part : api) {
vector<MetadataTreeNode*>* children = treeNode->children;
for (const auto &part: api) {
vector<MetadataTreeNode *> *children = treeNode->children;
if (children == nullptr) {
children = treeNode->children = new vector<MetadataTreeNode*>;
children = treeNode->children = new vector<MetadataTreeNode *>;
}

child = new MetadataTreeNode;
@@ -381,7 +302,8 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN

if ((cKind == 'C') || (cKind == 'I')) {
child->metadata = new string(part);
child->type = (cKind == 'C') ? MetadataTreeNode::CLASS : MetadataTreeNode::INTERFACE;
child->type = (cKind == 'C') ? MetadataTreeNode::CLASS
: MetadataTreeNode::INTERFACE;
if (name == "S") {
child->type |= MetadataTreeNode::STATIC;
}
@@ -397,7 +319,7 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN

child->offsetValue = m_valueLength;
m_valueData[m_valueLength++] = child->type;
*reinterpret_cast<uint16_t*>(m_valueData + m_valueLength) = baseClassNodeId;
*reinterpret_cast<uint16_t *>(m_valueData + m_valueLength) = baseClassNodeId;
m_valueLength += sizeof(uint16_t);
} else {
child->type = MetadataTreeNode::PACKAGE;
@@ -419,11 +341,12 @@ MetadataTreeNode* MetadataReader::GetOrCreateTreeNodeByName(const string& classN
return treeNode;
}

MetadataTreeNode* MetadataReader::GetBaseClassNode(MetadataTreeNode* treeNode) {
MetadataTreeNode* baseClassNode = nullptr;
MetadataTreeNode *MetadataReader::GetBaseClassNode(MetadataTreeNode *treeNode) {
MetadataTreeNode * baseClassNode = nullptr;

if (treeNode != nullptr) {
uint16_t baseClassNodeId = *reinterpret_cast<uint16_t*>(m_valueData + treeNode->offsetValue + 1);
uint16_t baseClassNodeId = *reinterpret_cast<uint16_t *>(m_valueData +
treeNode->offsetValue + 1);

size_t nodeCount = m_v.size();

174 changes: 111 additions & 63 deletions test-app/runtime/src/main/cpp/MetadataReader.h
Original file line number Diff line number Diff line change
@@ -7,78 +7,131 @@
#include <string>
#include <assert.h>
#include "robin_hood.h"
namespace tns {
typedef std::vector<std::string> (*GetTypeMetadataCallback)(const std::string& classname, int index);

class MethodInfo;
namespace tns {
typedef std::vector<std::string> (*GetTypeMetadataCallback)(const std::string &classname,
int index);

class MetadataReader {
class MetadataReader {
public:
MetadataReader();

MetadataReader(uint32_t nodesLength, uint8_t* nodeData, uint32_t nameLength, uint8_t* nameData, uint32_t valueLength, uint8_t* valueData, GetTypeMetadataCallback getTypeMetadataCallack);
MetadataReader(uint32_t nodesLength, uint8_t *nodeData, uint32_t nameLength,
uint8_t *nameData, uint32_t valueLength, uint8_t *valueData,
GetTypeMetadataCallback getTypeMetadataCallack);

inline static MetadataEntry ReadInstanceFieldEntry(uint8_t **data) {
MetadataEntry entry(nullptr, NodeType::Field);
entry.fi = *reinterpret_cast<FieldInfo **>(data);
entry.isStatic = false;
entry.isTypeMember = false;

*data += sizeof(FieldInfo);

return entry;
}

inline static MetadataEntry ReadStaticFieldEntry(uint8_t **data) {
MetadataEntry entry(nullptr, NodeType::StaticField);
entry.sfi = *reinterpret_cast<StaticFieldInfo **>(data);
entry.isStatic = true;
entry.isTypeMember = false;

*data += sizeof(StaticFieldInfo);

return entry;
}

inline static MetadataEntry ReadInstanceMethodEntry(uint8_t **data) {
MetadataEntry entry(nullptr, NodeType::Method);
entry.isTypeMember = true;

entry.mi = MethodInfo(*data); // Assign MethodInfo object directly
*data += entry.mi.GetSizeOfReadMethodInfo();

MetadataEntry ReadInstanceMethodEntry(uint8_t** data);
return entry;
}

inline static MetadataEntry ReadStaticMethodEntry(uint8_t **data) {
MetadataEntry entry(nullptr, NodeType::Method);
entry.isTypeMember = true;

entry.mi = MethodInfo(*data); // Assign MethodInfo object directly
entry.mi.isStatic = true;
entry.isStatic = true;

*data += entry.mi.GetSizeOfReadMethodInfo();

return entry;
}

MetadataEntry ReadStaticMethodEntry(uint8_t** data);
inline static MetadataEntry ReadExtensionFunctionEntry(uint8_t **data) {
MetadataEntry entry(nullptr, NodeType::Method);

MetadataEntry ReadExtensionFunctionEntry(uint8_t** data);
entry.mi = MethodInfo(*data); // Assign MethodInfo object directly
entry.mi.isStatic = true;
entry.isExtensionFunction = true;
entry.isStatic = true;

MetadataEntry ReadInstanceFieldEntry(uint8_t** data);
*data += entry.mi.GetSizeOfReadMethodInfo();

MetadataEntry ReadStaticFieldEntry(uint8_t** data);
return entry;
}

inline std::string ReadTypeName(uint16_t nodeId){
MetadataTreeNode* treeNode = GetNodeById(nodeId);
inline std::string ReadTypeName(uint16_t nodeId) {
MetadataTreeNode *treeNode = GetNodeById(nodeId);

return ReadTypeName(treeNode);
}
return ReadTypeName(treeNode);
}

std::string ReadTypeName(MetadataTreeNode* treeNode);
std::string ReadTypeName(MetadataTreeNode *treeNode);

inline std::string ReadName(uint32_t offset) {
uint16_t length = *reinterpret_cast<short*>(m_nameData + offset);
inline std::string ReadName(uint32_t offset) {
uint16_t length = *reinterpret_cast<short *>(m_nameData + offset);

std::string name(reinterpret_cast<char*>(m_nameData + offset + sizeof(uint16_t)), length);
std::string name(reinterpret_cast<char *>(m_nameData + offset + sizeof(uint16_t)),
length);

return name;
}
return name;
}

inline std::string ReadInterfaceImplementationTypeName(MetadataTreeNode* treeNode, bool& isPrefix) {
uint8_t* data = m_valueData + treeNode->offsetValue + sizeof(uint8_t) + sizeof(uint16_t);
inline std::string
ReadInterfaceImplementationTypeName(MetadataTreeNode *treeNode, bool &isPrefix) {
uint8_t *data =
m_valueData + treeNode->offsetValue + sizeof(uint8_t) + sizeof(uint16_t);

isPrefix = *data == 1;
isPrefix = *data == 1;

uint32_t pos = *reinterpret_cast<uint32_t*>(data + sizeof(uint8_t));
uint32_t pos = *reinterpret_cast<uint32_t *>(data + sizeof(uint8_t));

uint16_t len = *reinterpret_cast<uint16_t*>(m_nameData + pos);
uint16_t len = *reinterpret_cast<uint16_t *>(m_nameData + pos);

char* ptr = reinterpret_cast<char*>(m_nameData + pos + sizeof(uint16_t));
char *ptr = reinterpret_cast<char *>(m_nameData + pos + sizeof(uint16_t));

std::string name(ptr, len);
std::string name(ptr, len);

assert(name.length() == len);
assert(name.length() == len);

return name;
}
return name;
}

uint8_t* GetValueData() const;
uint8_t *GetValueData() const;

uint8_t GetNodeType(MetadataTreeNode* treeNode);
uint8_t GetNodeType(MetadataTreeNode *treeNode);

uint16_t GetNodeId(MetadataTreeNode* treeNode);
uint16_t GetNodeId(MetadataTreeNode *treeNode);

MetadataTreeNode* GetRoot() const;
MetadataTreeNode *GetRoot() const;

MetadataTreeNode* GetOrCreateTreeNodeByName(const std::string& className);
MetadataTreeNode *GetOrCreateTreeNodeByName(const std::string &className);

MetadataTreeNode* GetBaseClassNode(MetadataTreeNode* treeNode);
MetadataTreeNode *GetBaseClassNode(MetadataTreeNode *treeNode);

MetadataTreeNode* GetNodeById(uint16_t nodeId);
MetadataTreeNode *GetNodeById(uint16_t nodeId);

inline bool IsNodeTypeArray(uint8_t type) {
bool isArray = (((type & MetadataTreeNode::PRIMITIVE) == 0)
&& ((type & MetadataTreeNode::ARRAY) == MetadataTreeNode::ARRAY));
bool isArray = (((type & MetadataTreeNode::PRIMITIVE) == 0) &&
((type & MetadataTreeNode::ARRAY) == MetadataTreeNode::ARRAY));

return isArray;
}
@@ -90,15 +143,16 @@ class MetadataReader {
}

inline bool IsNodeTypeClass(uint8_t type) {
bool isClass = (((type & MetadataTreeNode::PRIMITIVE) == 0)
&& ((type & MetadataTreeNode::CLASS) == MetadataTreeNode::CLASS));
bool isClass = (((type & MetadataTreeNode::PRIMITIVE) == 0) &&
((type & MetadataTreeNode::CLASS) == MetadataTreeNode::CLASS));

return isClass;
}

inline bool IsNodeTypeInterface(uint8_t type) {
bool isInterface = (((type & MetadataTreeNode::PRIMITIVE) == 0)
&& ((type & MetadataTreeNode::INTERFACE) == MetadataTreeNode::INTERFACE));
bool isInterface = (((type & MetadataTreeNode::PRIMITIVE) == 0) &&
((type & MetadataTreeNode::INTERFACE) ==
MetadataTreeNode::INTERFACE));

return isInterface;
}
@@ -109,18 +163,13 @@ class MetadataReader {
return isPackage;
}

inline static void FillReturnType(MetadataEntry& entry) {
entry.returnType = ParseReturnType(entry.sig);
entry.retType = GetReturnType(entry.returnType);
}

inline static std::string ParseReturnType(const std::string& signature) {
inline static std::string ParseReturnType(const std::string &signature) {
int idx = signature.find(')');
auto returnType = signature.substr(idx + 1);
return returnType;
}

inline static MethodReturnType GetReturnType(const std::string& returnType) {
inline static MethodReturnType GetReturnType(const std::string &returnType) {
MethodReturnType retType;
char retTypePrefix = returnType[0];
switch (retTypePrefix) {
@@ -155,8 +204,7 @@ class MetadataReader {
case 'L':
retType = (returnType == "Ljava/lang/String;")
? MethodReturnType::String
:
MethodReturnType::Object;
: MethodReturnType::Object;
break;
default:
assert(false);
@@ -169,26 +217,26 @@ class MetadataReader {

static const uint32_t ARRAY_OFFSET = INT32_MAX; // 2147483647

MetadataTreeNode* BuildTree();
MetadataTreeNode *BuildTree();

std::string ReadTypeNameInternal(MetadataTreeNode* treeNode);
std::string ReadTypeNameInternal(MetadataTreeNode *treeNode);

void FillEntryWithFiedldInfo(FieldInfo* fi, MetadataEntry& entry);
void FillEntryWithFiedldInfo(FieldInfo *fi, MetadataEntry &entry);

void FillEntryWithMethodInfo(MethodInfo& mi, MetadataEntry& entry);
void FillEntryWithMethodInfo(MethodInfo &mi, MetadataEntry &entry);

MetadataTreeNode* m_root;
MetadataTreeNode *m_root;
uint32_t m_nodesLength;
uint32_t m_nameLength;
uint32_t m_valueLength;
uint8_t* m_nodeData;
uint8_t* m_nameData;
uint8_t* m_valueData;
std::vector<MetadataTreeNode*> m_v;
uint8_t *m_nodeData;
uint8_t *m_nameData;
uint8_t *m_valueData;
std::vector<MetadataTreeNode *> m_v;
GetTypeMetadataCallback m_getTypeMetadataCallback;

robin_hood::unordered_map<MetadataTreeNode*, std::string> m_typeNameCache;
};
robin_hood::unordered_map<MetadataTreeNode *, std::string> m_typeNameCache;
};
}

#endif /* METADATAREADER_H_ */