diff options
-rw-r--r-- | slang_rs_object_ref_count.cpp | 99 | ||||
-rw-r--r-- | slang_rs_object_ref_count.h | 2 | ||||
-rw-r--r-- | tests/P_refcount/refcount.rs | 27 | ||||
-rw-r--r-- | tests/P_refcount/stderr.txt.expect | 0 | ||||
-rw-r--r-- | tests/P_refcount/stdout.txt.expect | 1 |
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 ... |