From d7f3b92319117c4d60cce894f537514584df3822 Mon Sep 17 00:00:00 2001 From: rtrimana Date: Wed, 23 Nov 2016 15:21:44 -0800 Subject: [PATCH] Completing compiler with C++ struct support; need to clean up code! --- iotjava/iotpolicy/IoTCompiler.java | 788 ++++++++++++++++++++++++++--- 1 file changed, 706 insertions(+), 82 deletions(-) diff --git a/iotjava/iotpolicy/IoTCompiler.java b/iotjava/iotpolicy/IoTCompiler.java index 3908962..36ef1a8 100644 --- a/iotjava/iotpolicy/IoTCompiler.java +++ b/iotjava/iotpolicy/IoTCompiler.java @@ -752,7 +752,7 @@ public class IoTCompiler { List memTypes = structDecl.getMemberTypes(simpleType); List members = structDecl.getMembers(simpleType); if (isArrayOrList(retType, retType)) { // An array or list - println("for(int i = 0; i < retLen.length; i++) {"); + println("for(int i = 0; i < retLen; i++) {"); } if (isArray(retType)) { // An array for (int i = 0; i < members.size(); i++) { @@ -1425,9 +1425,9 @@ public class IoTCompiler { /** - * HELPER: writeLengthStructParamClassJavaSkeleton() writes lengths of params + * HELPER: writeLengthStructParamClassSkeleton() writes lengths of params */ - private void writeLengthStructParamClassJavaSkeleton(List methParams, List methPrmTypes, + private void writeLengthStructParamClassSkeleton(List methParams, List methPrmTypes, String method, InterfaceDecl intDecl) { // Iterate and find struct declarations - count number of params @@ -1504,7 +1504,7 @@ public class IoTCompiler { println("paramStruct" + i + "[i] = new " + simpleType + "();"); println("}"); } else if (isList(paramType)) { // A list - println("List<" + simpleType + "> structRet = new ArrayList<" + simpleType + ">();"); + println("List<" + simpleType + "> paramStruct" + i + " = new ArrayList<" + simpleType + ">();"); } else println(simpleType + " paramStruct" + i + " = new " + simpleType + "();"); println("int objPos = 0;"); @@ -1601,7 +1601,7 @@ public class IoTCompiler { boolean isCallbackMethod = false; String callbackType = null; print("int paramLen = "); - writeLengthStructParamClassJavaSkeleton(methParams, methPrmTypes, method, intDecl); + writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl); println(";"); println("Class[] paramCls = new Class[paramLen];"); println("Class[] paramClsGen = new Class[paramLen];"); @@ -1617,7 +1617,8 @@ public class IoTCompiler { if (callbackClasses.contains(prmType)) { isCallbackMethod = true; callbackType = prmType; - print("int.class"); + println("paramCls[pos] = int.class;"); + println("paramClsGen[pos++] = null;"); } else { // Generate normal classes if it's not a callback object String paramTypeOth = checkAndGetArray(methPrmTypes.get(i), methParams.get(i)); println("paramCls[pos] = " + getSimpleType(getEnumType(paramTypeOth)) + ".class;"); @@ -1800,7 +1801,6 @@ public class IoTCompiler { int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } - // TODO: Need to create comma separation } // Check if this is "void" if (retType.equals("void")) @@ -1896,9 +1896,9 @@ public class IoTCompiler { /** - * HELPER: writeCountVarStructJavaSkeleton() writes counter variable of struct for skeleton + * HELPER: writeCountVarStructSkeleton() writes counter variable of struct for skeleton */ - private void writeCountVarStructJavaSkeleton(Collection methods, InterfaceDecl intDecl) { + private void writeCountVarStructSkeleton(Collection methods, InterfaceDecl intDecl) { // Use this set to handle two same methodIds for (String method : methods) { @@ -1920,9 +1920,9 @@ public class IoTCompiler { /** - * HELPER: writeInputCountVarStructJavaSkeleton() writes counter variable of struct for skeleton + * HELPER: writeInputCountVarStructSkeleton() writes counter variable of struct for skeleton */ - private boolean writeInputCountVarStructJavaSkeleton(String method, InterfaceDecl intDecl) { + private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); @@ -1947,9 +1947,9 @@ public class IoTCompiler { /** - * HELPER: writeMethodCallStructJavaSkeleton() writes method call for wait invoke in skeleton + * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton */ - private void writeMethodCallStructJavaSkeleton(Collection methods, InterfaceDecl intDecl) { + private void writeMethodCallStructSkeleton(Collection methods, InterfaceDecl intDecl) { // Use this set to handle two same methodIds for (String method : methods) { @@ -1976,9 +1976,9 @@ public class IoTCompiler { /** - * HELPER: writeMethodCallStructJavaCallbackSkeleton() writes method call for wait invoke in skeleton + * HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton */ - private void writeMethodCallStructJavaCallbackSkeleton(Collection methods, InterfaceDecl intDecl) { + private void writeMethodCallStructCallbackSkeleton(Collection methods, InterfaceDecl intDecl) { // Use this set to handle two same methodIds for (String method : methods) { @@ -2035,7 +2035,7 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("private void ___waitRequestInvokeMethod() throws IOException {"); // Write variables here if we have callbacks or enums or structs - writeCountVarStructJavaSkeleton(methods, intDecl); + writeCountVarStructSkeleton(methods, intDecl); println("while (true) {"); println("rmiObj.getMethodBytes();"); println("int _objectId = rmiObj.getObjectId();"); @@ -2054,7 +2054,7 @@ public class IoTCompiler { else uniqueMethodIds.add(methodId); print(helperMethod + "("); - writeInputCountVarStructJavaSkeleton(method, intDecl); + writeInputCountVarStructSkeleton(method, intDecl); println("); break;"); } String method = "___initCallBack()"; @@ -2063,7 +2063,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(); break;"); } - writeMethodCallStructJavaSkeleton(methods, intDecl); + writeMethodCallStructSkeleton(methods, intDecl); println("default: "); println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");"); println("}"); @@ -2177,7 +2177,6 @@ public class IoTCompiler { int methodNumId = intDecl.getMethodNumId(method); print("int struct" + methodNumId + "Size" + i); } - // TODO: Need to create comma separation } // Check if this is "void" if (retType.equals("void")) @@ -2219,7 +2218,7 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("public void invokeMethod(IoTRMIObject rmiObj) throws IOException {"); // Write variables here if we have callbacks or enums or structs - writeCountVarStructJavaSkeleton(methods, intDecl); + writeCountVarStructSkeleton(methods, intDecl); // Write variables here if we have callbacks or enums or structs println("int methodId = rmiObj.getMethodId();"); // TODO: code the permission check here! @@ -2235,7 +2234,7 @@ public class IoTCompiler { else uniqueMethodIds.add(methodId); print(helperMethod + "("); - if (writeInputCountVarStructJavaSkeleton(method, intDecl)) + if (writeInputCountVarStructSkeleton(method, intDecl)) println(", rmiObj); break;"); else println("rmiObj); break;"); @@ -2246,7 +2245,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(rmiObj); break;"); } - writeMethodCallStructJavaCallbackSkeleton(methods, intDecl); + writeMethodCallStructCallbackSkeleton(methods, intDecl); println("default: "); println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");"); println("}"); @@ -2706,55 +2705,282 @@ public class IoTCompiler { } + /** + * HELPER: checkAndWriteStructSetupCplusStub() writes the struct type setup + */ + private void checkAndWriteStructSetupCplusStub(List methParams, List methPrmTypes, + InterfaceDecl intDecl, String method) { + + // Iterate and find struct declarations + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + // Check if this is enum type + println("int numParam" + i + " = 1;"); + int methodNumId = intDecl.getMethodNumId(method); + String helperMethod = methodNumId + "struct" + i; + println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";"); + println("string retTypeStruct" + i + " = \"void\";"); + println("string paramClsStruct" + i + "[] = { \"int\" };"); + print("int structLen" + i + " = "); + if (isArrayOrList(param, paramType)) { // An array + println(getSimpleArrayType(param) + ".size();"); + } else { // Just one element + println("1;"); + } + println("void* paramObjStruct" + i + "[] = { &structLen" + i + " };"); + println("void* retStructLen" + i + " = NULL;"); + println("rmiCall->remoteCall(objectId, methodIdStruct" + i + + ", retTypeStruct" + i + ", paramClsStruct" + i + ", paramObjStruct" + i + + ", numParam" + i + ", retStructLen" + i + ");\n"); + } + } + } + + + /** + * HELPER: writeLengthStructParamClassCplusStub() writes lengths of params + */ + private void writeLengthStructParamClassCplusStub(List methParams, List methPrmTypes) { + + // Iterate and find struct declarations - count number of params + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + int members = getNumOfMembers(simpleType); + if (isArrayOrList(param, paramType)) { // An array + String structLen = param + ".size()"; + print(members + "*" + structLen); + } else + print(Integer.toString(members)); + } else + print("1"); + if (i != methParams.size() - 1) { + print("+"); + } + } + } + + + /** + * HELPER: writeStructMembersCplusStub() writes parameters of struct + */ + private void writeStructMembersCplusStub(String simpleType, String paramType, String param) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + param + ".size(); i++) {"); + } + if (isArrayOrList(param, paramType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &" + param + "[i]."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &" + param + "."); + print(getSimpleIdentifier(members.get(i))); + println(";"); + } + } + } + + + /** + * HELPER: writeStructParamClassCplusStub() writes parameters if struct is present + */ + private void writeStructParamClassCplusStub(List methParams, List methPrmTypes) { + + print("int numParam = "); + writeLengthStructParamClassCplusStub(methParams, methPrmTypes); + println(";"); + println("void* paramObj[numParam];"); + println("string paramCls[numParam];"); + println("int pos = 0;"); + // Iterate again over the parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + writeStructMembersCplusStub(simpleType, paramType, param); + } else { + String prmTypeC = checkAndGetCplusType(methPrmTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, methParams.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("paramObj[pos++] = &"); + print(getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeStructRetMembersCplusStub() writes parameters of struct + */ + private void writeStructRetMembersCplusStub(String simpleType, String retType) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + } + if (isArrayOrList(retType, retType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + print("structRet[i]." + getSimpleIdentifier(members.get(i))); + println(" = retParam" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmType = checkAndGetArray(memTypes.get(i), members.get(i)); + print("structRet." + getSimpleIdentifier(members.get(i))); + println(" = retParam" + i + ";"); + } + } + println("return structRet;"); + } + + + /** + * HELPER: writeStructReturnCplusStub() writes parameters if struct is present + */ + private void writeStructReturnCplusStub(String simpleType, String retType) { + + // Minimum retLen is 1 if this is a single struct object + println("int retLen = 0;"); + println("void* retLenObj = { &retLen };"); + // Handle the returned struct!!! + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retLenObj);"); + int numMem = getNumOfMembers(simpleType); + println("int numRet = " + numMem + "*retLen;"); + println("string retCls[numRet];"); + println("void* retObj[numRet];"); + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + // Set up variables + if (isArrayOrList(retType, retType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " retParam" + i + "[retLen];"); + } + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " retParam" + i + ";"); + } + } + println("int retPos = 0;"); + // Get the struct declaration for this struct and generate initialization code + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("retObj[retPos++] = &retParam" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("retObj[retPos++] = &retParam" + i + ";"); + } + } + println("rmiCall->getStructObjects(retCls, numRet, retObj);"); + if (isArrayOrList(retType, retType)) { // An array or list + println("vector<" + simpleType + "> structRet(retLen);"); + } else + println(simpleType + " structRet;"); + writeStructRetMembersCplusStub(simpleType, retType); + } + + /** * HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class */ private void writeStdMethodBodyCplusStub(InterfaceDecl intDecl, List methParams, List methPrmTypes, String method) { - println("int numParam = " + methParams.size() + ";"); + checkAndWriteStructSetupCplusStub(methParams, methPrmTypes, intDecl, method); println("int methodId = " + intDecl.getMethodNumId(method) + ";"); String retType = intDecl.getMethodType(method); String retTypeC = checkAndGetCplusType(retType); - println("string retType = \"" + checkAndGetCplusArrayType(getEnumType(retTypeC)) + "\";"); + println("string retType = \"" + checkAndGetCplusArrayType(getStructType(getEnumType(retTypeC))) + "\";"); // Generate array of parameter types - print("string paramCls[] = { "); - for (int i = 0; i < methParams.size(); i++) { - String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); - String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); - print("\"" + getEnumType(paramType) + "\""); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + if (isStructPresent(methParams, methPrmTypes)) { + writeStructParamClassCplusStub(methParams, methPrmTypes); + } else { + println("int numParam = " + methParams.size() + ";"); + print("string paramCls[] = { "); + for (int i = 0; i < methParams.size(); i++) { + String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); + String paramType = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); + print("\"" + getEnumType(paramType) + "\""); + // Check if this is the last element (don't print a comma) + if (i != methParams.size() - 1) { + print(", "); + } } - } - println(" };"); - checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); - // Generate array of parameter objects - print("void* paramObj[] = { "); - for (int i = 0; i < methParams.size(); i++) { - print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); - // Check if this is the last element (don't print a comma) - if (i != methParams.size() - 1) { - print(", "); + println(" };"); + checkAndWriteEnumTypeCplusStub(methParams, methPrmTypes); + // Generate array of parameter objects + print("void* paramObj[] = { "); + for (int i = 0; i < methParams.size(); i++) { + print("&" + getEnumParam(methPrmTypes.get(i), getSimpleIdentifier(methParams.get(i)), i)); + // Check if this is the last element (don't print a comma) + if (i != methParams.size() - 1) { + print(", "); + } } + println(" };"); } - println(" };"); // Check if this is "void" if (retType.equals("void")) { println("void* retObj = NULL;"); println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); } else { // We do have a return value - if (getParamCategory(retType) == ParamCategory.ENUM) { - checkAndWriteEnumRetTypeCplusStub(retType); + // Generate array of parameter types + if (isStructClass(getGenericType(getSimpleArrayType(retType)))) { + writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType); } else { - if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) - println(checkAndGetCplusType(retType) + " retVal;"); - else - println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); - println("void* retObj = &retVal;"); - println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); - println("return retVal;"); + // Check if the return value NONPRIMITIVES + if (getParamCategory(retType) == ParamCategory.ENUM) { + checkAndWriteEnumRetTypeCplusStub(retType); + } else { + if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES) + println(checkAndGetCplusType(retType) + " retVal;"); + else + println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";"); + println("void* retObj = &retVal;"); + println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);"); + println("return retVal;"); + } } } } @@ -3428,6 +3654,8 @@ public class IoTCompiler { } else { // We do have a return value if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type print(checkAndGetCplusType(retType) + " retEnum = "); + else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + print(checkAndGetCplusType(retType) + " retStruct = "); else print(checkAndGetCplusType(retType) + " retVal = "); print(methodId + "("); @@ -3445,12 +3673,265 @@ public class IoTCompiler { } println(");"); checkAndWriteEnumRetTypeCplusSkeleton(retType); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type println("void* retObj = &retEnumInt;"); else - println("void* retObj = &retVal;"); + if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("void* retObj = &retVal;"); String retTypeC = checkAndGetCplusType(retType); - println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");"); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);"); + else + println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");"); + } + } + + + /** + * HELPER: writeStructMembersCplusSkeleton() writes parameters of struct + */ + private void writeStructMembersCplusSkeleton(String simpleType, String paramType, + String param, String method, InterfaceDecl intDecl, int iVar) { + + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + int methodNumId = intDecl.getMethodNumId(method); + String counter = "struct" + methodNumId + "Size" + iVar; + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + counter + "; i++) {"); + } + // Set up variables + if (isArrayOrList(param, paramType)) { // An array or list + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " param" + i + "[" + counter + "];"); + } + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println(getSimpleType(getEnumType(prmType)) + " param" + i + ";"); + } + } + println("int pos = 0;"); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("paramObj[pos++] = ¶m" + i + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String prmTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(prmTypeC, members.get(i)); + println("paramCls[pos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + println("paramObj[pos++] = ¶m" + i + ";"); + } + } + } + + + /** + * HELPER: writeStructMembersInitCplusSkeleton() writes parameters of struct + */ + private void writeStructMembersInitCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method) { + + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + String counter = "struct" + methodNumId + "Size" + i; + // Declaration + if (isArrayOrList(param, paramType)) { // An array or list + println("vector<" + simpleType + "> paramStruct" + i + ";"); + } else + println(simpleType + " paramStruct" + i + ";"); + // Initialize members + StructDecl structDecl = getStructDecl(simpleType); + List members = structDecl.getMembers(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + if (isArrayOrList(param, paramType)) { // An array or list + println("for(int i = 0; i < " + counter + "; i++) {"); + for (int j = 0; j < members.size(); j++) { + print("paramStruct" + i + "[i]." + getSimpleIdentifier(members.get(j))); + println(" = param" + j + "[i];"); + } + println("}"); + } else { // Just one struct element + for (int j = 0; j < members.size(); j++) { + print("paramStruct" + i + "." + getSimpleIdentifier(members.get(j))); + println(" = param" + j + ";"); + } + } + } + } + } + + + /** + * HELPER: writeStructReturnCplusSkeleton() writes parameters if struct is present + */ + private void writeStructReturnCplusSkeleton(String simpleType, String retType) { + + // Minimum retLen is 1 if this is a single struct object + if (isArrayOrList(retType, retType)) + println("int retLen = retStruct.size();"); + else // Just single struct object + println("int retLen = 1;"); + println("void* retLenObj = &retLen;"); + println("rmiObj->sendReturnObj(retLenObj, \"int\");"); + int numMem = getNumOfMembers(simpleType); + println("int numRetObj = " + numMem + "*retLen;"); + println("string retCls[numRetObj];"); + println("void* retObj[numRetObj];"); + println("int retPos = 0;"); + // Get the struct declaration for this struct and generate initialization code + StructDecl structDecl = getStructDecl(simpleType); + List memTypes = structDecl.getMemberTypes(simpleType); + List members = structDecl.getMembers(simpleType); + if (isArrayOrList(retType, retType)) { // An array or list + println("for(int i = 0; i < retLen; i++) {"); + for (int i = 0; i < members.size(); i++) { + String paramTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("retObj[retPos++] = &retStruct[i]."); + print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i)); + println(";"); + } + println("}"); + } else { // Just one struct element + for (int i = 0; i < members.size(); i++) { + String paramTypeC = checkAndGetCplusType(memTypes.get(i)); + String prmType = checkAndGetCplusArrayType(paramTypeC, members.get(i)); + println("retCls[retPos] = \"" + getSimpleType(getEnumType(prmType)) + "\";"); + print("retObj[retPos++] = &retStruct."); + print(getEnumParam(memTypes.get(i), getSimpleIdentifier(members.get(i)), i)); + println(";"); + } + } + + } + + + /** + * HELPER: writeMethodHelperStructCplusSkeleton() writes the struct in skeleton + */ + private void writeMethodHelperStructCplusSkeleton(InterfaceDecl intDecl, List methParams, + List methPrmTypes, String method, String methodId, Set callbackClasses) { + + // Generate array of parameter objects + boolean isCallbackMethod = false; + String callbackType = null; + print("int numParam = "); + writeLengthStructParamClassSkeleton(methParams, methPrmTypes, method, intDecl); + println(";"); + println("string paramCls[numParam];"); + println("void* paramObj[numParam];"); + // Iterate again over the parameters + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getGenericType(paramType); + if (isStructClass(simpleType)) { + writeStructMembersCplusSkeleton(simpleType, paramType, param, method, intDecl, i); + } else { + String prmType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(prmType)) { + isCallbackMethod = true; + callbackType = paramType; + writeCallbackCplusNumStubs(methParams, methPrmTypes, callbackType); + println("paramCls[pos] = \"int\";"); + println("paramObj[pos++] = &numStubs" + i + ";"); + } else { // Generate normal classes if it's not a callback object + String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i)); + String prmTypeC = checkAndGetCplusArrayType(paramTypeC, methParams.get(i)); + if (isEnumClass(getSimpleType(paramTypeC))) { // Check if this is enum type + println("vector paramEnumInt" + i + ";"); + } else { + String methParamComplete = checkAndGetCplusArray(paramTypeC, methParams.get(i)); + println(methParamComplete + ";"); + } + println("paramCls[pos] = \"" + getEnumType(prmTypeC) + "\";"); + if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + println("paramObj[pos++] = ¶mEnumInt" + i); + else + println("paramObj[pos++] = &" + getSimpleIdentifier(methParams.get(i)) + ";"); + } + } + } + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + if (isCallbackMethod) + writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType); + checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes); + writeStructMembersInitCplusSkeleton(intDecl, methParams, methPrmTypes, method); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + // Check if this is "void" + if (retType.equals("void")) { + print(methodId + "("); + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) + print("stub" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("paramEnum" + i); + else if (isStructClass(getSimpleType(paramType))) // Struct type + print("paramStruct" + i); + else + print(getSimpleIdentifier(methParams.get(i))); + if (i != methParams.size() - 1) { + print(", "); + } + } + println(");"); + } else { // We do have a return value + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + print(checkAndGetCplusType(retType) + " retEnum = "); + else if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + print(checkAndGetCplusType(retType) + " retStruct = "); + else + print(checkAndGetCplusType(retType) + " retVal = "); + print(methodId + "("); + for (int i = 0; i < methParams.size(); i++) { + String paramType = returnGenericCallbackType(methPrmTypes.get(i)); + if (callbackClasses.contains(paramType)) + print("stub" + i); + else if (isEnumClass(getSimpleType(paramType))) // Check if this is enum type + print("paramEnum" + i); + else if (isStructClass(getSimpleType(paramType))) // Struct type + print("paramStruct" + i); + else + print(getSimpleIdentifier(methParams.get(i))); + if (i != methParams.size() - 1) { + print(", "); + } + } + println(");"); + checkAndWriteEnumRetTypeCplusSkeleton(retType); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + writeStructReturnCplusSkeleton(getSimpleArrayType(getSimpleType(retType)), retType); + if (isEnumClass(getSimpleArrayType(getSimpleType(retType)))) // Enum type + println("void* retObj = &retEnumInt;"); + else + if (!isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("void* retObj = &retVal;"); + String retTypeC = checkAndGetCplusType(retType); + if (isStructClass(getSimpleArrayType(getSimpleType(retType)))) // Struct type + println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);"); + else + println("rmiObj->sendReturnObj(retObj, \"" + getEnumType(checkAndGetCplusArrayType(retTypeC)) + "\");"); } } @@ -3466,19 +3947,119 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - String methodId = intDecl.getMethodId(method); - print("void ___"); - String helperMethod = methodId; - if (uniqueMethodIds.contains(methodId)) - helperMethod = helperMethod + intDecl.getMethodNumId(method); - else - uniqueMethodIds.add(methodId); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - println(helperMethod + "() {"); - // Now, write the helper body of skeleton! - writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); - println("}\n"); + if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + String retType = intDecl.getMethodType(method); + print(helperMethod + "("); + boolean begin = true; + for (int i = 0; i < methParams.size(); i++) { // Print size variables + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + if (!begin) { // Generate comma for not the beginning variable + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("int struct" + methodNumId + "Size" + i); + } + } + println(") {"); + writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } else { + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + println(helperMethod + "() {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } + } + // Write method helper for structs + writeMethodHelperStructSetupCplusSkeleton(methods, intDecl); + } + + + /** + * HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of the struct in skeleton class + */ + private void writeMethodHelperStructSetupCplusSkeleton(Collection methods, + InterfaceDecl intDecl) { + + // Use this set to handle two same methodIds + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + // Check for params with structs + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("int ___"); + String helperMethod = methodNumId + "struct" + i; + println(helperMethod + "() {"); + // Now, write the helper body of skeleton! + println("string paramCls[] = { \"int\" };"); + println("int numParam = 1;"); + println("int param0 = 0;"); + println("void* paramObj[] = { ¶m0 };"); + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + println("return param0;"); + println("}\n"); + } + } + } + } + + + /** + * HELPER: writeMethodHelperStructSetupCplusCallbackSkeleton() writes the method helper of the struct in skeleton class + */ + private void writeMethodHelperStructSetupCplusCallbackSkeleton(Collection methods, + InterfaceDecl intDecl) { + + // Use this set to handle two same methodIds + for (String method : methods) { + + List methParams = intDecl.getMethodParams(method); + List methPrmTypes = intDecl.getMethodParamTypes(method); + // Check for params with structs + for (int i = 0; i < methParams.size(); i++) { + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + int methodNumId = intDecl.getMethodNumId(method); + print("int ___"); + String helperMethod = methodNumId + "struct" + i; + println(helperMethod + "(IoTRMIObject* rmiObj) {"); + // Now, write the helper body of skeleton! + println("string paramCls[] = { \"int\" };"); + println("int numParam = 1;"); + println("int param0 = 0;"); + println("void* paramObj[] = { ¶m0 };"); + println("rmiObj->getMethodParams(paramCls, numParam, paramObj);"); + println("return param0;"); + println("}\n"); + } + } } } @@ -3516,6 +4097,7 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("void ___waitRequestInvokeMethod() {"); // Write variables here if we have callbacks or enums or structs + writeCountVarStructSkeleton(methods, intDecl); println("while (true) {"); println("rmiObj->getMethodBytes();"); println("int _objectId = rmiObj->getObjectId();"); @@ -3533,7 +4115,9 @@ public class IoTCompiler { helperMethod = helperMethod + methodNumId; else uniqueMethodIds.add(methodId); - println(helperMethod + "(); break;"); + print(helperMethod + "("); + writeInputCountVarStructSkeleton(method, intDecl); + println("); break;"); } String method = "___initCallBack()"; // Print case -9999 (callback handler) if callback exists @@ -3541,6 +4125,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(); break;"); } + writeMethodCallStructSkeleton(methods, intDecl); println("default: "); println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;"); println("throw exception();"); @@ -3680,20 +4265,50 @@ public class IoTCompiler { List methParams = intDecl.getMethodParams(method); List methPrmTypes = intDecl.getMethodParamTypes(method); - String methodId = intDecl.getMethodId(method); - print("void ___"); - String helperMethod = methodId; - if (uniqueMethodIds.contains(methodId)) - helperMethod = helperMethod + intDecl.getMethodNumId(method); - else - uniqueMethodIds.add(methodId); - // Check if this is "void" - String retType = intDecl.getMethodType(method); - println(helperMethod + "(IoTRMIObject* rmiObj) {"); - // Now, write the helper body of skeleton! - writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); - println("}\n"); + if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + String retType = intDecl.getMethodType(method); + print(helperMethod + "("); + boolean begin = true; + for (int i = 0; i < methParams.size(); i++) { // Print size variables + String paramType = methPrmTypes.get(i); + String param = methParams.get(i); + String simpleType = getSimpleType(paramType); + if (isStructClass(simpleType)) { + if (!begin) { // Generate comma for not the beginning variable + print(", "); begin = false; + } + int methodNumId = intDecl.getMethodNumId(method); + print("int struct" + methodNumId + "Size" + i); + } + } + println(", IoTRMIObject* rmiObj) {"); + writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } else { + String methodId = intDecl.getMethodId(method); + print("void ___"); + String helperMethod = methodId; + if (uniqueMethodIds.contains(methodId)) + helperMethod = helperMethod + intDecl.getMethodNumId(method); + else + uniqueMethodIds.add(methodId); + // Check if this is "void" + String retType = intDecl.getMethodType(method); + println(helperMethod + "(IoTRMIObject* rmiObj) {"); + // Now, write the helper body of skeleton! + writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses); + println("}\n"); + } } + // Write method helper for structs + writeMethodHelperStructSetupCplusCallbackSkeleton(methods, intDecl); } @@ -3707,6 +4322,8 @@ public class IoTCompiler { Set uniqueMethodIds = new HashSet(); println("void invokeMethod(IoTRMIObject* rmiObj) {"); // Write variables here if we have callbacks or enums or structs + writeCountVarStructSkeleton(methods, intDecl); + // Write variables here if we have callbacks or enums or structs println("int methodId = rmiObj->getMethodId();"); // TODO: code the permission check here! println("switch (methodId) {"); @@ -3720,7 +4337,11 @@ public class IoTCompiler { helperMethod = helperMethod + methodNumId; else uniqueMethodIds.add(methodId); - println(helperMethod + "(rmiObj); break;"); + print(helperMethod + "("); + if (writeInputCountVarStructSkeleton(method, intDecl)) + println(", rmiObj); break;"); + else + println("rmiObj); break;"); } String method = "___initCallBack()"; // Print case -9999 (callback handler) if callback exists @@ -3728,6 +4349,7 @@ public class IoTCompiler { int methodId = intDecl.getHelperMethodNumId(method); println("case " + methodId + ": ___regCB(rmiObj); break;"); } + writeMethodCallStructCallbackSkeleton(methods, intDecl); println("default: "); println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;"); println("throw exception();"); @@ -4261,6 +4883,8 @@ public class IoTCompiler { } } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.ENUM) { includeClasses.add("\"" + simpleType + ".hpp\""); + } else if (getParamCategory(getSimpleArrayType(simpleType)) == ParamCategory.STRUCT) { + includeClasses.add("\"" + simpleType + ".hpp\""); } else if (param.contains("[]")) { // Check if this is array for C++; translate into vector includeClasses.add(""); -- 2.34.1