aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Sams <jsams@google.com>2012-03-12 15:07:58 -0700
committerJason Sams <jsams@google.com>2012-03-12 15:07:58 -0700
commit1b6a0883cd6984e11e59b0c847fb334df1f41afc (patch)
treed080989ee2037a78e7a54ae79e7958d7a5f02e7b
parent2b8fb64be3047df940a219872b331eb11de2758d (diff)
downloadandroid_frameworks_compile_slang-1b6a0883cd6984e11e59b0c847fb334df1f41afc.tar.gz
android_frameworks_compile_slang-1b6a0883cd6984e11e59b0c847fb334df1f41afc.tar.bz2
android_frameworks_compile_slang-1b6a0883cd6984e11e59b0c847fb334df1f41afc.zip
start cpp reflection
BUG=5972398 Change-Id: Iede58fde457d16293345e741f80109f89e653ad5
-rw-r--r--Android.mk4
-rw-r--r--slang_rs.cpp8
-rw-r--r--slang_rs_export_type.cpp48
-rw-r--r--slang_rs_export_type.h16
-rw-r--r--slang_rs_reflection_base.cpp148
-rw-r--r--slang_rs_reflection_base.h80
-rw-r--r--slang_rs_reflection_cpp.cpp300
-rw-r--r--slang_rs_reflection_cpp.h48
8 files changed, 650 insertions, 2 deletions
diff --git a/Android.mk b/Android.mk
index 05df356..2347d3d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -229,7 +229,9 @@ LOCAL_SRC_FILES := \
slang_rs_export_foreach.cpp \
slang_rs_object_ref_count.cpp \
slang_rs_reflection.cpp \
- slang_rs_reflect_utils.cpp \
+ slang_rs_reflection_base.cpp \
+ slang_rs_reflection_cpp.cpp \
+ slang_rs_reflect_utils.cpp
LOCAL_STATIC_LIBRARIES := \
libclangDriver libslang \
diff --git a/slang_rs.cpp b/slang_rs.cpp
index 13413c0..0eea6f9 100644
--- a/slang_rs.cpp
+++ b/slang_rs.cpp
@@ -36,6 +36,8 @@
#include "slang_rs_context.h"
#include "slang_rs_export_type.h"
+#include "slang_rs_reflection_cpp.h"
+
namespace slang {
#define RS_HEADER_SUFFIX "rsh"
@@ -321,7 +323,11 @@ bool SlangRS::compile(
if (OutputType != Slang::OT_Dependency) {
if (BitcodeStorage == BCST_CPP_CODE) {
- // TODO: Call C++ reflection routines + appendGeneratedFileName().
+ RSReflectionCpp R(mRSContext);
+ bool ret = R.reflect(JavaReflectionPathBase, getInputFileName(), getOutputFileName());
+ if (!ret) {
+ return false;
+ }
} else {
if (!reflectToJava(JavaReflectionPathBase,
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index dc2b356..843ef56 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -1439,4 +1439,52 @@ bool RSExportRecordType::equals(const RSExportable *E) const {
return true;
}
+void RSExportType::convertToRTD(RSReflectionTypeData *rtd) const {
+ memset(rtd, 0, sizeof(*rtd));
+ rtd->vecSize = 1;
+
+ switch(getClass()) {
+ case RSExportType::ExportClassPrimitive: {
+ const RSExportPrimitiveType *EPT = static_cast<const RSExportPrimitiveType*>(this);
+ rtd->type = RSExportPrimitiveType::getRSReflectionType(EPT);
+ return;
+ }
+ case RSExportType::ExportClassPointer: {
+ const RSExportPointerType *EPT = static_cast<const RSExportPointerType*>(this);
+ const RSExportType *PointeeType = EPT->getPointeeType();
+ PointeeType->convertToRTD(rtd);
+ rtd->isPointer = true;
+ return;
+ }
+ case RSExportType::ExportClassVector: {
+ const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(this);
+ rtd->type = EVT->getRSReflectionType(EVT);
+ rtd->vecSize = EVT->getNumElement();
+ return;
+ }
+ case RSExportType::ExportClassMatrix: {
+ const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType*>(this);
+ unsigned Dim = EMT->getDim();
+ slangAssert((Dim >= 2) && (Dim <= 4));
+ rtd->type = &gReflectionTypes[15 + Dim-2];
+ return;
+ }
+ case RSExportType::ExportClassConstantArray: {
+ const RSExportConstantArrayType* CAT =
+ static_cast<const RSExportConstantArrayType*>(this);
+ CAT->getElementType()->convertToRTD(rtd);
+ rtd->arraySize = CAT->getSize();
+ return;
+ }
+ case RSExportType::ExportClassRecord: {
+ slangAssert(!"RSExportType::ExportClassRecord not implemented");
+ return;// RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + ".Item";
+ }
+ default: {
+ slangAssert(false && "Unknown class of type");
+ }
+ }
+}
+
+
} // namespace slang
diff --git a/slang_rs_export_type.h b/slang_rs_export_type.h
index e88f42f..e3d8f78 100644
--- a/slang_rs_export_type.h
+++ b/slang_rs_export_type.h
@@ -71,6 +71,20 @@ typedef struct {
bool java_promotion;
} RSReflectionType;
+
+typedef struct RSReflectionTypeData_rec {
+ const RSReflectionType *type;
+ uint32_t vecSize;
+ bool isPointer;
+ uint32_t arraySize;
+
+ // Subelements
+ //std::vector<const struct RSReflectionTypeData_rec *> fields;
+ //std::vector< std::string > fieldNames;
+ //std::vector< uint32_t> fieldOffsetBytes;
+} RSReflectionTypeData;
+
+
class RSExportType : public RSExportable {
friend class RSExportElement;
public:
@@ -83,6 +97,8 @@ class RSExportType : public RSExportable {
ExportClassRecord
} ExportClass;
+ void convertToRTD(RSReflectionTypeData *rtd) const;
+
private:
ExportClass mClass;
std::string mName;
diff --git a/slang_rs_reflection_base.cpp b/slang_rs_reflection_base.cpp
new file mode 100644
index 0000000..9f0650d
--- /dev/null
+++ b/slang_rs_reflection_base.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+
+#include <cstdarg>
+#include <cctype>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "os_sep.h"
+#include "slang_rs_context.h"
+#include "slang_rs_export_var.h"
+#include "slang_rs_export_foreach.h"
+#include "slang_rs_export_func.h"
+#include "slang_rs_reflect_utils.h"
+#include "slang_version.h"
+#include "slang_utils.h"
+
+#include "slang_rs_reflection_base.h"
+
+
+
+using namespace std;
+
+namespace slang {
+
+static const char *const gApacheLicenseNote =
+"/*\n"
+" * Copyright (C) 2012 The Android Open Source Project\n"
+" *\n"
+" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+" * you may not use this file except in compliance with the License.\n"
+" * You may obtain a copy of the License at\n"
+" *\n"
+" * http://www.apache.org/licenses/LICENSE-2.0\n"
+" *\n"
+" * Unless required by applicable law or agreed to in writing, software\n"
+" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+" * See the License for the specific language governing permissions and\n"
+" * limitations under the License.\n"
+" */\n"
+"\n";
+
+
+RSReflectionBase::RSReflectionBase(const RSContext *con) {
+ mRSContext = con;
+ mLicenseNote = gApacheLicenseNote;
+
+
+}
+
+RSReflectionBase::~RSReflectionBase() {
+
+}
+
+/*
+bool RSReflectionBase::openFile(const string &name, string &errorMsg) {
+ if(!mUseStdout) {
+ mOF.clear();
+ if(!SlangUtils::CreateDirectoryWithParents(mOutputPath, &errorMsg)) {
+ return false;
+ }
+
+ string cf(mOutputPath + OS_PATH_SEPARATOR_STR + name);
+ mOF.open(cf.c_str());
+ if(!mOF.good()) {
+ errorMsg = "failed to open file '" + cf + "' for write";
+ return false;
+ }
+ }
+ return true;
+}
+*/
+
+void RSReflectionBase::startFile(const string &filename) {
+ if(mVerbose) {
+ printf("Generating %s\n", filename.c_str());
+ }
+
+ // License
+ write(mLicenseNote);
+
+ // Notice of generated file
+ write("/*");
+ write(" * This file is auto-generated. DO NOT MODIFY!");
+ write(" * The source Renderscript file: " + mInputFileName);
+ write(" */");
+ write("");
+}
+
+string RSReflectionBase::stripRS(const string &s) const {
+ size_t pos = s.rfind(".rs");
+ if(pos != string::npos) {
+ string tmp(s);
+ tmp.erase(pos);
+ return tmp;
+ }
+ return s;
+}
+
+void RSReflectionBase::write(const std::string &t) {
+ printf("%s%s\n", mIndent.c_str(), t.c_str());
+ mText.push_back(mIndent + t);
+}
+
+
+void RSReflectionBase::incIndent() {
+ mIndent.append(" ");
+}
+
+void RSReflectionBase::decIndent() {
+ mIndent.erase(0, 4);
+}
+
+bool RSReflectionBase::writeFile(const string &filename, const vector< string > &txt) {
+ FILE *pfin = fopen(filename.c_str(), "wt");
+ if (pfin == NULL) {
+ fprintf(stderr, "Error: could not write file %s\n", filename.c_str());
+ return false;
+ }
+
+ for(size_t ct=0; ct < txt.size(); ct++) {
+ fprintf(pfin, "%s\n", txt[ct].c_str());
+ }
+ fclose(pfin);
+ return true;
+}
+
+
+}
diff --git a/slang_rs_reflection_base.h b/slang_rs_reflection_base.h
new file mode 100644
index 0000000..b328646
--- /dev/null
+++ b/slang_rs_reflection_base.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_BASE_H_ // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_BASE_H_
+
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "llvm/ADT/StringExtras.h"
+
+#include "slang_assert.h"
+#include "slang_rs_export_type.h"
+
+namespace slang {
+ class RSContext;
+ class RSExportVar;
+ class RSExportFunc;
+ class RSExportForEach;
+
+class RSReflectionBase {
+protected:
+ const RSContext *mRSContext;
+
+
+
+ RSReflectionBase(const RSContext *);
+
+
+ bool mVerbose;
+
+ std::string mLicenseNote;
+ std::string mInputFileName;
+
+ std::string mClassName;
+ std::string mOutputPath;
+ std::string mOutputBCFileName;
+
+ std::vector< std::string > mText;
+ std::string mIndent;
+
+ bool openFile(const std::string &name, std::string &errorMsg);
+ void startFile(const std::string &filename);
+ void incIndent();
+ void decIndent();
+ void write(const std::string &t);
+
+ std::string stripRS(const std::string &s) const;
+
+ static bool writeFile(const std::string &filename, const std::vector< std::string > &txt);
+
+
+private:
+
+public:
+ virtual ~RSReflectionBase();
+
+
+}; // class RSReflection
+
+} // namespace slang
+
+#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_BASE_H_ NOLINT
diff --git a/slang_rs_reflection_cpp.cpp b/slang_rs_reflection_cpp.cpp
new file mode 100644
index 0000000..68c7c0a
--- /dev/null
+++ b/slang_rs_reflection_cpp.cpp
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <cstdarg>
+#include <cctype>
+
+#include <algorithm>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "os_sep.h"
+#include "slang_rs_context.h"
+#include "slang_rs_export_var.h"
+#include "slang_rs_export_foreach.h"
+#include "slang_rs_export_func.h"
+#include "slang_rs_reflect_utils.h"
+#include "slang_version.h"
+#include "slang_utils.h"
+
+#include "slang_rs_reflection_cpp.h"
+
+using namespace std;
+
+namespace slang {
+
+RSReflectionCpp::RSReflectionCpp(const RSContext *con) :
+ RSReflectionBase(con) {
+
+}
+
+RSReflectionCpp::~RSReflectionCpp() {
+
+}
+
+bool RSReflectionCpp::reflect(const string &OutputPathBase,
+ const string &InputFileName,
+ const string &OutputBCFileName) {
+ mInputFileName = InputFileName;
+ mOutputPath = OutputPathBase;
+ mOutputBCFileName = OutputBCFileName;
+ mClassName = string("ScriptC_") + stripRS(InputFileName);
+
+ makeHeader("ScriptC");
+ std::vector< std::string > header(mText);
+ mText.clear();
+
+ makeImpl("ScriptC");
+ std::vector< std::string > cpp(mText);
+ mText.clear();
+
+
+ RSReflectionBase::writeFile(mClassName + ".h", header);
+ RSReflectionBase::writeFile(mClassName + ".cpp", cpp);
+
+
+ return false;
+}
+
+typedef std::vector<std::pair<std::string, std::string> > ArgTy;
+
+
+#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_"
+
+
+
+bool RSReflectionCpp::makeHeader(const std::string &baseClass) {
+ startFile(mClassName + ".h");
+
+ write("");
+ write("#include \"ScriptC.h\"");
+ write("");
+
+ // Imports
+ //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
+ //out() << "import " << Import[i] << ";" << std::endl;
+ //out() << std::endl;
+
+ if(!baseClass.empty()) {
+ write("class " + mClassName + " : public " + baseClass + " {");
+ } else {
+ write("class " + mClassName + " {");
+ }
+
+ write("public:");
+ incIndent();
+ write(mClassName + "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength);");
+ write("virtual ~" + mClassName + "();");
+
+
+ // Reflect export variable
+ uint32_t slot = 0;
+ for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
+ E = mRSContext->export_vars_end(); I != E; I++) {
+
+ const RSExportVar *ev = *I;
+ //const RSExportType *et = ev->getType();
+
+ char buf[256];
+ sprintf(buf, " = %i;", slot++);
+ write("const static int mExportVarIdx_" + ev->getName() + buf);
+
+ //switch (ET->getClass()) {
+
+ //genExportVariable(C, *I);
+ }
+
+ // Reflect export for each functions
+ for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
+ E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
+
+ const RSExportForEach *ef = *I;
+ if (ef->isDummyRoot()) {
+ write("// No forEach_root(...)");
+ continue;
+ }
+
+ char buf[256];
+ sprintf(buf, " = %i;", slot);
+ write("const static int mExportForEachIdx_" + ef->getName() + buf);
+
+ string tmp("void forEach_" + ef->getName() + "(");
+ if(ef->hasIn())
+ tmp += "Allocation ain";
+ if(ef->hasOut())
+ tmp += "Allocation aout";
+
+ if(ef->getParamPacketType()) {
+ for(RSExportForEach::const_param_iterator i = ef->params_begin(),
+ e = ef->params_end(); i != e; i++) {
+
+ RSReflectionTypeData rtd;
+ (*i)->getType()->convertToRTD(&rtd);
+ tmp += rtd.type->c_name;
+ tmp += " ";
+ tmp +=(*i)->getName();
+ }
+ }
+ tmp += ") const;";
+ write(tmp);
+ }
+
+
+ // Reflect export function
+ for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
+ E = mRSContext->export_funcs_end(); I != E; I++) {
+
+ //genExportFunction(C, *I);
+ }
+
+ decIndent();
+ write("};");
+ return true;
+}
+
+bool RSReflectionCpp::writeBC() {
+ FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb");
+ if (pfin == NULL) {
+ fprintf(stderr, "Error: could not read file %s\n", mOutputBCFileName.c_str());
+ return false;
+ }
+
+ unsigned char buf[16];
+ int read_length;
+ write("static const unsigned char __txt[] = {");
+ incIndent();
+ while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) {
+ string s;
+ for(int i = 0; i < read_length; i++) {
+ char buf2[16];
+ sprintf(buf2, "0x%02x,", buf[i]);
+ s += buf2;
+ }
+ write(s);
+ }
+ decIndent();
+ write("};");
+ write("");
+ return true;
+}
+
+bool RSReflectionCpp::makeImpl(const std::string &baseClass) {
+ startFile(mClassName + ".h");
+
+ write("");
+ write("#include \"" + mClassName + ".h\"");
+ write("");
+
+ writeBC();
+
+ // Imports
+ //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++)
+ //out() << "import " << Import[i] << ";" << std::endl;
+ //out() << std::endl;
+
+ write(mClassName + "::" + mClassName +
+ "(RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :");
+ write(" ScriptC(rs, __txt, sizeof(__txt), " + mInputFileName +
+ ", 4, cacheDir, cacheDirLength) {");
+ incIndent();
+ //...
+ decIndent();
+ write("}");
+ write("");
+
+ write("virtual ~" + mClassName + "::" + mClassName + "() {");
+ write("}");
+ write("");
+
+
+ // Reflect export variable
+ uint32_t slot = 0;
+ for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(),
+ E = mRSContext->export_vars_end(); I != E; I++) {
+
+ const RSExportVar *ev = *I;
+ //const RSExportType *et = ev->getType();
+
+ char buf[256];
+ sprintf(buf, " = %i;", slot++);
+ write("const static int mExportVarIdx_" + ev->getName() + buf);
+
+ //switch (ET->getClass()) {
+
+ //genExportVariable(C, *I);
+ }
+
+ // Reflect export for each functions
+ slot = 0;
+ for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(),
+ E = mRSContext->export_foreach_end(); I != E; I++, slot++) {
+
+ const RSExportForEach *ef = *I;
+ if (ef->isDummyRoot()) {
+ write("// No forEach_root(...)");
+ continue;
+ }
+
+ char buf[256];
+ string tmp("void forEach_" + ef->getName() + "(");
+ if(ef->hasIn() && ef->hasOut()) {
+ tmp += "Allocation ain, Allocation aout";
+ } else if(ef->hasIn()) {
+ tmp += "Allocation ain";
+ } else {
+ tmp += "Allocation aout";
+ }
+ tmp += ") const {";
+ write(tmp);
+
+ incIndent();
+ sprintf(buf, "forEach(%i, ", slot);
+ tmp = buf;
+ if(ef->hasIn() && ef->hasOut()) {
+ tmp += "ain, aout, NULL, 0);";
+ } else if(ef->hasIn()) {
+ tmp += "ain, NULL, 0);";
+ } else {
+ tmp += "aout, NULL, 0);";
+ }
+ write(tmp);
+ decIndent();
+
+ write("}");
+ write("");
+ }
+
+
+ // Reflect export function
+ slot = 0;
+ for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(),
+ E = mRSContext->export_funcs_end(); I != E; I++) {
+
+ //genExportFunction(C, *I);
+ }
+
+ decIndent();
+ return true;
+}
+
+
+
+}
diff --git a/slang_rs_reflection_cpp.h b/slang_rs_reflection_cpp.h
new file mode 100644
index 0000000..1537286
--- /dev/null
+++ b/slang_rs_reflection_cpp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_ // NOLINT
+#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_
+
+#include "slang_rs_reflection_base.h"
+
+namespace slang {
+
+class RSReflectionCpp : public RSReflectionBase {
+protected:
+
+
+public:
+ RSReflectionCpp(const RSContext *);
+ virtual ~RSReflectionCpp();
+
+ bool reflect(const std::string &OutputPathBase,
+ const std::string &InputFileName,
+ const std::string &OutputBCFileName);
+
+
+private:
+ bool makeHeader(const std::string &baseClass);
+ bool makeImpl(const std::string &baseClass);
+ bool writeBC();
+
+ bool startScriptHeader();
+
+}; // class RSReflection
+
+} // namespace slang
+
+#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_CPP_H_ NOLINT