Skip to content

Commit da1c15e

Browse files
authored
Fix extension functions collision (#1577)
* Fix extension functions collision * Add missing import
1 parent 831365d commit da1c15e

File tree

4 files changed

+99
-61
lines changed

4 files changed

+99
-61
lines changed

test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
import com.telerik.metadata.parsing.kotlin.extensions.bytecode.BytecodeExtensionFunctionsCollector;
1818
import com.telerik.metadata.parsing.kotlin.metadata.ClassMetadataParser;
1919
import com.telerik.metadata.parsing.kotlin.metadata.bytecode.BytecodeClassMetadataParser;
20-
import com.telerik.metadata.security.MetadataSecurityViolationException;
2120
import com.telerik.metadata.security.classes.SecuredClassRepository;
2221
import com.telerik.metadata.security.classes.SecuredNativeClassDescriptor;
2322
import com.telerik.metadata.storage.functions.FunctionsStorage;
2423
import com.telerik.metadata.storage.functions.extensions.ExtensionFunctionsStorage;
24+
import com.telerik.metadata.security.MetadataSecurityViolationException;
2525

2626
import java.io.File;
2727
import java.util.ArrayList;
@@ -188,31 +188,30 @@ private static void setNodeMembers(NativeClassDescriptor clazz, TreeNode node, T
188188
private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDescriptor clazz, NativeMethodDescriptor[] ownMethodDescriptors, NativeMethodDescriptor[] ownAndParentMethodDescriptors, Map<String, MethodInfo> existingNodeMethods, boolean hasClassMetadataInfo) throws Exception {
189189

190190

191-
for (NativeMethodDescriptor m : ownMethodDescriptors) {
192-
if (m.isSynthetic()) {
191+
for (NativeMethodDescriptor ownMethod : ownMethodDescriptors) {
192+
if (ownMethod.isSynthetic()) {
193193
continue;
194194
}
195195

196-
if (hasClassMetadataInfo && !m.getName().equals("<init>")) {
197-
MetadataInfoAnnotationDescriptor metadataInfo = m.getMetadataInfoAnnotation();
196+
if (hasClassMetadataInfo && !ownMethod.getName().equals("<init>")) {
197+
MetadataInfoAnnotationDescriptor metadataInfo = ownMethod.getMetadataInfoAnnotation();
198198
if ((metadataInfo != null) && metadataInfo.skip()) {
199199
continue;
200200
}
201201
}
202202

203-
if (m.isPublic() || m.isProtected()) {
204-
boolean isStatic = m.isStatic();
203+
if (ownMethod.isPublic() || ownMethod.isProtected()) {
204+
boolean isStatic = ownMethod.isStatic();
205+
206+
MethodInfo mi = new MethodInfo(ownMethod);
205207

206-
MethodInfo mi = new MethodInfo(m);
207208
int countUnique = 0;
208-
for (NativeMethodDescriptor m1 : ownAndParentMethodDescriptors) {
209-
boolean m1IsStatic = m1.isStatic();
210-
if (!m1.isSynthetic()
211-
&& (m1.isPublic() || m1.isProtected())
209+
for (NativeMethodDescriptor ownOrParentMethod : ownAndParentMethodDescriptors) {
210+
boolean m1IsStatic = ownOrParentMethod.isStatic();
211+
if (!ownOrParentMethod.isSynthetic()
212+
&& (ownOrParentMethod.isPublic() || ownOrParentMethod.isProtected())
212213
&& (isStatic == m1IsStatic)
213-
&& (m1.getName().equals(mi.name) && (m1
214-
.getArgumentTypes().length == m
215-
.getArgumentTypes().length))) {
214+
&& (ownOrParentMethod.getName().equals(mi.name) && (ownOrParentMethod.getArgumentTypes().length == ownMethod.getArgumentTypes().length))) {
216215
if (++countUnique > 1) {
217216
break;
218217
}
@@ -221,8 +220,8 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDesc
221220
mi.isResolved = countUnique == 1;
222221

223222

224-
NativeTypeDescriptor[] params = m.getArgumentTypes();
225-
mi.signature = getMethodSignature(root, m.getReturnType(),
223+
NativeTypeDescriptor[] params = ownMethod.getArgumentTypes();
224+
mi.signature = getMethodSignature(root, ownMethod.getReturnType(),
226225
params);
227226

228227
if (mi.signature != null) {
@@ -231,11 +230,11 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDesc
231230
mi.declaringType = getOrCreateNode(root, clazz, null);
232231
node.staticMethods.add(mi);
233232
} else {
234-
mi.declaringType = getOrCreateNode(root, m.getDeclaringClass(), null);
233+
mi.declaringType = getOrCreateNode(root, ownMethod.getDeclaringClass(), null);
235234
node.addExtensionFunction(mi);
236235
}
237236
} else {
238-
String sig = m.getName() + m.getSignature();
237+
String sig = ownMethod.getName() + ownMethod.getSignature();
239238
if (existingNodeMethods.containsKey(sig)) {
240239
continue;
241240
}

test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Writer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,6 @@ public void writeClassValue(StreamWriter writer,
114114
writeInt(commonInterfacePrefixPosition, writer);
115115
}
116116

117-
int len = writeLength(n.instanceMethods.size(), writer);
118-
for (int i = 0; i < len; i++) {
119-
writeMethodInfo(n.instanceMethods.get(i), stringsMap, writer);
120-
}
121-
122117
List<MethodInfo> extensionFunctions = n.getExtensionFunctions();
123118

124119
writeLength(extensionFunctions.size(), writer);
@@ -127,6 +122,11 @@ public void writeClassValue(StreamWriter writer,
127122
writeTreeNodeId(extensionFunction.declaringType, writer);
128123
}
129124

125+
int len = writeLength(n.instanceMethods.size(), writer);
126+
for (int i = 0; i < len; i++) {
127+
writeMethodInfo(n.instanceMethods.get(i), stringsMap, writer);
128+
}
129+
130130
len = writeLength(n.instanceFields.size(), writer);
131131
for (int i = 0; i < len; i++) {
132132
FieldInfo fi = n.instanceFields.get(i);

test-app/runtime/src/main/cpp/MetadataNode.cpp

Lines changed: 75 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,17 @@ std::vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMembers(
488488
}
489489
}
490490

491-
vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMethodsFromStaticMetadata(Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode) {
491+
vector<MetadataNode::MethodCallbackData *> MetadataNode::SetInstanceMethodsFromStaticMetadata(Isolate *isolate,
492+
Local<FunctionTemplate> &ctorFuncTemplate,
493+
Local<ObjectTemplate> &prototypeTemplate,
494+
vector<MethodCallbackData *> &instanceMethodsCallbackData,
495+
const vector<MethodCallbackData *> &baseInstanceMethodsCallbackData,
496+
MetadataTreeNode *treeNode) {
492497
SET_PROFILER_FRAME();
493498

494-
std::vector<MethodCallbackData*> instanceMethodData;
499+
std::vector<MethodCallbackData *> instanceMethodData;
495500

496-
uint8_t* curPtr = s_metadataReader.GetValueData() + treeNode->offsetValue + 1;
501+
uint8_t *curPtr = s_metadataReader.GetValueData() + treeNode->offsetValue + 1;
497502

498503
auto nodeType = s_metadataReader.GetNodeType(treeNode);
499504

@@ -505,27 +510,55 @@ vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMethodsFromSt
505510
curPtr += sizeof(uint8_t) + sizeof(uint32_t);
506511
}
507512

508-
//get candidates from instance methods metadata
509-
auto instanceMethodCount = *reinterpret_cast<uint16_t*>(curPtr);
510-
curPtr += sizeof(uint16_t);
511513
string lastMethodName;
512-
MethodCallbackData* callbackData = nullptr;
514+
MethodCallbackData *callbackData = nullptr;
513515

514516
auto context = isolate->GetCurrentContext();
515-
516517
auto origin = Constants::APP_ROOT_FOLDER_PATH + GetOrCreateInternal(treeNode)->m_name;
518+
519+
std::unordered_map<std::string, MethodCallbackData *> collectedExtensionMethodDatas;
520+
521+
auto extensionFunctionsCount = *reinterpret_cast<uint16_t *>(curPtr);
522+
curPtr += sizeof(uint16_t);
523+
for (auto i = 0; i < extensionFunctionsCount; i++) {
524+
auto entry = s_metadataReader.ReadExtensionFunctionEntry(&curPtr);
525+
526+
if (entry.name != lastMethodName) {
527+
callbackData = new MethodCallbackData(this);
528+
auto funcData = External::New(isolate, callbackData);
529+
auto funcTemplate = FunctionTemplate::New(isolate, MethodCallback, funcData);
530+
auto funcName = ArgConverter::ConvertToV8String(isolate, entry.name);
531+
prototypeTemplate->Set(funcName, funcTemplate);
532+
533+
lastMethodName = entry.name;
534+
std::pair<std::string, MethodCallbackData *> p(entry.name, callbackData);
535+
collectedExtensionMethodDatas.insert(p);
536+
}
537+
callbackData->candidates.push_back(entry);
538+
}
539+
540+
541+
//get candidates from instance methods metadata
542+
auto instanceMethodCount = *reinterpret_cast<uint16_t *>(curPtr);
543+
curPtr += sizeof(uint16_t);
544+
517545
for (auto i = 0; i < instanceMethodCount; i++) {
518546
auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr);
519547

520548
// attach a function to the prototype of a javascript Object
521549
if (entry.name != lastMethodName) {
522-
callbackData = new MethodCallbackData(this);
550+
callbackData = tryGetExtensionMethodCallbackData(collectedExtensionMethodDatas,
551+
entry.name);
552+
if (callbackData == nullptr) {
553+
callbackData = new MethodCallbackData(this);
554+
}
555+
523556
instanceMethodData.push_back(callbackData);
524557

525558
instanceMethodsCallbackData.push_back(callbackData);
526559
auto itBegin = baseInstanceMethodsCallbackData.begin();
527560
auto itEnd = baseInstanceMethodsCallbackData.end();
528-
auto itFound = find_if(itBegin, itEnd, [&entry] (MethodCallbackData *x) {
561+
auto itFound = find_if(itBegin, itEnd, [&entry](MethodCallbackData *x) {
529562
return x->candidates.front().name == entry.name;
530563
});
531564
if (itFound != itEnd) {
@@ -539,10 +572,13 @@ vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMethodsFromSt
539572

540573
if (s_profilerEnabled) {
541574
auto func = funcTemplate->GetFunction(context).ToLocalChecked();
542-
Local<Function> wrapperFunc = Wrap(isolate, func, entry.name, origin, false /* isCtorFunc */);
575+
Local<Function> wrapperFunc = Wrap(isolate, func, entry.name, origin,
576+
false /* isCtorFunc */);
543577
Local<Function> ctorFunc = ctorFuncTemplate->GetFunction(context).ToLocalChecked();
544578
Local<Value> protoVal;
545-
ctorFunc->Get(context, ArgConverter::ConvertToV8String(isolate, "prototype")).ToLocal(&protoVal);
579+
ctorFunc->Get(context,
580+
ArgConverter::ConvertToV8String(isolate, "prototype")).ToLocal(
581+
&protoVal);
546582
if (!protoVal.IsEmpty() && !protoVal->IsUndefined() && !protoVal->IsNull()) {
547583
protoVal.As<Object>()->Set(context, funcName, wrapperFunc);
548584
}
@@ -556,23 +592,24 @@ vector<MetadataNode::MethodCallbackData*> MetadataNode::SetInstanceMethodsFromSt
556592
callbackData->candidates.push_back(entry);
557593
}
558594

559-
auto extensionFunctionsCount = *reinterpret_cast<uint16_t*>(curPtr);
560-
curPtr += sizeof(uint16_t);
561-
for (auto i = 0; i < extensionFunctionsCount; i++) {
562-
auto entry = s_metadataReader.ReadExtensionFunctionEntry(&curPtr);
563-
if (entry.name != lastMethodName) {
564-
callbackData = new MethodCallbackData(this);
565-
auto funcData = External::New(isolate, callbackData);
566-
auto funcTemplate = FunctionTemplate::New(isolate, MethodCallback, funcData);
567-
auto funcName = ArgConverter::ConvertToV8String(isolate, entry.name);
568-
prototypeTemplate->Set(funcName, funcTemplate);
595+
return instanceMethodData;
596+
}
569597

570-
lastMethodName = entry.name;
571-
}
572-
callbackData->candidates.push_back(entry);
598+
MetadataNode::MethodCallbackData *MetadataNode::tryGetExtensionMethodCallbackData(
599+
std::unordered_map<std::string, MethodCallbackData *> collectedMethodCallbackDatas,
600+
std::string lookupName) {
601+
602+
if (collectedMethodCallbackDatas.size() < 1) {
603+
return nullptr;
573604
}
574605

575-
return instanceMethodData;
606+
auto iter = collectedMethodCallbackDatas.find(lookupName);
607+
608+
if (iter != collectedMethodCallbackDatas.end()) {
609+
return iter->second;
610+
}
611+
612+
return nullptr;
576613
}
577614

578615
void MetadataNode::SetInstanceFieldsFromStaticMetadata(Isolate* isolate, Local<FunctionTemplate>& ctorFuncTemplate, Local<ObjectTemplate>& prototypeTemplate, vector<MethodCallbackData*>& instanceMethodsCallbackData, const vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode) {
@@ -592,6 +629,12 @@ void MetadataNode::SetInstanceFieldsFromStaticMetadata(Isolate* isolate, Local<F
592629
curPtr += sizeof(uint8_t) + sizeof(uint32_t);
593630
}
594631

632+
auto extensionFunctionsCount = *reinterpret_cast<uint16_t*>(curPtr);
633+
curPtr += sizeof(uint16_t);
634+
for (auto i = 0; i < extensionFunctionsCount; i++) {
635+
auto entry = s_metadataReader.ReadExtensionFunctionEntry(&curPtr);
636+
}
637+
595638
//get candidates from instance methods metadata
596639
auto instanceMethodCout = *reinterpret_cast<uint16_t*>(curPtr);
597640
curPtr += sizeof(uint16_t);
@@ -601,12 +644,6 @@ void MetadataNode::SetInstanceFieldsFromStaticMetadata(Isolate* isolate, Local<F
601644
auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr);
602645
}
603646

604-
auto extensionFunctionsCount = *reinterpret_cast<uint16_t*>(curPtr);
605-
curPtr += sizeof(uint16_t);
606-
for (auto i = 0; i < extensionFunctionsCount; i++) {
607-
auto entry = s_metadataReader.ReadExtensionFunctionEntry(&curPtr);
608-
}
609-
610647
//get candidates from instance fields metadata
611648
auto instanceFieldCout = *reinterpret_cast<uint16_t*>(curPtr);
612649
curPtr += sizeof(uint16_t);
@@ -733,18 +770,19 @@ void MetadataNode::SetStaticMembers(Isolate* isolate, Local<Function>& ctorFunct
733770
if (s_metadataReader.IsNodeTypeInterface(nodeType)) {
734771
curPtr += sizeof(uint8_t) + sizeof(uint32_t);
735772
}
736-
auto instanceMethodCout = *reinterpret_cast<uint16_t*>(curPtr);
737-
curPtr += sizeof(uint16_t);
738-
for (auto i = 0; i < instanceMethodCout; i++) {
739-
auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr);
740-
}
741773

742774
auto extensionFunctionsCount = *reinterpret_cast<uint16_t*>(curPtr);
743775
curPtr += sizeof(uint16_t);
744776
for (auto i = 0; i < extensionFunctionsCount; i++) {
745777
auto entry = s_metadataReader.ReadExtensionFunctionEntry(&curPtr);
746778
}
747779

780+
auto instanceMethodCout = *reinterpret_cast<uint16_t*>(curPtr);
781+
curPtr += sizeof(uint16_t);
782+
for (auto i = 0; i < instanceMethodCout; i++) {
783+
auto entry = s_metadataReader.ReadInstanceMethodEntry(&curPtr);
784+
}
785+
748786
auto instanceFieldCout = *reinterpret_cast<uint16_t*>(curPtr);
749787
curPtr += sizeof(uint16_t);
750788
for (auto i = 0; i < instanceFieldCout; i++) {

test-app/runtime/src/main/cpp/MetadataNode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class MetadataNode {
8282

8383
std::vector<MethodCallbackData*> SetInstanceMembers(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate, v8::Local<v8::ObjectTemplate>& prototypeTemplate, std::vector<MethodCallbackData*>& instanceMethodsCallbackData, const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode);
8484
std::vector<MethodCallbackData*> SetInstanceMethodsFromStaticMetadata(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate, v8::Local<v8::ObjectTemplate>& prototypeTemplate, std::vector<MethodCallbackData*>& instanceMethodsCallbackData, const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode);
85+
MethodCallbackData* tryGetExtensionMethodCallbackData(std::unordered_map<std::string, MethodCallbackData*> collectedMethodCallbackDatas, std::string lookupName);
8586
void SetInstanceFieldsFromStaticMetadata(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate, v8::Local<v8::ObjectTemplate>& prototypeTemplate, std::vector<MethodCallbackData*>& instanceMethodsCallbackData, const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode);
8687
std::vector<MethodCallbackData*> SetInstanceMembersFromRuntimeMetadata(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate>& ctorFuncTemplate, v8::Local<v8::ObjectTemplate>& prototypeTemplate, std::vector<MethodCallbackData*>& instanceMethodsCallbackData, const std::vector<MethodCallbackData*>& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode);
8788
void SetStaticMembers(v8::Isolate* isolate, v8::Local<v8::Function>& ctorFunction, MetadataTreeNode* treeNode);

0 commit comments

Comments
 (0)