summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp/var.cc
diff options
context:
space:
mode:
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;
}