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

slice2java: fix constructor parameter count check #1540

Merged
merged 7 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions cpp/src/Slice/JavaUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
}
Expand Down
9 changes: 9 additions & 0 deletions cpp/src/Slice/JavaUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
externl marked this conversation as resolved.
Show resolved Hide resolved
externl marked this conversation as resolved.
Show resolved Hide resolved

class JavaOutput : public ::IceUtilInternal::Output
{
public:
Expand Down
20 changes: 11 additions & 9 deletions cpp/src/slice2java/Gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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;
Expand Down
20 changes: 11 additions & 9 deletions cpp/src/slice2java/GenCompat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down