summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp/var.cc
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-05 23:52:49 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-05 23:52:49 +0000
commita4f10d1ed4c8921a2a47354f78753032d0b6a999 (patch)
treef45726ef6b68ea48e80f1996079bf7049fd71a96 /ppapi/cpp/var.cc
parent4ccc9dd43bc25978691045cd4dba6664fd8afa1f (diff)
downloadchromium_src-a4f10d1ed4c8921a2a47354f78753032d0b6a999.zip
chromium_src-a4f10d1ed4c8921a2a47354f78753032d0b6a999.tar.gz
chromium_src-a4f10d1ed4c8921a2a47354f78753032d0b6a999.tar.bz2
Fix some egregious bugs in Var.
Self-assignment was broken and would lose the reference. I uncovered this when running a test. It outputted a warning to the console, but we never looked at it. I made a more explicit test. This also fixes output exceptions. The OutException helper class detected whether the existing object had an exception or not incorrectly. This was exposed when var assignment was fixed. TEST=included BUG=none Review URL: http://codereview.chromium.org/7511026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95690 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp/var.cc')
-rw-r--r--ppapi/cpp/var.cc29
1 files changed, 18 insertions, 11 deletions
diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc
index 8df9b67..683a344 100644
--- a/ppapi/cpp/var.cc
+++ b/ppapi/cpp/var.cc
@@ -117,20 +117,27 @@ Var::~Var() {
}
Var& Var::operator=(const Var& other) {
- if (needs_release_ && has_interface<PPB_Var>())
- get_interface<PPB_Var>()->Release(var_);
- var_ = other.var_;
- if (NeedsRefcounting(var_)) {
- if (has_interface<PPB_Var>()) {
- needs_release_ = true;
- get_interface<PPB_Var>()->AddRef(var_);
- } else {
- var_.type = PP_VARTYPE_NULL;
- needs_release_ = false;
- }
+ // Early return for self-assignment. Note however, that two distinct vars
+ // can refer to the same object, so we still need to be careful about the
+ // refcounting below.
+ if (this == &other)
+ return *this;
+
+ // Be careful to keep the ref alive for cases where we're assigning an
+ // object to itself by addrefing the new one before releasing the old one.
+ bool old_needs_release = needs_release_;
+ if (NeedsRefcounting(other.var_)) {
+ // Assume we already has_interface<PPB_Var> for refcounted vars or else we
+ // couldn't have created them in the first place.
+ needs_release_ = true;
+ get_interface<PPB_Var>()->AddRef(other.var_);
} else {
needs_release_ = false;
}
+ if (old_needs_release)
+ get_interface<PPB_Var>()->Release(var_);
+
+ var_ = other.var_;
return *this;
}