private String subdir;
private Map<String,Integer> mapPortCount; // Counter for ports
private static int portCount = 0;
+ private String mainClass;
/**
pw = null;
dir = OUTPUT_DIRECTORY;
subdir = null;
+ mainClass = null;
}
// Map new interface method name to the original interface
// TODO: perhaps need to check in the future if we have more than 1 stub interface for one original interface
mapInt2NewIntName.put(origInt, strInt);
+ if (mainClass == null) // Take the first class as the main class (whichever is placed first in the order of compilation files)
+ mainClass = origInt;
}
// Map the map of interface-methods to the original interface
mapInt2NewInts.put(origInt, mapNewIntMethods);
private void checkAndWriteEnumRetTypeJavaStub(String retType, String method, InterfaceDecl intDecl) {
// Write the wait-for-return-value part
- writeWaitForReturnValue(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
// Strips off array "[]" for return type
String pureType = getSimpleArrayType(getGenericType(retType));
// Take the inner type of generic
int methodNumId = intDecl.getMethodNumId(method);
String helperMethod = methodNumId + "struct" + i;
println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
- println("Class<?> retTypeStruct" + i + " = void.class;");
println("Class<?>[] paramClsStruct" + i + " = new Class<?>[] { int.class };");
if (isArray(param)) { // An array
println("Object[] paramObjStruct" + i + " = new Object[] { " + getSimpleArrayType(param) + ".length };");
private void writeStructReturnJavaStub(String simpleType, String retType, String method, InterfaceDecl intDecl) {
// Handle the returned struct size
- writeWaitForReturnValue(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
// Minimum retLen is 1 if this is a single struct object
println("int retLen = (int) retObj;");
int numMem = getNumOfMembers(simpleType);
}
//println("Object[] retActualObj = rmiComm.getStructObjects(retCls, retClsVal);");
// Handle the actual returned struct
- writeWaitForReturnValue(method, intDecl, "Object[] retActualObj = rmiComm.getStructObjects(retCls, retClsVal);");
+ writeWaitForReturnValueJava(method, intDecl, "Object[] retActualObj = rmiComm.getStructObjects(retCls, retClsVal);");
if (isArray(retType)) { // An array
println(simpleType + "[] structRet = new " + simpleType + "[retLen];");
println("for(int i = 0; i < retLen; i++) {");
/**
- * HELPER: writeWaitForReturnValue() writes the synchronization part for return values
+ * HELPER: writeWaitForReturnValueJava() writes the synchronization part for return values
*/
- private void writeWaitForReturnValue(String method, InterfaceDecl intDecl, String getReturnValue) {
+ private void writeWaitForReturnValueJava(String method, InterfaceDecl intDecl, String getReturnValue) {
println("// Waiting for return value");
int methodNumId = intDecl.getMethodNumId(method);
// Check if the return value NONPRIMITIVES
String retGenValType = getGenericType(retType);
println("Class<?> retGenValType = " + retGenValType + ".class;");
- writeWaitForReturnValue(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, retGenValType);");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, retGenValType);");
println("return (" + retType + ")retObj;");
} else {
- writeWaitForReturnValue(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
+ writeWaitForReturnValueJava(method, intDecl, "Object retObj = rmiComm.getReturnValue(retType, null);");
println("return (" + retType + ")retObj;");
}
}
println("}");
println("};");
println("thread.start();");
- println("while(!skel0.didAlreadyInitWaitInvoke());");
+ println("while(!skel" + counter + ".didAlreadyInitWaitInvoke());");
println("}");
println("else");
println("{");
*/
private void writeMethodJavaStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
- boolean isDefined = false;
for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
//else
writeStdMethodBodyJavaStub(intDecl, methParams, methPrmTypes, method, callbackType);
println("}\n");
- // Write the init callback helper method
- if (isCallbackMethod && !isDefined) {
- //writeInitCallbackJavaStub(callbackType, intDecl, newStubClass);
- isDefined = true;
- }
}
}
private void writeMethodJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses,
boolean callbackSkeleton, String intface) {
- boolean isDefined = false;
for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
// Now, write the body of skeleton!
writeStdMethodBodyJavaSkeleton(methParams, methodId, intDecl.getMethodType(method));
println("}\n");
- if (isCallbackMethod && !isDefined) { // Make sure that this function is only defined once!
- //writeInitCallbackJavaSkeleton(callbackSkeleton, intface);
- isDefined = true;
- }
}
}
/**
* HELPER: writeCallbackInstantiationJavaStubGeneration() writes the instantiation of callback stubs
*/
- private void writeCallbackInstantiationJavaStubGeneration(int counter, String exchParamType) {
+ private void writeCallbackInstantiationJavaStubGeneration(String exchParamType) {
//println("int objIdRecv = (int[]) paramObj[0];");
println(exchParamType + " newStub = null;");
println("List<" + exchParamType + "> stub" + i + " = new ArrayList<" + exchParamType + ">();");
} else {
println("int objIdRecv = stubIdArray" + i + "[0];");
- writeCallbackInstantiationJavaStubGeneration(i, exchParamType);
+ writeCallbackInstantiationJavaStubGeneration(exchParamType);
}
}
// Generate a loop if needed
String exchParamType = checkAndGetParamClass(getGenericType(paramType));
if (isArray(param)) {
println("for (int i = 0; i < numStubs" + i + "; i++) {");
- println("int objIdRecv = stubIdArray" + i + "[numStubs" + i + "];");
- writeCallbackInstantiationJavaStubGeneration(i, exchParamType);
+ println("int objIdRecv = stubIdArray" + i + "[i];");
+ writeCallbackInstantiationJavaStubGeneration(exchParamType);
println("stub" + i + "[i] = newStub;");
println("}");
} else if (isList(paramType)) {
println("for (int i = 0; i < numStubs" + i + "; i++) {");
- println("int objIdRecv = stubIdArray" + i + "[numStubs" + i + "];");
- writeCallbackInstantiationJavaStubGeneration(i, exchParamType);
+ println("int objIdRecv = stubIdArray" + i + "[i];");
+ writeCallbackInstantiationJavaStubGeneration(exchParamType);
println("stub" + i + ".add(newStub);");
println("}");
} else
}
}
-
+
/**
- * HELPER: writeInputCountVarStructSkeleton() writes input counter variable of struct for skeleton
+ * HELPER: writeInputCountVarStructJavaSkeleton() writes input counter variable of struct for skeleton
*/
- private boolean writeInputCountVarStructSkeleton(String method, InterfaceDecl intDecl) {
+ private boolean writeInputCountVarStructJavaSkeleton(String method, InterfaceDecl intDecl) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
return structExist;
}
+
+ /**
+ * HELPER: writeInputCountVarStructCplusSkeleton() writes input counter variable of struct for skeleton
+ */
+ private boolean writeInputCountVarStructCplusSkeleton(String method, InterfaceDecl intDecl) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ boolean structExist = false;
+ boolean begin = true;
+ // 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ structExist = true;
+ if (!begin)
+ print(", ");
+ else
+ begin = false;
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("struct" + methodNumId + "Size" + i);
+ }
+ }
+ return structExist;
+ }
+
/**
- * HELPER: writeMethodCallStructSkeleton() writes method call for wait invoke in skeleton
+ * HELPER: writeMethodCallStructJavaSkeleton() writes method call for wait invoke in skeleton
*/
- private void writeMethodCallStructSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+ private void writeMethodCallStructJavaSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
// Use this set to handle two same methodIds
for (String method : methods) {
}
+ /**
+ * HELPER: writeMethodCallStructCplusSkeleton() writes method call for wait invoke in skeleton
+ */
+ private void writeMethodCallStructCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("case ");
+ String helperMethod = methodNumId + "struct" + i;
+ String tempVar = "struct" + methodNumId + "Size" + i;
+ print(intDecl.getHelperMethodNumId(helperMethod) + ": ");
+ print(tempVar + " = ___");
+ println(helperMethod + "(skel); break;");
+ }
+ }
+ }
+ }
+
+
/**
* HELPER: writeMethodCallStructCallbackSkeleton() writes method call for wait invoke in skeleton
*/
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
int newObjectId = getNewIntfaceObjectId(newIntface);
- println("if (_objectId == object" + newObjectId + "Id) {");
+ println("if (_objectId == objectId) {");
println("if (!set" + newObjectId + "Allowed.contains(methodId)) {");
println("throw new Error(\"Object with object Id: \" + _objectId + \" is not allowed to access method: \" + methodId);");
println("}");
else
uniqueMethodIds.add(methodId);
print(helperMethod + "(");
- writeInputCountVarStructSkeleton(method, intDecl);
+ writeInputCountVarStructJavaSkeleton(method, intDecl);
println(");");
println("}");
println("catch (Exception ex) {");
println("break;");
}
String method = "___initCallBack()";
- writeMethodCallStructSkeleton(methods, intDecl);
+ writeMethodCallStructJavaSkeleton(methods, intDecl);
println("default: ");
println("throw new Error(\"Method Id \" + methodId + \" not recognized!\");");
println("}");
}
-/*================
- * C++ generation
- *================/
+/*================================================================================
+ *
+ * C++ generation
+ *
+ *================================================================================/
/**
* HELPER: writeMethodCplusLocalInterface() writes the method of the local interface
Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
printIncludeStatements(includeClasses); println("");
println("using namespace std;\n");
- //writeStructCplus(structDecl);
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ if (!intface.equals(mainClass)) // Forward declare if not main class
+ writeMethodCplusInterfaceForwardDecl(methods, intDecl, callbackClasses, true);
println("class " + intface); println("{");
println("public:");
// Write methods
}
+ /**
+ * HELPER: writeMethodCplusInterfaceForwardDecl() writes the forward declaration of the interface
+ */
+ private void writeMethodCplusInterfaceForwardDecl(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, boolean needNewIntface) {
+
+ Set<String> isDefined = new HashSet<String>();
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ for (int i = 0; i < methParams.size(); i++) {
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ // Check if this has callback object
+ if (callbackClasses.contains(paramType)) {
+ if (!isDefined.contains(paramType)) {
+ if (needNewIntface)
+ println("class " + getStubInterface(paramType) + ";\n");
+ else
+ println("class " + paramType + ";\n");
+ isDefined.add(paramType);
+ }
+ }
+ }
+ }
+ }
+
+
/**
* generateCPlusInterfaces() generate stub interfaces based on the methods list in C++
* <p>
// Pass in set of methods and get import classes
Set<String> methods = intMeth.getValue();
Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, false);
- List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
- List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
- printIncludeStatements(allIncludeClasses); println("");
+ printIncludeStatements(includeClasses); println("");
println("using namespace std;\n");
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ writeMethodCplusInterfaceForwardDecl(methods, intDecl, callbackClasses, false);
println("class " + newIntface);
println("{");
println("public:");
}
+ /**
+ * HELPER: writeMethodDeclCplusStub() writes the method declarations of the stub
+ */
+ private void writeMethodDeclCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
+
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
+ intDecl.getMethodId(method) + "(");
+ boolean isCallbackMethod = false;
+ String callbackType = null;
+ for (int i = 0; i < methParams.size(); i++) {
+
+ String paramType = returnGenericCallbackType(methPrmTypes.get(i));
+ // Check if this has callback object
+ if (callbackClasses.contains(paramType)) {
+ isCallbackMethod = true;
+ callbackType = paramType;
+ // Even if there're 2 callback arguments, we expect them to be of the same interface
+ }
+ String methPrmType = checkAndGetCplusType(methPrmTypes.get(i));
+ String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+ print(methParamComplete);
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ }
+ }
+
+
/**
* HELPER: writeMethodCplusStub() writes the methods of the stub
*/
private void writeMethodCplusStub(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses, String newStubClass) {
- boolean isDefined = false;
for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
- print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " +
+ // Print the mutex lock first
+ int methodNumId = intDecl.getMethodNumId(method);
+ String mutexVar = "mtx" + newStubClass + "MethodExec" + methodNumId;
+ println("mutex " + mutexVar + ";");
+ print(checkAndGetCplusType(intDecl.getMethodType(method)) + " " + newStubClass + "::" +
intDecl.getMethodId(method) + "(");
boolean isCallbackMethod = false;
String callbackType = null;
}
}
println(") { ");
+ println("lock_guard<mutex> guard(" + mutexVar + ");");
if (isCallbackMethod)
writeCallbackMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType);
writeStdMethodBodyCplusStub(intDecl, methParams, methPrmTypes, method, callbackType, isCallbackMethod);
println("}\n");
- // Write the init callback helper method
- if (isCallbackMethod && !isDefined) {
- //writeInitCallbackCplusStub(callbackType, intDecl, newStubClass);
- //writeInitCallbackSendInfoCplusStub(intDecl);
- isDefined = true;
- }
+
}
}
+ /**
+ * HELPER: writeCallbackInstantiationMethodBodyCplusStub() writes the callback object instantiation in the method of the stub class
+ */
+ private void writeCallbackInstantiationMethodBodyCplusStub(String paramIdent, String callbackType, int counter) {
+
+ println("auto it = IoTRMIUtil::mapSkel->find(" + paramIdent + ");");
+ println("if (it == IoTRMIUtil::mapSkel->end()) {");
+ println("int newObjIdSent = rmiComm->getObjectIdCounter();");
+ println("objIdSent.push_back(newObjIdSent);");
+ println("rmiComm->decrementObjectIdCounter();");
+ println(callbackType + "_Skeleton* skel" + counter + " = new " + callbackType + "_Skeleton(" + paramIdent + ", rmiComm, newObjIdSent);");
+ println("vecCallbackObj.push_back(skel0);");
+ println("IoTRMIUtil::mapSkel->insert(make_pair(" + paramIdent + ", skel0));");
+ println("IoTRMIUtil::mapSkelId->insert(make_pair(" + paramIdent + ", newObjIdSent));");
+ println("thread th0 (&" + callbackType + "_Skeleton::___waitRequestInvokeMethod, std::ref(skel0), std::ref(skel0));");
+ println("th0.detach();");
+ println("while(!skel" + counter + "->didInitWaitInvoke());");
+ println("}");
+ println("else");
+ println("{");
+ println("auto itId = IoTRMIUtil::mapSkelId->find(" + paramIdent + ");");
+ println("objIdSent.push_back(itId->second);");
+ println("}");
+ }
+
+
/**
* HELPER: writeCallbackMethodBodyCplusStub() writes the callback method of the stub class
*/
// Check if this is single object, array, or list of objects
boolean isArrayOrList = false;
String callbackParam = null;
+ println("vector<int> objIdSent;");
for (int i = 0; i < methParams.size(); i++) {
String paramType = methPrmTypes.get(i);
if (checkCallbackType(paramType, callbackType)) { // Check if this has callback object
String param = methParams.get(i);
- if (isArrayOrList(paramType, param)) { // Generate loop
+ if (isArrayOrList(paramType, param)) { // Generate loop
println("for (" + getGenericType(paramType) + "* cb : " + getSimpleIdentifier(param) + ") {");
- println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(cb, callbackAddress, objIdCnt++);");
+ writeCallbackInstantiationMethodBodyCplusStub("cb", callbackType, i);
isArrayOrList = true;
callbackParam = getSimpleIdentifier(param);
- } else
- println(callbackType + "_CallbackSkeleton* skel" + i + " = new " + callbackType + "_CallbackSkeleton(" +
- getSimpleIdentifier(param) + ", callbackAddress, objIdCnt++);");
- println("vecCallbackObj.push_back(skel" + i + ");");
+ } else {
+ writeCallbackInstantiationMethodBodyCplusStub(getSimpleIdentifier(param), callbackType, i);
+ }
if (isArrayOrList)
println("}");
- print("int ___paramCB" + i + " = ");
- if (isArrayOrList)
- println(callbackParam + ".size();");
- else
- println("1;");
+ println("vector<int> ___paramCB" + i + " = objIdSent;");
}
}
}
/**
* HELPER: checkAndWriteEnumRetTypeCplusStub() writes the enum return type (convert from enum to int)
*/
- private void checkAndWriteEnumRetTypeCplusStub(String retType) {
+ private void checkAndWriteEnumRetTypeCplusStub(String retType, String method, InterfaceDecl intDecl) {
// Strips off array "[]" for return type
String pureType = getSimpleArrayType(getGenericType(retType));
// Check if this is enum type
println("vector<int> retEnumInt;");
println("void* retObj = &retEnumInt;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retObj);");
if (isArrayOrList(retType, retType)) { // An array or vector
println("int retLen = retEnumInt.size();");
println("vector<" + pureType + "> retVal(retLen);");
int methodNumId = intDecl.getMethodNumId(method);
String helperMethod = methodNumId + "struct" + i;
println("int methodIdStruct" + i + " = " + intDecl.getHelperMethodNumId(helperMethod) + ";");
- println("string retTypeStruct" + i + " = \"void\";");
+ //println("string retTypeStruct" + i + " = \"void\";");
println("string paramClsStruct" + i + "[] = { \"int\" };");
print("int structLen" + i + " = ");
if (isArrayOrList(paramType, param)) { // An array
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");
+ //println("void* retStructLen" + i + " = NULL;");
+ println("rmiComm->remoteCall(objectId, methodIdStruct" + i +
+ ", paramClsStruct" + i + ", paramObjStruct" + i +
+ ", numParam" + i + ");\n");
}
}
}
/**
* HELPER: writeStructReturnCplusStub() writes member parameters of struct for return statement
*/
- private void writeStructReturnCplusStub(String simpleType, String retType) {
+ private void writeStructReturnCplusStub(String simpleType, String retType, String method, InterfaceDecl intDecl) {
// 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);");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retLenObj);");
int numMem = getNumOfMembers(simpleType);
println("int numRet = " + numMem + "*retLen;");
println("string retCls[numRet];");
println("retObj[retPos++] = &retParam" + i + ";");
}
}
- println("rmiCall->getStructObjects(retCls, numRet, retObj);");
+ //println("rmiComm->getStructObjects(retCls, numRet, retObj);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getStructObjects(retCls, numRet, retObj);");
if (isArrayOrList(retType, retType)) { // An array or list
println("vector<" + simpleType + "> structRet(retLen);");
} else
}
+ /**
+ * HELPER: writeWaitForReturnValueCplus() writes the synchronization part for return values
+ */
+ private void writeWaitForReturnValueCplus(String method, InterfaceDecl intDecl, String getReturnValue) {
+
+ println("// Waiting for return value");
+ int methodNumId = intDecl.getMethodNumId(method);
+ println("while (!retValueReceived" + methodNumId + ");");
+ println(getReturnValue);
+ println("retValueReceived" + methodNumId + " = false;");
+ println("didGetReturnBytes.exchange(true);\n");
+ }
+
+
/**
* HELPER: writeStdMethodBodyCplusStub() writes the standard method body in the stub class
*/
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
if (checkCallbackType(paramType, callbackType)) {
- print("\"int\"");
+ print("\"int*\"");
} else {
String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
print("\"" + paramTypeC + "\"");
}
// Check if this is "void"
if (retType.equals("void")) {
- println("void* retObj = NULL;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
} else { // We do have a return value
// Generate array of parameter types
if (isStructClass(getGenericType(getSimpleArrayType(retType)))) {
- writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType);
+ writeStructReturnCplusStub(getGenericType(getSimpleArrayType(retType)), retType, method, intDecl);
} else {
// Check if the return value NONPRIMITIVES
if (isEnumClass(getSimpleArrayType(getGenericType(retType)))) {
- checkAndWriteEnumRetTypeCplusStub(retType);
+ checkAndWriteEnumRetTypeCplusStub(retType, method, intDecl);
} else {
//if (getParamCategory(retType) == ParamCategory.NONPRIMITIVES)
if (isArrayOrList(retType,retType))
println(checkAndGetCplusType(retType) + " retVal = " + generateCplusInitializer(retType) + ";");
}
println("void* retObj = &retVal;");
- println("rmiCall->remoteCall(objectId, methodId, retType, paramCls, paramObj, numParam, retObj);");
+ println("rmiComm->remoteCall(objectId, methodId, paramCls, paramObj, numParam);");
+ writeWaitForReturnValueCplus(method, intDecl, "rmiComm->getReturnValue(retType, retObj);");
println("return retVal;");
}
}
/**
- * HELPER: writePropertiesCplusStub() writes the properties of the stub class
+ * HELPER: writePropertiesCplusPermission() writes the properties of the stub class
*/
private void writePropertiesCplusPermission(String intface) {
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
int newObjectId = getNewIntfaceObjectId(newIntface);
- println("const static int object" + newObjectId + "Id = " + newObjectId + ";\t//" + newIntface);
+ println("int objectId = " + newObjectId + ";");
println("static set<int> set" + newObjectId + "Allowed;");
}
}
/**
* HELPER: writePropertiesCplusStub() writes the properties of the stub class
*/
- private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist, Set<String> callbackClasses) {
+ private void writePropertiesCplusStub(String intface, String newIntface, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
- println("IoTRMICall *rmiCall;");
- println("string callbackAddress;");
- println("vector<int> ports;\n");
+ println("IoTRMIComm *rmiComm;");
// Get the object Id
Integer objId = mapIntfaceObjId.get(intface);
- println("const static int objectId = " + objId + ";");
+ println("int objectId = " + objId + ";");
if (callbackExist) {
// We assume that each class only has one callback interface for now
Iterator it = callbackClasses.iterator();
String callbackType = (String) it.next();
println("// Callback properties");
- println("IoTRMIObject *rmiObj;");
println("vector<" + callbackType + "*> vecCallbackObj;");
- println("static int objIdCnt;");
- // Generate permission stuff for callback stubs
- writePropertiesCplusPermission(callbackType);
+ }
+ println("// Synchronization variables");
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("bool retValueReceived" + methodNumId + " = false;");
+ }
}
println("\n");
}
/**
* HELPER: writeConstructorCplusStub() writes the constructor of the stub class
*/
- private void writeConstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
+ private void writeConstructorCplusStub(String newStubClass, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
- println(newStubClass +
- "(int _port, const char* _skeletonAddress, string _callbackAddress, int _rev, bool* _bResult, vector<int> _ports) {");
- println("callbackAddress = _callbackAddress;");
- println("ports = _ports;");
- println("rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev, _bResult);");
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- DeclarationHandler decHandler = mapIntDeclHand.get(callbackType);
- InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(callbackType);
- //writeCplusInitCallbackPermission(callbackType, intDecl, callbackExist);
- //println("thread th1 (&" + newStubClass + "::___initCallBack, this);");
- //println("th1.detach();");
- //println("___regCB();");
+ println(newStubClass + "::" + newStubClass +
+ "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult) {");
+ println("rmiComm = new IoTRMICommClient(_portSend, _portRecv, _skeletonAddress, _rev, _bResult);");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm->registerStub(objectId, " + methodNumId + ", &retValueReceived" + methodNumId + ");");
+ }
+ }
+ println("IoTRMIUtil::mapStub->insert(make_pair(objectId, this));");
+ println("}\n");
+ }
+
+
+ /**
+ * HELPER: writeCallbackConstructorCplusStub() writes the callback constructor of the stub class
+ */
+ private void writeCallbackConstructorCplusStub(String newStubClass, boolean callbackExist,
+ Set<String> callbackClasses, Set<String> methods, InterfaceDecl intDecl) {
+
+ println(newStubClass + "::" + newStubClass + "(IoTRMIComm* _rmiComm, int _objectId) {");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
+ // Register the AtomicBoolean variables
+ for (String method : methods) {
+ // Generate AtomicBooleans for methods that have return values
+ String returnType = intDecl.getMethodType(method);
+ int methodNumId = intDecl.getMethodNumId(method);
+ if (!returnType.equals("void")) {
+ println("rmiComm->registerStub(objectId, " + methodNumId + ", &retValueReceived" + methodNumId + ");");
+ }
}
println("}\n");
}
*/
private void writeDeconstructorCplusStub(String newStubClass, boolean callbackExist, Set<String> callbackClasses) {
- println("~" + newStubClass + "() {");
- println("if (rmiCall != NULL) {");
- println("delete rmiCall;");
- println("rmiCall = NULL;");
+ println(newStubClass + "::~" + newStubClass + "() {");
+ println("if (rmiComm != NULL) {");
+ println("delete rmiComm;");
+ println("rmiComm = NULL;");
println("}");
if (callbackExist) {
// We assume that each class only has one callback interface for now
- println("if (rmiObj != NULL) {");
- println("delete rmiObj;");
- println("rmiObj = NULL;");
- println("}");
Iterator it = callbackClasses.iterator();
String callbackType = (String) it.next();
println("for(" + callbackType + "* cb : vecCallbackObj) {");
/**
- * generateCPlusStubClasses() generate stubs based on the methods list in C++
+ * generateCPlusStubClassesHpp() generate stubs based on the methods list in C++ (.hpp file)
*/
- public void generateCPlusStubClasses() throws IOException {
+ public void generateCPlusStubClassesHpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
boolean callbackExist = !callbackClasses.isEmpty();
- if (callbackExist) // Need thread library if this has callback
- println("#include <thread>");
+ println("#include <thread>");
+ println("#include <mutex>");
+ List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
+ printIncludeStatements(stdIncludeClasses); println("");
println("#include \"" + newIntface + ".hpp\""); println("");
println("using namespace std;"); println("");
println("class " + newStubClass + " : public " + newIntface); println("{");
println("private:\n");
- writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses);
+ writePropertiesCplusStub(intface, newIntface, callbackExist, callbackClasses, methods, intDecl);
println("public:\n");
// Add default constructor and destructor
- println(newStubClass + "() { }"); println("");
- writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses);
- writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
+ println(newStubClass + "();");
+ // Declarations
+ println(newStubClass + "(int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult);");
+ println(newStubClass + "(IoTRMIComm* _rmiComm, int _objectId);");
+ println("~" + newStubClass + "();");
// Write methods
- writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
+ writeMethodDeclCplusStub(methods, intDecl, callbackClasses, newStubClass);
print("}"); println(";");
- if (callbackExist) {
- Iterator it = callbackClasses.iterator();
- String callbackType = (String) it.next();
- // Generate permission stuff for callback stubs
- DeclarationHandler decHandlerCallback = mapIntDeclHand.get(callbackType);
- InterfaceDecl intDeclCallback = (InterfaceDecl) decHandlerCallback.getInterfaceDecl(callbackType);
- writePermissionInitializationCplus(callbackType, newStubClass, intDeclCallback);
- }
- writeObjectIdCountInitializationCplus(newStubClass, callbackExist);
println("#endif");
pw.close();
System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".hpp...");
}
+ /**
+ * writeStubExternalCFunctions() generate external functions for .so file
+ */
+ public void writeStubExternalCFunctions(String newStubClass) throws IOException {
+
+ println("extern \"C\" void* create" + newStubClass + "(void** params) {");
+ println("// Args: int _portSend, int _portRecv, const char* _skeletonAddress, int _rev, bool* _bResult");
+ println("return new " + newStubClass + "(*((int*) params[0]), *((int*) params[1]), ((string*) params[2])->c_str(), " +
+ "*((int*) params[3]), (bool*) params[4]);");
+ println("}\n");
+ println("extern \"C\" void destroy" + newStubClass + "(void* t) {");
+ println(newStubClass + "* obj = (" + newStubClass + "*) t;");
+ println("delete obj;");
+ println("}\n");
+ //println("extern \"C\" void init" + newStubClass + "(void* t) {");
+ //println(newStubClass + "* obj = (" + newStubClass + "*) t;");
+ //println("obj->init();");
+ //println("while(true);");
+ //println("}\n");
+ }
+
+
+ /**
+ * generateCPlusStubClassesCpp() generate stubs based on the methods list in C++ (.cpp file)
+ */
+ public void generateCPlusStubClassesCpp() throws IOException {
+
+ // Create a new directory
+ String path = createDirectories(dir, subdir);
+ for (String intface : mapIntfacePTH.keySet()) {
+
+ Map<String,Set<String>> mapNewIntMethods = mapInt2NewInts.get(intface);
+ for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
+ // Open a new file to write into
+ String newIntface = intMeth.getKey();
+ String newStubClass = newIntface + "_Stub";
+ FileWriter fw = new FileWriter(path + "/" + newStubClass + ".cpp");
+ pw = new PrintWriter(new BufferedWriter(fw));
+ // Write file headers
+ println("#include <iostream>");
+ // Find out if there are callback objects
+ Set<String> methods = intMeth.getValue();
+ DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+ InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ boolean callbackExist = !callbackClasses.isEmpty();
+ println("#include \"" + newStubClass + ".hpp\""); println("");
+ for(String str: callbackClasses) {
+ if (intface.equals(mainClass))
+ println("#include \"" + str + "_Skeleton.cpp\"\n");
+ else
+ println("#include \"" + str + "_Skeleton.hpp\"\n");
+ }
+ println("using namespace std;"); println("");
+ // Add default constructor and destructor
+ //println(newStubClass + "() { }"); println("");
+ writeConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
+ writeCallbackConstructorCplusStub(newStubClass, callbackExist, callbackClasses, methods, intDecl);
+ writeDeconstructorCplusStub(newStubClass, callbackExist, callbackClasses);
+ // Write methods
+ writeMethodCplusStub(methods, intDecl, callbackClasses, newStubClass);
+ // Write external functions for .so file
+ writeStubExternalCFunctions(newStubClass);
+ // TODO: Remove this later
+ if (intface.equals(mainClass)) {
+ println("int main() {");
+ println("return 0;");
+ println("}");
+ }
+ pw.close();
+ System.out.println("IoTCompiler: Generated stub class " + newStubClass + ".cpp...");
+ }
+ }
+ }
+
+
/**
* HELPER: writePropertiesCplusSkeleton() writes the properties of the skeleton class
*/
private void writePropertiesCplusSkeleton(String intface, boolean callbackExist, Set<String> callbackClasses) {
println(intface + " *mainObj;");
- println("vector<int> ports;");
- println("string callbackAddress;");
// Callback
if (callbackExist) {
Iterator it = callbackClasses.iterator();
String callbackType = (String) it.next();
String exchangeType = checkAndGetParamClass(callbackType);
println("// Callback properties");
- println("static int objIdCnt;");
println("vector<" + exchangeType + "*> vecCallbackObj;");
- println("IoTRMICall *rmiCall;");
}
- println("IoTRMIObject *rmiObj;\n");
+ println("IoTRMIComm *rmiComm;");
+ println("char* methodBytes;");
+ println("int methodLen;");
// Keep track of object Ids of all stubs registered to this interface
writePropertiesCplusPermission(intface);
+ println("// Synchronization variables");
+ println("bool methodReceived = false;");
+ println("bool didAlreadyInitWaitInvoke = false;");
println("\n");
}
*/
private void writeConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
- println(newSkelClass + "(" + intface + " *_mainObj, string _callbackAddress, int _port) {");
+ println(newSkelClass + "::" + newSkelClass + "(" + intface + " *_mainObj, int _portSend, int _portRecv) {");
println("bool _bResult = false;");
println("mainObj = _mainObj;");
- println("callbackAddress = _callbackAddress;");
- println("rmiObj = new IoTRMIObject(_port, &_bResult);");
- //writeCplusInitCallbackPermission(intface, intDecl, callbackExist);
+ println("rmiComm = new IoTRMICommServer(_portSend, _portRecv, &_bResult);");
+ println("IoTRMIUtil::mapSkel->insert(make_pair(_mainObj, this));");
+ println("IoTRMIUtil::mapSkelId->insert(make_pair(_mainObj, objectId));");
+ println("rmiComm->registerSkeleton(objectId, &methodReceived);");
+ writeStructPermissionCplusSkeleton(methods, intDecl, intface);
+ println("thread th1 (&" + newSkelClass + "::___waitRequestInvokeMethod, this, this);");
+ println("th1.join();");
+ println("}\n");
+ }
+
+
+ /**
+ * HELPER: writeCallbackConstructorCplusSkeleton() writes the callback constructor of the skeleton class
+ */
+ private void writeCallbackConstructorCplusSkeleton(String newSkelClass, String intface, boolean callbackExist, InterfaceDecl intDecl, Collection<String> methods) {
+
+ println(newSkelClass + "::" + newSkelClass + "(" + intface + " *_mainObj, IoTRMIComm *_rmiComm, int _objectId) {");
+ println("bool _bResult = false;");
+ println("mainObj = _mainObj;");
+ println("rmiComm = _rmiComm;");
+ println("objectId = _objectId;");
+ println("rmiComm->registerSkeleton(objectId, &methodReceived);");
writeStructPermissionCplusSkeleton(methods, intDecl, intface);
- println("___waitRequestInvokeMethod();");
println("}\n");
}
*/
private void writeDeconstructorCplusSkeleton(String newSkelClass, boolean callbackExist, Set<String> callbackClasses) {
- println("~" + newSkelClass + "() {");
- println("if (rmiObj != NULL) {");
- println("delete rmiObj;");
- println("rmiObj = NULL;");
+ println(newSkelClass + "::~" + newSkelClass + "() {");
+ println("if (rmiComm != NULL) {");
+ println("delete rmiComm;");
+ println("rmiComm = NULL;");
println("}");
if (callbackExist) {
// We assume that each class only has one callback interface for now
- println("if (rmiCall != NULL) {");
- println("delete rmiCall;");
- println("rmiCall = NULL;");
- println("}");
Iterator it = callbackClasses.iterator();
String callbackType = (String) it.next();
String exchangeType = checkAndGetParamClass(callbackType);
}
+ /**
+ * HELPER: writeMethodDeclCplusSkeleton() writes the method declaration of the skeleton class
+ */
+ private void writeMethodDeclCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
+ Set<String> callbackClasses) {
+
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ String methodId = intDecl.getMethodId(method);
+ String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
+ print(methodType + " " + methodId + "(");
+ boolean isCallbackMethod = false;
+ String callbackType = null;
+ for (int i = 0; i < methParams.size(); i++) {
+
+ String origParamType = methPrmTypes.get(i);
+ if (callbackClasses.contains(origParamType)) { // Check if this has callback object
+ isCallbackMethod = true;
+ callbackType = origParamType;
+ }
+ String paramType = checkAndGetParamClass(methPrmTypes.get(i));
+ String methPrmType = checkAndGetCplusType(paramType);
+ String methParamComplete = checkAndGetCplusArray(methPrmType, methParams.get(i));
+ print(methParamComplete);
+ // Check if this is the last element (don't print a comma)
+ if (i != methParams.size() - 1) {
+ print(", ");
+ }
+ }
+ println(");");
+ }
+ }
+
+
/**
* HELPER: writeMethodCplusSkeleton() writes the method of the skeleton class
*/
private void writeMethodCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
- Set<String> callbackClasses, boolean callbackSkeleton, String intface) {
+ Set<String> callbackClasses, boolean callbackSkeleton, String intface, String newSkelClass) {
- boolean isDefined = false;
for (String method : methods) {
List<String> methParams = intDecl.getMethodParams(method);
List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
String methodId = intDecl.getMethodId(method);
String methodType = checkAndGetCplusType(intDecl.getMethodType(method));
- print(methodType + " " + methodId + "(");
+ print(methodType + " " + newSkelClass + "::" + methodId + "(");
boolean isCallbackMethod = false;
String callbackType = null;
for (int i = 0; i < methParams.size(); i++) {
// Now, write the body of skeleton!
writeStdMethodBodyCplusSkeleton(methParams, methodId, intDecl.getMethodType(method));
println("}\n");
- if (isCallbackMethod && !isDefined) {
- //writeInitCallbackCplusSkeleton(callbackSkeleton, intface);
- isDefined = true;
- }
}
}
String param = methParams.get(i);
//if (callbackType.equals(paramType)) {
if (checkCallbackType(paramType, callbackType)) // Check if this has callback object
- println("int numStubs" + i + " = 0;");
+ //println("int numStubs" + i + " = 0;");
+ println("vector<int> numStubIdArray" + i + ";");
}
}
+ /**
+ * HELPER: writeCallbackInstantiationCplusStubGeneration() writes the instantiation of callback stubs
+ */
+ private void writeCallbackInstantiationCplusStubGeneration(String exchParamType) {
+
+ //println("int objIdRecv = (int[]) paramObj[0];");
+ println(exchParamType + "* newStub = NULL;");
+ println("auto it = IoTRMIUtil::mapStub->find(objIdRecv);");
+ println("if (it == IoTRMIUtil::mapStub->end()) {");
+ println("newStub = new " + exchParamType + "_Stub(rmiComm, objIdRecv);");
+ println("IoTRMIUtil::mapStub->insert(make_pair(objIdRecv, newStub));");
+ println("rmiComm->setObjectIdCounter(objIdRecv);");
+ println("rmiComm->decrementObjectIdCounter();");
+ println("skel->vecCallbackObj.push_back(newStub);");
+ println("}");
+ println("else {");
+ println("newStub = (" + exchParamType + "_Stub*) it->second;");
+ println("}");
+ }
+
+
/**
* HELPER: writeCallbackCplusStubGeneration() writes the callback stub generation part
*/
String exchParamType = checkAndGetParamClass(getGenericType(paramType));
if (isArrayOrList(paramType, param)) {
println("vector<" + exchParamType + "*> stub" + i + ";");
- println("for (int objId = 0; objId < numStubs" + i + "; objId++) {");
- println(exchParamType + "* cb" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
- println("stub" + i + ".push_back(cb" + i + ");");
- println("vecCallbackObj.push_back(cb" + i + ");");
- println("objIdCnt++;");
+ println("for (int i = 0; i < numStubIdArray" + i + ".size(); i++) {");
+ println("int objIdRecv = numStubIdArray" + i + "[i];");
+ writeCallbackInstantiationCplusStubGeneration(exchParamType);
+ println("stub" + i + ".push_back(newStub);");
println("}");
} else {
- println(exchParamType + "* stub" + i + " = new " + exchParamType + "_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);");
- println("vecCallbackObj.push_back(stub" + i + ");");
- println("objIdCnt++;");
+ println("int objIdRecv = numStubIdArray" + i + "[0];");
+ writeCallbackInstantiationCplusStubGeneration(exchParamType);
+ println(exchParamType + "* stub" + i + " = newStub;");
}
}
}
List<String> methPrmTypes, String method, boolean isCallbackMethod, String callbackType,
String methodId, Set<String> callbackClasses) {
- println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
if (isCallbackMethod)
writeCallbackCplusStubGeneration(methParams, methPrmTypes, callbackType);
checkAndWriteEnumTypeCplusSkeleton(methParams, methPrmTypes);
println("void* retObj = &retVal;");
String retTypeC = checkAndGetCplusType(retType);
if (isStructClass(getSimpleArrayType(getGenericType(retType)))) // Struct type
- println("rmiObj->sendReturnObj(retObj, retCls, numRetObj);");
+ println("rmiComm->sendReturnObj(retObj, retCls, numRetObj, localMethodBytes);");
else
- println("rmiObj->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\");");
+ println("rmiComm->sendReturnObj(retObj, \"" + checkAndGetCplusRetClsType(getEnumType(retType)) + "\", localMethodBytes);");
}
}
if (callbackClasses.contains(paramType)) {
isCallbackMethod = true;
callbackType = paramType;
- print("\"int\"");
+ print("\"int*\"");
} else { // Generate normal classes if it's not a callback object
String paramTypeC = checkAndGetCplusArgClsType(methPrmTypes.get(i), methParams.get(i));
print("\"" + paramTypeC + "\"");
for (int i = 0; i < methParams.size(); i++) {
String paramType = returnGenericCallbackType(methPrmTypes.get(i));
if (callbackClasses.contains(paramType))
- print("&numStubs" + i);
+ print("&numStubIdArray" + i);
else if (isEnumClass(getGenericType(paramType))) // Check if this is enum type
print("¶mEnumInt" + i);
else
else // Just single struct object
println("int retLen = 1;");
println("void* retLenObj = &retLen;");
- println("rmiObj->sendReturnObj(retLenObj, \"int\");");
+ println("rmiComm->sendReturnObj(retLenObj, \"int\", localMethodBytes);");
int numMem = getNumOfMembers(simpleType);
println("int numRetObj = " + numMem + "*retLen;");
println("string retCls[numRetObj];");
if (callbackClasses.contains(prmType)) {
isCallbackMethod = true;
callbackType = prmType;
- println("int numStubs" + i + " = 0;");
- println("paramCls[pos] = \"int\";");
- println("paramObj[pos++] = &numStubs" + i + ";");
+ //println("int numStubs" + i + " = 0;");
+ println("vector<int> numStubIdArray" + i + ";");
+ println("paramCls[pos] = \"int*\";");
+ println("paramObj[pos++] = &numStubIdArray" + i + ";");
} else { // Generate normal classes if it's not a callback object
String paramTypeC = checkAndGetCplusType(methPrmTypes.get(i));
if (isEnumClass(getGenericType(paramTypeC))) { // Check if this is enum type
/**
- * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
+ * HELPER: writeMethodHelperDeclCplusSkeleton() writes the method helper declarations of the skeleton class
*/
- private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl, Set<String> callbackClasses) {
+ private void writeMethodHelperDeclCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
+ Set<String> callbackClasses, String newSkelClass) {
// Use this set to handle two same methodIds
Set<String> uniqueMethodIds = new HashSet<String>();
print("int struct" + methodNumId + "Size" + i);
}
}
- println(") {");
+ println(", " + newSkelClass + "* skel);");
+ } 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 + "(" + newSkelClass + "* skel);");
+ }
+ }
+ // Write method helper for structs
+ writeMethodHelperStructDeclSetupCplusSkeleton(methods, intDecl, newSkelClass);
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperStructDeclSetupCplusSkeleton() writes the struct method helper declaration in skeleton class
+ */
+ private void writeMethodHelperStructDeclSetupCplusSkeleton(Collection<String> methods,
+ InterfaceDecl intDecl, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int ___");
+ String helperMethod = methodNumId + "struct" + i;
+ println(helperMethod + "(" + newSkelClass + "* skel);");
+ }
+ }
+ }
+ }
+
+
+ /**
+ * HELPER: writeMethodBytesCopy() writes the methodBytes copy part in C++ skeleton
+ */
+ private void writeMethodBytesCopy() {
+
+ println("char* localMethodBytes = new char[methodLen];");
+ println("memcpy(localMethodBytes, skel->methodBytes, methodLen);");
+ println("didGetMethodBytes.exchange(true);");
+ }
+
+
+ /**
+ * HELPER: writeMethodHelperCplusSkeleton() writes the method helper of the skeleton class
+ */
+ private void writeMethodHelperCplusSkeleton(Collection<String> methods, InterfaceDecl intDecl,
+ Set<String> callbackClasses, String newSkelClass) {
+
+ // Use this set to handle two same methodIds
+ Set<String> uniqueMethodIds = new HashSet<String>();
+ for (String method : methods) {
+
+ List<String> methParams = intDecl.getMethodParams(method);
+ List<String> methPrmTypes = intDecl.getMethodParamTypes(method);
+ if (isStructPresent(methParams, methPrmTypes)) { // Treat struct differently
+ String methodId = intDecl.getMethodId(method);
+ print("void " + newSkelClass + "::___");
+ 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 = getGenericType(paramType);
+ if (isStructClass(simpleType)) {
+ if (!begin) // Generate comma for not the beginning variable
+ print(", ");
+ else
+ begin = false;
+ int methodNumId = intDecl.getMethodNumId(method);
+ print("int struct" + methodNumId + "Size" + i);
+ }
+ }
+ println(", " + newSkelClass + "* skel) {");
+ writeMethodBytesCopy();
writeMethodHelperStructCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
+ println("delete[] localMethodBytes;");
println("}\n");
} else {
String methodId = intDecl.getMethodId(method);
- print("void ___");
+ print("void " + newSkelClass + "::___");
String helperMethod = methodId;
if (uniqueMethodIds.contains(methodId))
helperMethod = helperMethod + intDecl.getMethodNumId(method);
uniqueMethodIds.add(methodId);
// Check if this is "void"
String retType = intDecl.getMethodType(method);
- println(helperMethod + "() {");
+ println(helperMethod + "(" + newSkelClass + "* skel) {");
+ writeMethodBytesCopy();
// Now, write the helper body of skeleton!
writeStdMethodHelperBodyCplusSkeleton(intDecl, methParams, methPrmTypes, method, methodId, callbackClasses);
+ println("delete[] localMethodBytes;");
println("}\n");
}
}
// Write method helper for structs
- writeMethodHelperStructSetupCplusSkeleton(methods, intDecl);
+ writeMethodHelperStructSetupCplusSkeleton(methods, intDecl, newSkelClass);
}
* HELPER: writeMethodHelperStructSetupCplusSkeleton() writes the method helper of struct in skeleton class
*/
private void writeMethodHelperStructSetupCplusSkeleton(Collection<String> methods,
- InterfaceDecl intDecl) {
+ InterfaceDecl intDecl, String newSkelClass) {
// Use this set to handle two same methodIds
for (String method : methods) {
String simpleType = getGenericType(paramType);
if (isStructClass(simpleType)) {
int methodNumId = intDecl.getMethodNumId(method);
- print("int ___");
+ print("int " + newSkelClass + "::___");
String helperMethod = methodNumId + "struct" + i;
- println(helperMethod + "() {");
+ println(helperMethod + "(" + newSkelClass + "* skel) {");
// Now, write the helper body of skeleton!
+ writeMethodBytesCopy();
println("string paramCls[] = { \"int\" };");
println("int numParam = 1;");
println("int param0 = 0;");
println("void* paramObj[] = { ¶m0 };");
- println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
println("return param0;");
+ println("delete[] localMethodBytes;");
println("}\n");
}
}
println("int numParam = 1;");
println("int param0 = 0;");
println("void* paramObj[] = { ¶m0 };");
- println("rmiObj->getMethodParams(paramCls, numParam, paramObj);");
+ println("rmiComm->getMethodParams(paramCls, numParam, paramObj, localMethodBytes);");
println("return param0;");
println("}\n");
}
for (Map.Entry<String,Set<String>> intMeth : mapNewIntMethods.entrySet()) {
String newIntface = intMeth.getKey();
int newObjectId = getNewIntfaceObjectId(newIntface);
- println("if (_objectId == object" + newObjectId + "Id) {");
+ println("if (_objectId == objectId) {");
println("if (set" + newObjectId + "Allowed.find(methodId) == set" + newObjectId + "Allowed.end()) {");
println("cerr << \"Object with object Id: \" << _objectId << \" is not allowed to access method: \" << methodId << endl;");
println("return;");
println("}");
println("}");
println("else {");
- println("cerr << \"Object Id: \" << _objectId << \" not recognized!\" << endl;");
- println("return;");
+ println("continue;");
println("}");
}
}
/**
* HELPER: writeCplusWaitRequestInvokeMethod() writes the main loop of the skeleton class
*/
- private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl, boolean callbackExist, String intface) {
+ private void writeCplusWaitRequestInvokeMethod(Collection<String> methods, InterfaceDecl intDecl,
+ boolean callbackExist, String intface, String newSkelClass) {
// Use this set to handle two same methodIds
Set<String> uniqueMethodIds = new HashSet<String>();
- println("void ___waitRequestInvokeMethod() {");
+ println("void " + newSkelClass + "::___waitRequestInvokeMethod(" + newSkelClass + "* skel) {");
// Write variables here if we have callbacks or enums or structs
writeCountVarStructSkeleton(methods, intDecl);
+ println("skel->didAlreadyInitWaitInvoke = true;");
println("while (true) {");
- println("rmiObj->getMethodBytes();");
- println("int _objectId = rmiObj->getObjectId();");
- println("int methodId = rmiObj->getMethodId();");
+ println("if (!methodReceived) {");
+ println("continue;");
+ println("}");
+ println("skel->methodBytes = skel->rmiComm->getMethodBytes();");
+ println("skel->methodLen = skel->rmiComm->getMethodLength();");
+ println("methodReceived = false;");
+ println("int _objectId = skel->rmiComm->getObjectId(skel->methodBytes);");
+ println("int methodId = skel->rmiComm->getMethodId(skel->methodBytes);");
// Generate permission check
writeCplusMethodPermission(intface);
println("switch (methodId) {");
for (String method : methods) {
String methodId = intDecl.getMethodId(method);
int methodNumId = intDecl.getMethodNumId(method);
- print("case " + methodNumId + ": ___");
+ println("case " + methodNumId + ": {");
+ print("thread th" + methodNumId + " (&" + newSkelClass + "::___");
String helperMethod = methodId;
if (uniqueMethodIds.contains(methodId))
helperMethod = helperMethod + methodNumId;
else
uniqueMethodIds.add(methodId);
- print(helperMethod + "(");
- writeInputCountVarStructSkeleton(method, intDecl);
- println("); break;");
- }
- String method = "___initCallBack()";
- // Print case -9999 (callback handler) if callback exists
- if (callbackExist) {
- int methodId = intDecl.getHelperMethodNumId(method);
- println("case " + methodId + ": ___regCB(); break;");
+ print(helperMethod + ", std::ref(skel), ");
+ boolean structExists = writeInputCountVarStructCplusSkeleton(method, intDecl);
+ if (structExists)
+ print(", ");
+ println("skel);");
+ println("th" + methodNumId + ".detach(); break;");
+ println("}");
}
- writeMethodCallStructSkeleton(methods, intDecl);
+ writeMethodCallStructCplusSkeleton(methods, intDecl);
println("default: ");
println("cerr << \"Method Id \" << methodId << \" not recognized!\" << endl;");
- println("throw exception();");
+ println("return;");
println("}");
println("}");
println("}\n");
/**
- * generateCplusSkeletonClass() generate skeletons based on the methods list in C++
+ * generateCplusSkeletonClassHpp() generate skeletons based on the methods list in C++ (.hpp file)
*/
- public void generateCplusSkeletonClass() throws IOException {
+ public void generateCplusSkeletonClassHpp() throws IOException {
// Create a new directory
String path = createDirectories(dir, subdir);
DeclarationHandler decHandler = mapIntDeclHand.get(intface);
InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
List<String> methods = intDecl.getMethods();
- Set<String> includeClasses = getIncludeClasses(methods, intDecl, intface, true);
List<String> stdIncludeClasses = getStandardCplusIncludeClasses();
- List<String> allIncludeClasses = getAllLibClasses(stdIncludeClasses, includeClasses);
- printIncludeStatements(allIncludeClasses); println("");
+ printIncludeStatements(stdIncludeClasses); println("");
println("using namespace std;\n");
// Find out if there are callback objects
Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
// Write properties
writePropertiesCplusSkeleton(intface, callbackExist, callbackClasses);
println("public:\n");
+ // Write constructors
+ println(newSkelClass + "();");
+ println(newSkelClass + "(" + intface + "*_mainObj, int _portSend, int _portRecv);");
+ println(newSkelClass + "(" + intface + "*_mainObj, IoTRMIComm *rmiComm, int _objectId);");
+ // Write deconstructor
+ println("~" + newSkelClass + "();");
+ // Write method declarations
+ println("bool didInitWaitInvoke();");
+ writeMethodDeclCplusSkeleton(methods, intDecl, callbackClasses);
+ // Write method helper declarations
+ writeMethodHelperDeclCplusSkeleton(methods, intDecl, callbackClasses, newSkelClass);
+ // Write waitRequestInvokeMethod() declaration - main loop
+ println("void ___waitRequestInvokeMethod(" + newSkelClass + "* skel);");
+ println("};");
+ writePermissionInitializationCplus(intface, newSkelClass, intDecl);
+ println("#endif");
+ pw.close();
+ System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
+ }
+ }
+
+ /**
+ * HELPER: writeReturnDidAlreadyInitWaitInvoke() writes the function to return didAlreadyInitWaitInvoke
+ */
+ private void writeReturnDidAlreadyInitWaitInvoke(String newSkelClass) {
+
+ println("bool " + newSkelClass + "::didInitWaitInvoke() {");
+ println("return didAlreadyInitWaitInvoke;");
+ println("}\n");
+ }
+
+
+ /**
+ * writeSkelExternalCFunctions() generate external functions for .so file
+ */
+ public void writeSkelExternalCFunctions(String newSkelClass, String intface) throws IOException {
+
+ println("extern \"C\" void* create" + newSkelClass + "(void** params) {");
+ println("// Args: *_mainObj, int _portSend, int _portRecv");
+ println("return new " + newSkelClass + "((" + intface + "*) params[0], *((int*) params[0]), *((int*) params[1]));");
+ println("}\n");
+ println("extern \"C\" void destroy" + newSkelClass + "(void* t) {");
+ println(newSkelClass + "* obj = (" + newSkelClass + "*) t;");
+ println("delete obj;");
+ println("}\n");
+ //println("extern \"C\" void init" + newSkelClass + "(void* t) {");
+ //println(newSkelClass + "* obj = (" + newSkelClass + "*) t;");
+ //println("obj->init();");
+ //println("while(true);");
+ //println("}\n");
+ }
+
+
+ /**
+ * generateCplusSkeletonClassCpp() generate skeletons based on the methods list in C++ (.cpp file)
+ */
+ public void generateCplusSkeletonClassCpp() throws IOException {
+
+ // Create a new directory
+ String path = createDirectories(dir, subdir);
+ for (String intface : mapIntfacePTH.keySet()) {
+ // Open a new file to write into
+ String newSkelClass = intface + "_Skeleton";
+ FileWriter fw = new FileWriter(path + "/" + newSkelClass + ".cpp");
+ pw = new PrintWriter(new BufferedWriter(fw));
+ // Write file headers
+ println("#include <iostream>");
+ println("#include \"" + newSkelClass + ".hpp\"\n");
+ // Pass in set of methods and get import classes
+ DeclarationHandler decHandler = mapIntDeclHand.get(intface);
+ InterfaceDecl intDecl = (InterfaceDecl) decHandler.getInterfaceDecl(intface);
+ List<String> methods = intDecl.getMethods();
+ // Find out if there are callback objects
+ Set<String> callbackClasses = getCallbackClasses(methods, intDecl);
+ boolean callbackExist = !callbackClasses.isEmpty();
+ for(String str: callbackClasses) {
+ if (intface.equals(mainClass))
+ println("#include \"" + getStubInterface(str) + "_Stub.cpp\"\n");
+ else
+ println("#include \"" + getStubInterface(str) + "_Stub.hpp\"\n");
+ }
+ println("using namespace std;\n");
// Write constructor
writeConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
+ // Write callback constructor
+ writeCallbackConstructorCplusSkeleton(newSkelClass, intface, callbackExist, intDecl, methods);
// Write deconstructor
writeDeconstructorCplusSkeleton(newSkelClass, callbackExist, callbackClasses);
+ // Write didInitWaitInvoke() to return bool
+ writeReturnDidAlreadyInitWaitInvoke(newSkelClass);
// Write methods
- writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false, intface);
+ writeMethodCplusSkeleton(methods, intDecl, callbackClasses, false, intface, newSkelClass);
// Write method helper
- writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses);
+ writeMethodHelperCplusSkeleton(methods, intDecl, callbackClasses, newSkelClass);
// Write waitRequestInvokeMethod() - main loop
- writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface);
- println("};");
- writePermissionInitializationCplus(intface, newSkelClass, intDecl);
- writeObjectIdCountInitializationCplus(newSkelClass, callbackExist);
- println("#endif");
+ writeCplusWaitRequestInvokeMethod(methods, intDecl, callbackExist, intface, newSkelClass);
+ // Write external functions for .so file
+ writeSkelExternalCFunctions(newSkelClass, intface);
+ // TODO: Remove this later
+ if (intface.equals(mainClass)) {
+ println("int main() {");
+ println("return 0;");
+ println("}");
+ }
pw.close();
- System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".hpp...");
+ System.out.println("IoTCompiler: Generated skeleton class " + newSkelClass + ".cpp...");
}
}
// Add the standard list first
importClasses.add("<vector>");
importClasses.add("<set>");
- importClasses.add("\"IoTRMICall.hpp\"");
- importClasses.add("\"IoTRMIObject.hpp\"");
+ //importClasses.add("\"IoTRMICall.hpp\"");
+ //importClasses.add("\"IoTRMIObject.hpp\"");
+ importClasses.add("\"IoTRMIComm.hpp\"");
+ importClasses.add("\"IoTRMICommClient.hpp\"");
+ importClasses.add("\"IoTRMICommServer.hpp\"");
return importClasses;
}
List<String> methParams = intDecl.getMethodParams(method);
for (int i = 0; i < methPrmTypes.size(); i++) {
+ String genericType = getGenericType(methPrmTypes.get(i));
String simpleType = getSimpleType(methPrmTypes.get(i));
String param = methParams.get(i);
if (getParamCategory(simpleType) == ParamCategory.NONPRIMITIVES) {
includeClasses.add("<" + getNonPrimitiveCplusClass(simpleType) + ">");
- } else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
+ //} else if (getParamCategory(simpleType) == ParamCategory.USERDEFINED) {
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.USERDEFINED) {
// For original interface, we need it exchanged... not for stub interfaces
if (needExchange) {
- includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
- includeClasses.add("\"" + exchangeParamType(simpleType) + "_CallbackStub.hpp\"");
+ //includeClasses.add("\"" + exchangeParamType(simpleType) + ".hpp\"");
+ includeClasses.add("\"" + exchangeParamType(getSimpleArrayType(genericType)) + ".hpp\"");
} else {
- includeClasses.add("\"" + simpleType + ".hpp\"");
- includeClasses.add("\"" + simpleType + "_CallbackSkeleton.hpp\"");
+ //includeClasses.add("\"" + simpleType + ".hpp\"");
+ includeClasses.add("\"" + getSimpleArrayType(genericType) + ".hpp\"");
}
- } 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("[]")) {
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.ENUM) {
+ includeClasses.add("\"" + genericType + ".hpp\"");
+ }
+ if (getParamCategory(getSimpleArrayType(genericType)) == ParamCategory.STRUCT) {
+ includeClasses.add("\"" + genericType + ".hpp\"");
+ }
+ if (param.contains("[]")) {
// Check if this is array for C++; translate into vector
includeClasses.add("<vector>");
}
comp.generateJavaLocalInterfaces();
comp.generateJavaInterfaces();
comp.generateJavaStubClasses();
- //comp.generateJavaCallbackStubClasses();
comp.generateJavaSkeletonClass();
- //comp.generateJavaCallbackSkeletonClass();
comp.generateEnumCplus();
comp.generateStructCplus();
comp.generateCplusLocalInterfaces();
comp.generateCPlusInterfaces();
- comp.generateCPlusStubClasses();
+ comp.generateCPlusStubClassesHpp();
+ comp.generateCPlusStubClassesCpp();
//comp.generateCPlusCallbackStubClasses();
- comp.generateCplusSkeletonClass();
+ comp.generateCplusSkeletonClassHpp();
+ comp.generateCplusSkeletonClassCpp();
//comp.generateCplusCallbackSkeletonClass();
} else {
// Check other options
comp.generateJavaLocalInterfaces();
comp.generateJavaInterfaces();
comp.generateJavaStubClasses();
- //comp.generateJavaCallbackStubClasses();
comp.generateJavaSkeletonClass();
- //comp.generateJavaCallbackSkeletonClass();
} else {
comp.generateEnumCplus();
comp.generateStructCplus();
comp.generateCplusLocalInterfaces();
comp.generateCPlusInterfaces();
- comp.generateCPlusStubClasses();
+ comp.generateCPlusStubClassesHpp();
+ comp.generateCPlusStubClassesCpp();
//comp.generateCPlusCallbackStubClasses();
- comp.generateCplusSkeletonClass();
+ comp.generateCplusSkeletonClassHpp();
+ comp.generateCplusSkeletonClassCpp();
//comp.generateCplusCallbackSkeletonClass();
}
}