diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-11 04:27:47 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-11 04:27:47 +0000 |
commit | 9b6db26fcc22a7a4ec0510a93733b2e190d9e649 (patch) | |
tree | fff3f2610cab083b3093ab1052cad6202335ff59 /ppapi/cpp | |
parent | b648e91bd6c911ed26d6c65048c4a597040359ed (diff) | |
download | chromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.zip chromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.tar.gz chromium_src-9b6db26fcc22a7a4ec0510a93733b2e190d9e649.tar.bz2 |
Create a VarPrivate interface to contain the scripting helper functions of Var.
Currently, the old functions are left in Var. When people have a chance to move
to this new API, we can delete them from Var.
This also adds new enums for ARRAY and DICTIONARY vars, and makes the var C++
wrapper forward-compatible with them by refcounting any enums that it doesn't
know about.
Review URL: http://codereview.chromium.org/6823016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81068 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp')
-rw-r--r-- | ppapi/cpp/dev/scriptable_object_deprecated.h | 3 | ||||
-rw-r--r-- | ppapi/cpp/private/var_private.cc | 186 | ||||
-rw-r--r-- | ppapi/cpp/private/var_private.h | 117 | ||||
-rw-r--r-- | ppapi/cpp/var.cc | 7 | ||||
-rw-r--r-- | ppapi/cpp/var.h | 8 |
5 files changed, 313 insertions, 8 deletions
diff --git a/ppapi/cpp/dev/scriptable_object_deprecated.h b/ppapi/cpp/dev/scriptable_object_deprecated.h index 42ab466..3099977 100644 --- a/ppapi/cpp/dev/scriptable_object_deprecated.h +++ b/ppapi/cpp/dev/scriptable_object_deprecated.h @@ -11,8 +11,8 @@ struct PPP_Class_Deprecated; namespace pp { class Var; +class VarPrivate; } -using pp::Var; namespace pp { @@ -77,6 +77,7 @@ class ScriptableObject { private: friend class ::pp::Var; + friend class ::pp::VarPrivate; static const PPP_Class_Deprecated* GetClass(); // Unimplemented, copy and assigmnent is not allowed. diff --git a/ppapi/cpp/private/var_private.cc b/ppapi/cpp/private/var_private.cc new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/ppapi/cpp/private/var_private.cc @@ -0,0 +1,186 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/private/var_private.h" + +#include "ppapi/c/dev/ppb_var_deprecated.h" +#include "ppapi/cpp/instance.h" +#include "ppapi/cpp/logging.h" +#include "ppapi/cpp/module_impl.h" +#include "ppapi/cpp/dev/scriptable_object_deprecated.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_Var_Deprecated>() { + return PPB_VAR_DEPRECATED_INTERFACE; +} + +} // namespace + +using namespace deprecated; + +VarPrivate::VarPrivate(Instance* instance, ScriptableObject* object) { + if (has_interface<PPB_Var_Deprecated>()) { + var_ = get_interface<PPB_Var_Deprecated>()->CreateObject( + instance->pp_instance(), object->GetClass(), object); + needs_release_ = true; + } else { + var_.type = PP_VARTYPE_NULL; + var_.padding = 0; + needs_release_ = false; + } +} + +ScriptableObject* VarPrivate::AsScriptableObject() const { + if (!is_object()) { + PP_NOTREACHED(); + } else if (has_interface<PPB_Var_Deprecated>()) { + void* object = NULL; + if (get_interface<PPB_Var_Deprecated>()->IsInstanceOf( + var_, ScriptableObject::GetClass(), &object)) { + return reinterpret_cast<ScriptableObject*>(object); + } + } + return NULL; +} + +bool VarPrivate::HasProperty(const Var& name, Var* exception) const { + if (!has_interface<PPB_Var_Deprecated>()) + return false; + return get_interface<PPB_Var_Deprecated>()->HasProperty( + var_, name.pp_var(), OutException(exception).get()); +} + +bool VarPrivate::HasMethod(const Var& name, Var* exception) const { + if (!has_interface<PPB_Var_Deprecated>()) + return false; + return get_interface<PPB_Var_Deprecated>()->HasMethod( + var_, name.pp_var(), OutException(exception).get()); +} + +VarPrivate VarPrivate::GetProperty(const Var& name, Var* exception) const { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->GetProperty( + var_, name.pp_var(), OutException(exception).get())); +} + +void VarPrivate::GetAllPropertyNames(std::vector<Var>* properties, + Var* exception) const { + if (!has_interface<PPB_Var_Deprecated>()) + return; + PP_Var* props = NULL; + uint32_t prop_count = 0; + get_interface<PPB_Var_Deprecated>()->GetAllPropertyNames( + var_, &prop_count, &props, OutException(exception).get()); + if (!prop_count) + return; + properties->resize(prop_count); + for (uint32_t i = 0; i < prop_count; ++i) { + Var temp(PassRef(), props[i]); + (*properties)[i] = temp; + } + Module::Get()->core()->MemFree(props); +} + +void VarPrivate::SetProperty(const Var& name, const Var& value, + Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return; + get_interface<PPB_Var_Deprecated>()->SetProperty( + var_, name.pp_var(), value.pp_var(), OutException(exception).get()); +} + +void VarPrivate::RemoveProperty(const Var& name, Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return; + get_interface<PPB_Var_Deprecated>()->RemoveProperty( + var_, name.pp_var(), OutException(exception).get()); +} + +VarPrivate VarPrivate::Call(const Var& method_name, uint32_t argc, Var* argv, + Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + if (argc > 0) { + std::vector<PP_Var> args; + args.reserve(argc); + for (size_t i = 0; i < argc; i++) + args.push_back(argv[i].pp_var()); + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), argc, &args[0], + OutException(exception).get())); + } else { + // Don't try to get the address of a vector if it's empty. + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 0, NULL, + OutException(exception).get())); + } +} + +VarPrivate VarPrivate::Construct(uint32_t argc, Var* argv, + Var* exception) const { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + if (argc > 0) { + std::vector<PP_Var> args; + args.reserve(argc); + for (size_t i = 0; i < argc; i++) + args.push_back(argv[i].pp_var()); + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct( + var_, argc, &args[0], OutException(exception).get())); + } else { + // Don't try to get the address of a vector if it's empty. + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Construct( + var_, 0, NULL, OutException(exception).get())); + } +} + +VarPrivate VarPrivate::Call(const Var& method_name, Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 0, NULL, OutException(exception).get())); +} + +VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1, + Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + PP_Var args[1] = {arg1.pp_var()}; + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 1, args, OutException(exception).get())); +} + +VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1, + const Var& arg2, Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + PP_Var args[2] = {arg1.pp_var(), arg2.pp_var()}; + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 2, args, OutException(exception).get())); +} + +VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1, + const Var& arg2, const Var& arg3, Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + PP_Var args[3] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var()}; + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 3, args, OutException(exception).get())); +} + +VarPrivate VarPrivate::Call(const Var& method_name, const Var& arg1, + const Var& arg2, const Var& arg3, const Var& arg4, + Var* exception) { + if (!has_interface<PPB_Var_Deprecated>()) + return Var(); + PP_Var args[4] = {arg1.pp_var(), arg2.pp_var(), arg3.pp_var(), arg4.pp_var()}; + return Var(PassRef(), get_interface<PPB_Var_Deprecated>()->Call( + var_, method_name.pp_var(), 4, args, OutException(exception).get())); +} + +} // namespace pp diff --git a/ppapi/cpp/private/var_private.h b/ppapi/cpp/private/var_private.h new file mode 100644 index 0000000..55068bc --- /dev/null +++ b/ppapi/cpp/private/var_private.h @@ -0,0 +1,117 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ +#define PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ + +#include "ppapi/cpp/var.h" + +namespace pp { + +// VarPrivate is a version of Var that exposes the private scripting API. +// It's designed to be mostly interchangable with Var since most callers will +// be dealing with Vars from various places. +class VarPrivate : public Var { + public: + VarPrivate() : Var() {} + VarPrivate(Null) : Var(Null()) {} + VarPrivate(bool b) : Var(b) {} + VarPrivate(int32_t i) : Var(i) {} + VarPrivate(double d) : Var(d) {} + VarPrivate(const char* utf8_str) : Var(utf8_str) {} + VarPrivate(const std::string& utf8_str) : Var(utf8_str) {} + VarPrivate(PassRef, PP_Var var) : Var(PassRef(), var) {} + VarPrivate(DontManage, PP_Var var) : Var(DontManage(), var) {} + VarPrivate(Instance* instance, deprecated::ScriptableObject* object); + VarPrivate(const Var& other) : Var(other) {} + + virtual ~VarPrivate() {} + + // This assumes the object is of type object. If it's not, it will assert in + // debug mode. If it is not an object or not a ScriptableObject type, returns + // NULL. + deprecated::ScriptableObject* AsScriptableObject() const; + + bool HasProperty(const Var& name, Var* exception = NULL) const; + bool HasMethod(const Var& name, Var* exception = NULL) const; + VarPrivate GetProperty(const Var& name, Var* exception = NULL) const; + void GetAllPropertyNames(std::vector<Var>* properties, + Var* exception = NULL) const; + void SetProperty(const Var& name, const Var& value, Var* exception = NULL); + void RemoveProperty(const Var& name, Var* exception = NULL); + VarPrivate Call(const Var& method_name, uint32_t argc, Var* argv, + Var* exception = NULL); + VarPrivate Construct(uint32_t argc, Var* argv, Var* exception = NULL) const; + + // Convenience functions for calling functions with small # of args. + VarPrivate Call(const Var& method_name, Var* exception = NULL); + VarPrivate Call(const Var& method_name, const Var& arg1, + Var* exception = NULL); + VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, + Var* exception = NULL); + VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, + const Var& arg3, Var* exception = NULL); + VarPrivate Call(const Var& method_name, const Var& arg1, const Var& arg2, + const Var& arg3, const Var& arg4, Var* exception = NULL); + + // For use when calling the raw C PPAPI when using the C++ Var as a possibly + // NULL exception. This will handle getting the address of the internal value + // out if it's non-NULL and fixing up the reference count. + // + // Danger: this will only work for things with exception semantics, i.e. that + // the value will not be changed if it's a non-undefined exception. Otherwise, + // this class will mess up the refcounting. + // + // This is a bit subtle: + // - If NULL is passed, we return NULL from get() and do nothing. + // + // - If a undefined value is passed, we return the address of a undefined var + // from get and have the output value take ownership of that var. + // + // - If a non-undefined value is passed, we return the address of that var + // from get, and nothing else should change. + // + // Example: + // void FooBar(a, b, Var* exception = NULL) { + // foo_interface->Bar(a, b, VarPrivate::OutException(exception).get()); + // } + class OutException { + public: + OutException(Var* v) + : output_(v), + originally_had_exception_(v && v->is_null()) { + if (output_) { + temp_ = output_->pp_var(); + } else { + temp_.padding = 0; + temp_.type = PP_VARTYPE_UNDEFINED; + } + } + ~OutException() { + if (output_ && !originally_had_exception_) + *output_ = Var(PassRef(), temp_); + } + + PP_Var* get() { + if (output_) + return &temp_; + return NULL; + } + + private: + Var* output_; + bool originally_had_exception_; + PP_Var temp_; + }; + + private: + // Prevent an arbitrary pointer argument from being implicitly converted to + // a bool at Var construction. If somebody makes such a mistake, (s)he will + // get a compilation error. + VarPrivate(void* non_scriptable_object_pointer); +}; + +} // namespace pp + +#endif // PPAPI_CPP_PRIVATE_VAR_PRIVATE_H_ diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc index 09a91d8..00ef401 100644 --- a/ppapi/cpp/var.cc +++ b/ppapi/cpp/var.cc @@ -35,7 +35,7 @@ template <> const char* interface_name<PPB_Var_Deprecated>() { // cross-process calls depending on the plugin. This is an optimization so we // only do refcounting on the necessary objects. inline bool NeedsRefcounting(const PP_Var& var) { - return var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT; + return var.type > PP_VARTYPE_DOUBLE; } } // namespace @@ -167,11 +167,8 @@ bool Var::operator==(const Var& other) const { if (var_.value.as_id == other.var_.value.as_id) return true; return AsString() == other.AsString(); - // TODO(neb): Document that this is === and not ==, unlike strings. - case PP_VARTYPE_OBJECT: + default: // Objects, arrays, dictionaries. return var_.value.as_id == other.var_.value.as_id; - default: - return false; } } diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h index 0154fd3..e113761 100644 --- a/ppapi/cpp/var.h +++ b/ppapi/cpp/var.h @@ -60,6 +60,8 @@ class Var { Var& operator=(const Var& other); + // For objects, dictionaries, and arrays, this operator compares object + // identity rather than value identity. bool operator==(const Var& other) const; bool is_undefined() const { return var_.type == PP_VARTYPE_UNDEFINED; } @@ -195,14 +197,16 @@ class Var { PP_Var temp_; }; + protected: + PP_Var var_; + bool needs_release_; + private: // Prevent an arbitrary pointer argument from being implicitly converted to // a bool at Var construction. If somebody makes such a mistake, (s)he will // get a compilation error. Var(void* non_scriptable_object_pointer); - PP_Var var_; - bool needs_release_; }; } // namespace pp |