aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-21 00:37:51 -0700
committerStephen Hines <srhines@google.com>2013-08-22 00:41:37 -0700
commit003ac666e57669d4312b5792068c3db302ee7b84 (patch)
tree30df440657fd812b5db52fca4830ef8b885b62d7
parentd00bdedaf5de247990a41e62ecfcce2a08195bca (diff)
downloadandroid_frameworks_compile_slang-003ac666e57669d4312b5792068c3db302ee7b84.tar.gz
android_frameworks_compile_slang-003ac666e57669d4312b5792068c3db302ee7b84.tar.bz2
android_frameworks_compile_slang-003ac666e57669d4312b5792068c3db302ee7b84.zip
Type checking for C++ API.
Bug: 10427951 Change-Id: I76a6093237a3b27a0c9e6ce38997cb1e0128efb9
-rw-r--r--slang_rs_reflection_base.cpp9
-rw-r--r--slang_rs_reflection_base.h4
-rw-r--r--slang_rs_reflection_cpp.cpp124
-rw-r--r--slang_rs_reflection_cpp.h12
4 files changed, 143 insertions, 6 deletions
diff --git a/slang_rs_reflection_base.cpp b/slang_rs_reflection_base.cpp
index 65da696..fe93054 100644
--- a/slang_rs_reflection_base.cpp
+++ b/slang_rs_reflection_base.cpp
@@ -194,5 +194,14 @@ string RSReflectionBase::genInitValue(const clang::APValue &Val, bool asBool) {
return tmp.str();
}
+bool RSReflectionBase::addTypeNameForElement(
+ const std::string &TypeName) {
+ if (mTypesToCheck.find(TypeName) == mTypesToCheck.end()) {
+ mTypesToCheck.insert(TypeName);
+ return true;
+ } else {
+ return false;
+ }
+}
}
diff --git a/slang_rs_reflection_base.h b/slang_rs_reflection_base.h
index 8667e0d..100f5eb 100644
--- a/slang_rs_reflection_base.h
+++ b/slang_rs_reflection_base.h
@@ -39,7 +39,8 @@ class RSReflectionBase {
protected:
const RSContext *mRSContext;
-
+ // Generated RS Elements for type-checking code.
+ std::set<std::string> mTypesToCheck;
RSReflectionBase(const RSContext *);
@@ -67,6 +68,7 @@ protected:
bool writeFile(const std::string &filename, const std::vector< std::string > &txt);
+ bool addTypeNameForElement(const std::string &TypeName);
private:
diff --git a/slang_rs_reflection_cpp.cpp b/slang_rs_reflection_cpp.cpp
index a6a921a..ea4227d 100644
--- a/slang_rs_reflection_cpp.cpp
+++ b/slang_rs_reflection_cpp.cpp
@@ -43,6 +43,8 @@ namespace slang {
#define RS_TYPE_ITEM_CLASS_NAME "Item"
+#define RS_ELEM_PREFIX "__rs_elem_"
+
static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) {
static const char *MatrixTypeCNameMap[] = {
"rs_matrix2x2",
@@ -170,12 +172,32 @@ bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
E = mRSContext->export_vars_end(); I != E; I++, slot++) {
const RSExportVar *ev = *I;
- RSReflectionTypeData rtd;
- ev->getType()->convertToRTD(&rtd);
if (!ev->isConst()) {
write(GetTypeName(ev->getType()) + " __" + ev->getName() + ";");
}
}
+ for (RSContext::const_export_foreach_iterator
+ I = mRSContext->export_foreach_begin(),
+ E = mRSContext->export_foreach_end(); I != E; I++) {
+ const RSExportForEach *EF = *I;
+ const RSExportType *IET = EF->getInType();
+ const RSExportType *OET = EF->getOutType();
+ if (IET) {
+ genTypeInstanceFromPointer(IET);
+ }
+ if (OET) {
+ genTypeInstanceFromPointer(OET);
+ }
+ }
+
+ for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
+ E = mTypesToCheck.end();
+ I != E;
+ I++) {
+ write("android::RSC::sp<const android::RSC::Element> " RS_ELEM_PREFIX
+ + *I + ";");
+ }
+
decIndent();
write("public:");
@@ -298,7 +320,12 @@ bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
<< ", \"/data/data/" << packageName << "/app\", sizeof(\"" << packageName << "\")) {";
write(ss);
incIndent();
- //...
+ for (std::set<std::string>::iterator I = mTypesToCheck.begin(),
+ E = mTypesToCheck.end();
+ I != E;
+ I++) {
+ write(RS_ELEM_PREFIX + *I + " = android::RSC::Element::" + *I + "(mRS);");
+ }
decIndent();
write("}");
write("");
@@ -347,6 +374,19 @@ bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
write(tmp);
tmp.str("");
+ const RSExportType *IET = ef->getInType();
+ const RSExportType *OET = ef->getOutType();
+
+ incIndent();
+ if (IET) {
+ genTypeCheck(IET, "ain");
+ }
+
+ if (OET) {
+ genTypeCheck(OET, "aout");
+ }
+ decIndent();
+
std::string FieldPackerName = ef->getName() + "_fp";
if (ERT) {
if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) {
@@ -367,6 +407,7 @@ bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
tmp << "NULL, ";
}
+ // FIXME (no support for usrData with C++ kernels)
tmp << "NULL, 0);";
write(tmp);
@@ -596,8 +637,6 @@ void RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
case RSExportType::ExportClassVector:
case RSExportType::ExportClassPointer:
case RSExportType::ExportClassMatrix: {
- RSReflectionTypeData rtd;
- ET->convertToRTD(&rtd);
ss << " " << FieldPackerName << ".add(" << VarName << ");";
write(ss);
break;
@@ -690,4 +729,79 @@ void RSReflectionCpp::genPackVarOfType(const RSExportType *ET,
}
}
+
+void RSReflectionCpp::genTypeCheck(const RSExportType *ET,
+ const char *VarName) {
+ stringstream tmp;
+ tmp << "// Type check for " << VarName;
+ write(tmp);
+ tmp.str("");
+
+ if (ET->getClass() == RSExportType::ExportClassPointer) {
+ const RSExportPointerType *EPT =
+ static_cast<const RSExportPointerType*>(ET);
+ ET = EPT->getPointeeType();
+ }
+
+ std::string TypeName;
+ switch (ET->getClass()) {
+ case RSExportType::ExportClassPrimitive:
+ case RSExportType::ExportClassVector:
+ case RSExportType::ExportClassRecord: {
+ TypeName = ET->getElementName();
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (!TypeName.empty()) {
+ //tmp << "// TypeName: " << TypeName;
+ tmp << "if (!" << VarName
+ << "->getType()->getElement()->isCompatible("
+ << RS_ELEM_PREFIX
+ << TypeName << ")) {";
+ write(tmp);
+
+ incIndent();
+ write("mRS->throwError(RS_ERROR_RUNTIME_ERROR, "
+ "\"Incompatible type\");");
+ write("return;");
+ decIndent();
+
+ write("}");
+ }
+}
+
+void RSReflectionCpp::genTypeInstanceFromPointer(const RSExportType *ET) {
+ if (ET->getClass() == RSExportType::ExportClassPointer) {
+ // For pointer parameters to original forEach kernels.
+ const RSExportPointerType *EPT =
+ static_cast<const RSExportPointerType*>(ET);
+ genTypeInstance(EPT->getPointeeType());
+ } else {
+ // For handling pass-by-value kernel parameters.
+ genTypeInstance(ET);
+ }
+}
+
+void RSReflectionCpp::genTypeInstance(const RSExportType *ET) {
+ switch (ET->getClass()) {
+ case RSExportType::ExportClassPrimitive:
+ case RSExportType::ExportClassVector:
+ case RSExportType::ExportClassConstantArray:
+ case RSExportType::ExportClassRecord: {
+ std::string TypeName = ET->getElementName();
+ addTypeNameForElement(TypeName);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+
} // namespace slang
diff --git a/slang_rs_reflection_cpp.h b/slang_rs_reflection_cpp.h
index de7e824..948d624 100644
--- a/slang_rs_reflection_cpp.h
+++ b/slang_rs_reflection_cpp.h
@@ -19,6 +19,9 @@
#include "slang_rs_reflection_base.h"
+#include <set>
+#include <string>
+
namespace slang {
class RSReflectionCpp : public RSReflectionBase {
@@ -40,6 +43,7 @@ class RSReflectionCpp : public RSReflectionBase {
mNextExportVarSlot = 0;
mNextExportFuncSlot = 0;
mNextExportForEachSlot = 0;
+ mTypesToCheck.clear();
}
inline unsigned int getNextExportVarSlot() {
@@ -83,6 +87,14 @@ class RSReflectionCpp : public RSReflectionBase {
void genPackVarOfType(const RSExportType *ET,
const char *VarName,
const char *FieldPackerName);
+
+ // Generate a runtime type check for VarName.
+ void genTypeCheck(const RSExportType *ET, const char *VarName);
+
+ // Generate a type instance for a given forEach argument type.
+ void genTypeInstanceFromPointer(const RSExportType *ET);
+ void genTypeInstance(const RSExportType *ET);
+
}; // class RSReflectionCpp
} // namespace slang