diff options
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/Slice/JavaUtil.cpp | 22 | ||||
-rw-r--r-- | cpp/src/Slice/JavaUtil.h | 9 | ||||
-rw-r--r-- | cpp/src/slice2java/Gen.cpp | 20 | ||||
-rw-r--r-- | cpp/src/slice2java/GenCompat.cpp | 20 |
4 files changed, 53 insertions, 18 deletions
diff --git a/cpp/src/Slice/JavaUtil.cpp b/cpp/src/Slice/JavaUtil.cpp index ad20211a1c7..9ad435fbae7 100644 --- a/cpp/src/Slice/JavaUtil.cpp +++ b/cpp/src/Slice/JavaUtil.cpp @@ -669,6 +669,28 @@ Slice::computeSerialVersionUUID(const ExceptionPtr& p) return hashCode; } +bool +Slice::isValidMethodParameterList(const DataMemberList& members, int additionalUnits) +{ + // The maximum length of a method parameter list is 255 units, including the implicit 'this' parameter. + // Each parameter is 1 unit, except for long and double parameters, which are 2 units. + // Start the length at 1 to account for the implicit 'this' parameter (plus any additional units). + int length = 1 + additionalUnits; + for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast((*p)->type()); + if(builtin && (builtin->kind() == Builtin::KindLong || builtin->kind() == Builtin::KindDouble)) + { + length += 2; + } + else + { + length++; + } + } + return length <= 255; +} + Slice::JavaOutput::JavaOutput() { } diff --git a/cpp/src/Slice/JavaUtil.h b/cpp/src/Slice/JavaUtil.h index 326d7adfa1a..d9c6e440d0c 100644 --- a/cpp/src/Slice/JavaUtil.h +++ b/cpp/src/Slice/JavaUtil.h @@ -29,6 +29,15 @@ computeSerialVersionUUID(const ExceptionPtr&); long computeSerialVersionUUID(const StructPtr&); +// +// Returns true if we can generate a method from the given data member list. A Java method +// can have a maximum of 255 parameters (including the implicit 'this') where each parameter +// is counted as 1 unit, except for long and double which are counted as 2 units. +// See https://docs.oracle.com/javase/specs/jvms/se20/html/jvms-4.html#jvms-4.3.3 +// +bool +isValidMethodParameterList(const DataMemberList&, int additionalUnits = 0); + class JavaOutput : public ::IceUtilInternal::Output { public: diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp index dbd2ddfd280..7cd4c75f268 100644 --- a/cpp/src/slice2java/Gen.cpp +++ b/cpp/src/slice2java/Gen.cpp @@ -2552,9 +2552,9 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(allDataMembers.size() < 255) + if(isValidMethodParameterList(allDataMembers)) { DataMemberList baseDataMembers; if(baseClass) @@ -2945,9 +2945,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) } // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(allDataMembers.size() < 255) + if(isValidMethodParameterList(allDataMembers)) { if(hasRequiredMembers && hasOptionalMembers) { @@ -3010,8 +3010,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) // // Create constructor that takes all data members plus a Throwable. + // Do this only when the parameter list is not too large. // - if(allDataMembers.size() < 254) + if(isValidMethodParameterList(allDataMembers, 1)) { const string causeParamName = getEscapedParamName(allDataMembers, "cause"); @@ -3090,9 +3091,10 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << eb; // - // Create constructor that takes all data members plus a Throwable + // Create constructor that takes all data members plus a Throwable. + // Do this only when the parameter list is not too large. // - if(allDataMembers.size() < 254) + if(isValidMethodParameterList(allDataMembers, 1)) { const string causeParamName = getEscapedParamName(allDataMembers, "cause"); @@ -3382,9 +3384,9 @@ Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p) out << eb; // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(members.size() < 255) + if(isValidMethodParameterList(members)) { vector<string> paramDecl; vector<string> paramNames; diff --git a/cpp/src/slice2java/GenCompat.cpp b/cpp/src/slice2java/GenCompat.cpp index b3f5504f741..eb76ecbe9cf 100644 --- a/cpp/src/slice2java/GenCompat.cpp +++ b/cpp/src/slice2java/GenCompat.cpp @@ -2945,9 +2945,9 @@ Slice::GenCompat::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) out << eb; // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(allDataMembers.size() < 255) + if(isValidMethodParameterList(members)) { DataMemberList baseDataMembers; if(baseClass) @@ -3255,9 +3255,9 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) } // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(allDataMembers.size() < 255) + if(isValidMethodParameterList(members)) { if(hasRequiredMembers && hasOptionalMembers) { @@ -3319,8 +3319,9 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) // // Create constructor that takes all data members plus a Throwable. + // Do this only when the parameter list is not too large. // - if(allDataMembers.size() < 254) + if(isValidMethodParameterList(allDataMembers, 1)) { const string causeParamName = getEscapedParamName(allDataMembers, "cause"); paramDecl.push_back("Throwable " + causeParamName); @@ -3397,9 +3398,10 @@ Slice::GenCompat::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out << eb; // - // Create constructor that takes all data members plus a Throwable + // Create constructor that takes all data members plus a Throwable. + // Do this only when the parameter list is not too large. // - if(allDataMembers.size() < 254) + if(isValidMethodParameterList(allDataMembers, 1)) { const string causeParamName = getEscapedParamName(allDataMembers, "cause"); paramDecl.push_back("Throwable " + causeParamName); @@ -3670,9 +3672,9 @@ Slice::GenCompat::TypesVisitor::visitStructEnd(const StructPtr& p) out << eb; // - // A method cannot have more than 255 parameters (including the implicit "this" argument). + // Generate constructor if the parameter list is not too large. // - if(members.size() < 255) + if(isValidMethodParameterList(members)) { vector<string> paramDecl; vector<string> paramNames; |