aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--slang_rs_object_ref_count.cpp99
-rw-r--r--slang_rs_object_ref_count.h2
-rw-r--r--tests/P_refcount/refcount.rs27
-rw-r--r--tests/P_refcount/stderr.txt.expect0
-rw-r--r--tests/P_refcount/stdout.txt.expect1
5 files changed, 126 insertions, 3 deletions
diff --git a/slang_rs_object_ref_count.cpp b/slang_rs_object_ref_count.cpp
index d2c088c..59ec672 100644
--- a/slang_rs_object_ref_count.cpp
+++ b/slang_rs_object_ref_count.cpp
@@ -142,6 +142,39 @@ static void AppendToCompoundStatement(clang::ASTContext& C,
return;
}
+static void ReplaceinCompoundStmt(clang::ASTContext& C,
+ clang::CompoundStmt *CS,
+ clang::Stmt* OldStmt,
+ clang::Stmt* NewStmt) {
+ clang::CompoundStmt::body_iterator bI = CS->body_begin();
+
+ unsigned StmtCount = 0;
+ for (bI = CS->body_begin(); bI != CS->body_end(); bI++) {
+ StmtCount++;
+ }
+
+ //OldStmt->dump();
+ //NewStmt->dump();
+
+ clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount];
+
+ unsigned UpdatedStmtCount = 0;
+ for (bI = CS->body_begin(); bI != CS->body_end(); bI++) {
+ if (*bI == OldStmt) {
+ UpdatedStmtList[UpdatedStmtCount++] = NewStmt;
+ } else {
+ UpdatedStmtList[UpdatedStmtCount++] = *bI;
+ }
+ }
+
+ CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount);
+
+ delete [] UpdatedStmtList;
+
+ return;
+}
+
+
// This class visits a compound statement and inserts the StmtList containing
// destructors in proper locations. This includes inserting them before any
// return statement in any sub-block, at the end of the logical enclosing
@@ -376,6 +409,61 @@ static clang::Stmt *ClearArrayRSObject(clang::VarDecl *VD,
} // namespace
+void RSObjectRefCount::Scope::ReplaceRSObjectAssignment(
+ clang::BinaryOperator *AS) {
+
+ clang::QualType QT = AS->getType();
+ RSExportPrimitiveType::DataType DT =
+ RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr());
+
+ clang::FunctionDecl *SetObjectFD =
+ RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
+ assert((SetObjectFD != NULL) &&
+ "rsSetObject doesn't cover all RS object types");
+ clang::ASTContext &C = SetObjectFD->getASTContext();
+
+ clang::QualType SetObjectFDType = SetObjectFD->getType();
+ clang::QualType SetObjectFDArgType[2];
+ SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType();
+ SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType();
+
+ clang::SourceLocation Loc = SetObjectFD->getLocation();
+ clang::Expr *RefRSSetObjectFD =
+ clang::DeclRefExpr::Create(C,
+ NULL,
+ SetObjectFD->getQualifierRange(),
+ SetObjectFD,
+ Loc,
+ SetObjectFDType);
+
+ clang::Expr *RSSetObjectFP =
+ clang::ImplicitCastExpr::Create(C,
+ C.getPointerType(SetObjectFDType),
+ clang::CK_FunctionToPointerDecay,
+ RefRSSetObjectFD,
+ NULL,
+ clang::VK_RValue);
+
+ clang::Expr *ArgList[2];
+ ArgList[0] = new(C) clang::UnaryOperator(AS->getLHS(),
+ clang::UO_AddrOf,
+ SetObjectFDArgType[0],
+ Loc);
+ ArgList[1] = AS->getRHS();
+
+ clang::CallExpr *RSSetObjectCall =
+ new(C) clang::CallExpr(C,
+ RSSetObjectFP,
+ ArgList,
+ 2,
+ SetObjectFD->getCallResultType(),
+ Loc);
+
+ ReplaceinCompoundStmt(C, mCS, AS, RSSetObjectCall);
+
+ return;
+}
+
void RSObjectRefCount::Scope::InsertLocalVarDestructors() {
std::list<clang::Stmt*> RSClearObjectCalls;
for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(),
@@ -634,8 +722,6 @@ void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) {
VisitStmt(CS);
// Destroy the scope
- // TODO(srhines): Update reference count of the RS object refenced by
- // getCurrentScope().
assert((getCurrentScope() == S) && "Corrupted scope stack!");
S->InsertLocalVarDestructors();
mScopeStack.pop();
@@ -645,7 +731,14 @@ void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) {
}
void RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) {
- // TODO(srhines): Update reference count
+ clang::QualType QT = AS->getType();
+ RSExportPrimitiveType::DataType DT =
+ RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr());
+
+ if (RSExportPrimitiveType::IsRSObjectType(DT)) {
+ getCurrentScope()->ReplaceRSObjectAssignment(AS);
+ }
+
return;
}
diff --git a/slang_rs_object_ref_count.h b/slang_rs_object_ref_count.h
index 580b955..a154ab1 100644
--- a/slang_rs_object_ref_count.h
+++ b/slang_rs_object_ref_count.h
@@ -56,6 +56,8 @@ class RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> {
// Initialize RSSetObjectFD and RSClearObjectFD.
static void GetRSRefCountingFunctions(clang::ASTContext &C);
+ void ReplaceRSObjectAssignment(clang::BinaryOperator *AS);
+
void InsertLocalVarDestructors();
static clang::Stmt *ClearRSObject(clang::VarDecl *VD);
diff --git a/tests/P_refcount/refcount.rs b/tests/P_refcount/refcount.rs
new file mode 100644
index 0000000..214113c
--- /dev/null
+++ b/tests/P_refcount/refcount.rs
@@ -0,0 +1,27 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+rs_font globalAlloc;
+rs_font globalAlloc2;
+
+static void foo() {
+
+ rs_font fontUninit;
+ rs_font fontArr[10];
+ fontUninit = globalAlloc;
+ for (int i = 0; i < 10; i++) {
+ fontArr[i] = globalAlloc;
+ }
+
+ return;
+}
+
+void singleStmt() {
+ globalAlloc = globalAlloc2;
+}
+
+int root(int num) {
+ foo();
+ return 10;
+}
+
diff --git a/tests/P_refcount/stderr.txt.expect b/tests/P_refcount/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_refcount/stderr.txt.expect
diff --git a/tests/P_refcount/stdout.txt.expect b/tests/P_refcount/stdout.txt.expect
new file mode 100644
index 0000000..7e2f82c
--- /dev/null
+++ b/tests/P_refcount/stdout.txt.expect
@@ -0,0 +1 @@
+Generating ScriptC_refcount.java ...