diff options
Diffstat (limited to 'webkit/glue/plugins/pepper_var.cc')
-rw-r--r-- | webkit/glue/plugins/pepper_var.cc | 857 |
1 files changed, 857 insertions, 0 deletions
diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc new file mode 100644 index 0000000..414df7b --- /dev/null +++ b/webkit/glue/plugins/pepper_var.cc @@ -0,0 +1,857 @@ +// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_var.h" + +#include "base/logging.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "third_party/ppapi/c/pp_var.h" +#include "third_party/ppapi/c/ppb_var.h" +#include "third_party/ppapi/c/ppp_class.h" +#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" +#include "webkit/glue/plugins/pepper_string.h" +#include "v8/include/v8.h" + +using WebKit::WebBindings; + +namespace pepper { + +namespace { + +void Release(PP_Var var); +PP_Var VarFromUtf8(const char* data, uint32_t len); + +// --------------------------------------------------------------------------- +// Exceptions + +class TryCatch { + public: + TryCatch(PP_Var* exception) : exception_(exception) { + WebBindings::pushExceptionHandler(&TryCatch::Catch, this); + } + + ~TryCatch() { + WebBindings::popExceptionHandler(); + } + + bool HasException() const { + return exception_ && exception_->type != PP_VARTYPE_VOID; + } + + void SetException(const char* message) { + DCHECK(!HasException()); + if (exception_) + *exception_ = VarFromUtf8(message, strlen(message)); + } + + private: + static void Catch(void* self, const NPUTF8* message) { + static_cast<TryCatch*>(self)->SetException(message); + } + + // May be null if the consumer isn't interesting in catching exceptions. + PP_Var* exception_; +}; + +const char kInvalidObjectException[] = "Error: Invalid object"; +const char kInvalidPropertyException[] = "Error: Invalid property"; +const char kUnableToGetPropertyException[] = "Error: Unable to get property"; +const char kUnableToSetPropertyException[] = "Error: Unable to set property"; +const char kUnableToRemovePropertyException[] = + "Error: Unable to remove property"; +const char kUnableToGetAllPropertiesException[] = + "Error: Unable to get all properties"; +const char kUnableToCallMethodException[] = "Error: Unable to call method"; +const char kUnableToConstructException[] = "Error: Unable to construct"; + +// --------------------------------------------------------------------------- +// Utilities + +String* GetStringUnchecked(PP_Var var) { + return reinterpret_cast<String*>(var.value.as_id); +} + +NPObject* GetNPObjectUnchecked(PP_Var var) { + return reinterpret_cast<NPObject*>(var.value.as_id); +} + +// Returns a PP_Var that corresponds to the given NPVariant. The contents of +// the NPVariant will be copied unless the NPVariant corresponds to an object. +PP_Var NPVariantToPPVar(const NPVariant* variant) { + switch (variant->type) { + case NPVariantType_Void: + return PP_MakeVoid(); + case NPVariantType_Null: + return PP_MakeNull(); + case NPVariantType_Bool: + return PP_MakeBool(NPVARIANT_TO_BOOLEAN(*variant)); + case NPVariantType_Int32: + return PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); + case NPVariantType_Double: + return PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant)); + case NPVariantType_String: + return VarFromUtf8(NPVARIANT_TO_STRING(*variant).UTF8Characters, + NPVARIANT_TO_STRING(*variant).UTF8Length); + case NPVariantType_Object: + return NPObjectToPPVar(NPVARIANT_TO_OBJECT(*variant)); + } + NOTREACHED(); + return PP_MakeVoid(); +} + +// Returns a NPVariant that corresponds to the given PP_Var. The contents of +// the PP_Var will be copied unless the PP_Var corresponds to an object. +NPVariant PPVarToNPVariant(PP_Var var) { + NPVariant ret; + switch (var.type) { + case PP_VARTYPE_VOID: + VOID_TO_NPVARIANT(ret); + break; + case PP_VARTYPE_NULL: + NULL_TO_NPVARIANT(ret); + break; + case PP_VARTYPE_BOOL: + BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); + break; + case PP_VARTYPE_INT32: + INT32_TO_NPVARIANT(var.value.as_int, ret); + break; + case PP_VARTYPE_DOUBLE: + DOUBLE_TO_NPVARIANT(var.value.as_double, ret); + break; + case PP_VARTYPE_STRING: { + const std::string& value = GetStringUnchecked(var)->value(); + STRINGN_TO_NPVARIANT(base::strdup(value.c_str()), value.size(), ret); + break; + } + case PP_VARTYPE_OBJECT: { + NPObject* object = GetNPObjectUnchecked(var); + OBJECT_TO_NPVARIANT(WebBindings::retainObject(object), ret); + break; + } + } + return ret; +} + +// Returns a NPVariant that corresponds to the given PP_Var. The contents of +// the PP_Var will NOT be copied, so you need to ensure that the PP_Var remains +// valid while the resultant NPVariant is in use. +NPVariant PPVarToNPVariantNoCopy(PP_Var var) { + NPVariant ret; + switch (var.type) { + case PP_VARTYPE_VOID: + VOID_TO_NPVARIANT(ret); + break; + case PP_VARTYPE_NULL: + NULL_TO_NPVARIANT(ret); + break; + case PP_VARTYPE_BOOL: + BOOLEAN_TO_NPVARIANT(var.value.as_bool, ret); + break; + case PP_VARTYPE_INT32: + INT32_TO_NPVARIANT(var.value.as_int, ret); + break; + case PP_VARTYPE_DOUBLE: + DOUBLE_TO_NPVARIANT(var.value.as_double, ret); + break; + case PP_VARTYPE_STRING: { + const std::string& value = GetStringUnchecked(var)->value(); + STRINGN_TO_NPVARIANT(value.c_str(), value.size(), ret); + break; + } + case PP_VARTYPE_OBJECT: { + OBJECT_TO_NPVARIANT(GetNPObjectUnchecked(var), ret); + break; + } + } + return ret; +} + +// Returns a NPIdentifier that corresponds to the given PP_Var. The contents +// of the PP_Var will be copied. Returns NULL if the given PP_Var is not a a +// string or integer type. +NPIdentifier PPVarToNPIdentifier(PP_Var var) { + switch (var.type) { + case PP_VARTYPE_STRING: + return WebBindings::getStringIdentifier( + GetStringUnchecked(var)->value().c_str()); + case PP_VARTYPE_INT32: + return WebBindings::getIntIdentifier(var.value.as_int); + default: + return NULL; + } +} + +PP_Var NPIdentifierToPPVar(NPIdentifier id) { + const NPUTF8* string_value = NULL; + int32_t int_value = 0; + bool is_string = false; + WebBindings::extractIdentifierData(id, string_value, int_value, is_string); + if (is_string) + return VarFromUtf8(string_value, strlen(string_value)); + + return PP_MakeInt32(int_value); +} + +PP_Var NPIdentifierToPPVarString(NPIdentifier id) { + PP_Var var = NPIdentifierToPPVar(id); + if (var.type == PP_VARTYPE_STRING) + return var; + DCHECK(var.type == PP_VARTYPE_INT32); + const std::string& str = IntToString(var.value.as_int); + return VarFromUtf8(str.data(), str.size()); +} + +void ThrowException(NPObject* object, PP_Var exception) { + String* str = GetString(exception); + if (str) + WebBindings::setException(object, str->value().c_str()); +} + +// --------------------------------------------------------------------------- +// NPObject implementation in terms of PPP_Class + +struct WrapperObject : NPObject { + const PPP_Class* ppp_class; + void* ppp_class_data; +}; + +static WrapperObject* ToWrapper(NPObject* object) { + return static_cast<WrapperObject*>(object); +} + +NPObject* WrapperClass_Allocate(NPP npp, NPClass* unused) { + return new WrapperObject; +} + +void WrapperClass_Deallocate(NPObject* object) { + WrapperObject* wrapper = ToWrapper(object); + wrapper->ppp_class->Deallocate(wrapper->ppp_class_data); + delete object; +} + +void WrapperClass_Invalidate(NPObject* object) { + // TODO(darin): Do I need to do something here? +} + +bool WrapperClass_HasMethod(NPObject* object, NPIdentifier method_name) { + WrapperObject* wrapper = ToWrapper(object); + + PP_Var method_name_var = NPIdentifierToPPVarString(method_name); + PP_Var exception = PP_MakeVoid(); + bool rv = wrapper->ppp_class->HasMethod(wrapper->ppp_class_data, + method_name_var, + &exception); + Release(method_name_var); + + if (exception.type != PP_VARTYPE_VOID) { + ThrowException(object, exception); + Release(exception); + return false; + } + return rv; +} + +bool WrapperClass_Invoke(NPObject* object, NPIdentifier method_name, + const NPVariant* argv, uint32_t argc, + NPVariant* result) { + WrapperObject* wrapper = ToWrapper(object); + + scoped_array<PP_Var> args; + if (argc) { + args.reset(new PP_Var[argc]); + for (uint32_t i = 0; i < argc; ++i) + args[i] = NPVariantToPPVar(&argv[i]); + } + PP_Var method_name_var = NPIdentifierToPPVarString(method_name); + PP_Var exception = PP_MakeVoid(); + PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data, + method_name_var, argc, + args.get(), &exception); + Release(method_name_var); + for (uint32_t i = 0; i < argc; ++i) + Release(args[i]); + + bool rv; + if (exception.type == PP_VARTYPE_VOID) { + rv = true; + *result = PPVarToNPVariant(result_var); + } else { + rv = false; + ThrowException(object, exception); + Release(exception); + } + Release(result_var); + return rv; +} + +bool WrapperClass_InvokeDefault(NPObject* object, const NPVariant* argv, + uint32_t argc, NPVariant* result) { + WrapperObject* wrapper = ToWrapper(object); + + scoped_array<PP_Var> args; + if (argc) { + args.reset(new PP_Var[argc]); + for (uint32_t i = 0; i < argc; ++i) + args[i] = NPVariantToPPVar(&argv[i]); + } + PP_Var exception = PP_MakeVoid(); + PP_Var result_var = wrapper->ppp_class->Call(wrapper->ppp_class_data, + PP_MakeVoid(), argc, args.get(), + &exception); + for (uint32_t i = 0; i < argc; ++i) + Release(args[i]); + + bool rv; + if (exception.type == PP_VARTYPE_VOID) { + rv = true; + *result = PPVarToNPVariant(result_var); + } else { + rv = false; + ThrowException(object, exception); + Release(exception); + } + Release(result_var); + return rv; +} + +bool WrapperClass_HasProperty(NPObject* object, NPIdentifier property_name) { + WrapperObject* wrapper = ToWrapper(object); + + PP_Var property_name_var = NPIdentifierToPPVar(property_name); + PP_Var exception = PP_MakeVoid(); + bool rv = wrapper->ppp_class->HasProperty(wrapper->ppp_class_data, + property_name_var, + &exception); + Release(property_name_var); + + if (exception.type != PP_VARTYPE_VOID) { + ThrowException(object, exception); + Release(exception); + return false; + } + return rv; +} + +bool WrapperClass_GetProperty(NPObject* object, NPIdentifier property_name, + NPVariant* result) { + WrapperObject* wrapper = ToWrapper(object); + + PP_Var property_name_var = NPIdentifierToPPVar(property_name); + PP_Var exception = PP_MakeVoid(); + PP_Var result_var = wrapper->ppp_class->GetProperty(wrapper->ppp_class_data, + property_name_var, + &exception); + Release(property_name_var); + + bool rv; + if (exception.type == PP_VARTYPE_VOID) { + rv = true; + *result = PPVarToNPVariant(result_var); + } else { + rv = false; + ThrowException(object, exception); + Release(exception); + } + Release(result_var); + return rv; +} + +bool WrapperClass_SetProperty(NPObject* object, NPIdentifier property_name, + const NPVariant* value) { + WrapperObject* wrapper = ToWrapper(object); + + PP_Var property_name_var = NPIdentifierToPPVar(property_name); + PP_Var value_var = NPVariantToPPVar(value); + PP_Var exception = PP_MakeVoid(); + wrapper->ppp_class->SetProperty(wrapper->ppp_class_data, property_name_var, + value_var, &exception); + Release(value_var); + Release(property_name_var); + + if (exception.type != PP_VARTYPE_VOID) { + ThrowException(object, exception); + Release(exception); + return false; + } + return true; +} + +bool WrapperClass_RemoveProperty(NPObject* object, NPIdentifier property_name) { + WrapperObject* wrapper = ToWrapper(object); + + PP_Var property_name_var = NPIdentifierToPPVar(property_name); + PP_Var exception = PP_MakeVoid(); + wrapper->ppp_class->RemoveProperty(wrapper->ppp_class_data, property_name_var, + &exception); + Release(property_name_var); + + if (exception.type != PP_VARTYPE_VOID) { + ThrowException(object, exception); + Release(exception); + return false; + } + return true; +} + +bool WrapperClass_Enumerate(NPObject* object, NPIdentifier** values, + uint32_t* count) { + WrapperObject* wrapper = ToWrapper(object); + + uint32_t property_count = 0; + PP_Var* properties = NULL; + PP_Var exception = PP_MakeVoid(); + wrapper->ppp_class->GetAllPropertyNames(wrapper->ppp_class_data, + &property_count, + &properties, + &exception); + + bool rv; + if (exception.type == PP_VARTYPE_VOID) { + rv = true; + if (property_count == 0) { + *values = NULL; + *count = 0; + } else { + *values = static_cast<NPIdentifier*>( + malloc(sizeof(NPIdentifier) * property_count)); + *count = property_count; + for (uint32_t i = 0; i < property_count; ++i) + (*values)[i] = PPVarToNPIdentifier(properties[i]); + } + } else { + rv = false; + ThrowException(object, exception); + Release(exception); + } + + for (uint32_t i = 0; i < property_count; ++i) + Release(properties[i]); + free(properties); + return rv; +} + +bool WrapperClass_Construct(NPObject* object, const NPVariant* argv, + uint32_t argc, NPVariant* result) { + WrapperObject* wrapper = ToWrapper(object); + + scoped_array<PP_Var> args; + if (argc) { + args.reset(new PP_Var[argc]); + for (uint32_t i = 0; i < argc; ++i) + args[i] = NPVariantToPPVar(&argv[i]); + } + + PP_Var exception = PP_MakeVoid(); + PP_Var result_var = wrapper->ppp_class->Construct(wrapper->ppp_class_data, + argc, args.get(), + &exception); + for (uint32_t i = 0; i < argc; ++i) + Release(args[i]); + + bool rv; + if (exception.type == PP_VARTYPE_VOID) { + rv = true; + *result = PPVarToNPVariant(result_var); + } else { + rv = false; + ThrowException(object, exception); + Release(exception); + } + Release(result_var); + return rv; +} + +const NPClass wrapper_class = { + NP_CLASS_STRUCT_VERSION, + WrapperClass_Allocate, + WrapperClass_Deallocate, + WrapperClass_Invalidate, + WrapperClass_HasMethod, + WrapperClass_Invoke, + WrapperClass_InvokeDefault, + WrapperClass_HasProperty, + WrapperClass_GetProperty, + WrapperClass_SetProperty, + WrapperClass_RemoveProperty, + WrapperClass_Enumerate, + WrapperClass_Construct +}; + +// --------------------------------------------------------------------------- +// PPB_Var methods + +void AddRef(PP_Var var) { + if (var.type == PP_VARTYPE_STRING) { + GetStringUnchecked(var)->AddRef(); + } else if (var.type == PP_VARTYPE_OBJECT) { + // TODO(darin): Add thread safety check + WebBindings::retainObject(GetNPObjectUnchecked(var)); + } +} + +void Release(PP_Var var) { + if (var.type == PP_VARTYPE_STRING) { + GetStringUnchecked(var)->Release(); + } else if (var.type == PP_VARTYPE_OBJECT) { + // TODO(darin): Add thread safety check + WebBindings::releaseObject(GetNPObjectUnchecked(var)); + } +} + +PP_Var VarFromUtf8(const char* data, uint32_t len) { + String* str = new String(data, len); + str->AddRef(); // This is for the caller, we return w/ a refcount of 1. + PP_Var ret; + ret.type = PP_VARTYPE_STRING; + ret.value.as_id = reinterpret_cast<intptr_t>(str); + return ret; +} + +const char* VarToUtf8(PP_Var var, uint32_t* len) { + if (var.type != PP_VARTYPE_STRING) { + *len = 0; + return NULL; + } + const std::string& str = GetStringUnchecked(var)->value(); + *len = static_cast<uint32_t>(str.size()); + if (str.empty()) + return ""; // Don't return NULL on success. + return str.data(); +} + +bool HasProperty(PP_Var var, + PP_Var name, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return false; + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return false; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return false; + } + + return WebBindings::hasProperty(NULL, object, identifier); +} + +bool HasMethod(PP_Var var, + PP_Var name, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return false; + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return false; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return false; + } + + return WebBindings::hasMethod(NULL, object, identifier); +} + +PP_Var GetProperty(PP_Var var, + PP_Var name, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return PP_MakeVoid(); + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return PP_MakeVoid(); + } + + NPVariant result; + if (!WebBindings::getProperty(NULL, object, identifier, &result)) { + // An exception may have been raised. + if (!try_catch.HasException()) + try_catch.SetException(kUnableToGetPropertyException); + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); + return ret; +} + +void GetAllPropertyNames(PP_Var var, + uint32_t* property_count, + PP_Var** properties, + PP_Var* exception) { + *properties = NULL; + *property_count = 0; + + TryCatch try_catch(exception); + if (try_catch.HasException()) + return; + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return; + } + + NPIdentifier* identifiers = NULL; + uint32_t count = 0; + if (!WebBindings::enumerate(NULL, object, &identifiers, &count)) { + if (!try_catch.HasException()) + try_catch.SetException(kUnableToGetAllPropertiesException); + return; + } + + if (count == 0) + return; + + *property_count = count; + *properties = static_cast<PP_Var*>(malloc(sizeof(PP_Var) * count)); + for (uint32_t i = 0; i < count; ++i) + (*properties)[i] = NPIdentifierToPPVar(identifiers[i]); + free(identifiers); +} + +void SetProperty(PP_Var var, + PP_Var name, + PP_Var value, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return; + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return; + } + + NPVariant variant = PPVarToNPVariantNoCopy(value); + if (!WebBindings::setProperty(NULL, object, identifier, &variant)) { + if (!try_catch.HasException()) + try_catch.SetException(kUnableToSetPropertyException); + } +} + +void RemoveProperty(PP_Var var, + PP_Var name, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return; + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return; + } + + NPIdentifier identifier = PPVarToNPIdentifier(name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return; + } + + if (!WebBindings::removeProperty(NULL, object, identifier)) { + if (!try_catch.HasException()) + try_catch.SetException(kUnableToRemovePropertyException); + } +} + +PP_Var Call(PP_Var var, + PP_Var method_name, + uint32_t argc, + PP_Var* argv, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return PP_MakeVoid(); + } + + NPIdentifier identifier; + if (method_name.type == PP_VARTYPE_VOID) { + identifier = NULL; + } else if (method_name.type == PP_VARTYPE_STRING) { + // Specifically allow only string functions to be called. + identifier = PPVarToNPIdentifier(method_name); + if (!identifier) { + try_catch.SetException(kInvalidPropertyException); + return PP_MakeVoid(); + } + } else { + try_catch.SetException(kInvalidPropertyException); + return PP_MakeVoid(); + } + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (uint32_t i = 0; i < argc; ++i) + args[i] = PPVarToNPVariantNoCopy(argv[i]); + } + + bool ok; + + NPVariant result; + if (identifier) { + ok = WebBindings::invoke(NULL, object, identifier, args.get(), argc, + &result); + } else { + ok = WebBindings::invokeDefault(NULL, object, args.get(), argc, &result); + } + + if (!ok) { + // An exception may have been raised. + if (!try_catch.HasException()) + try_catch.SetException(kUnableToCallMethodException); + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); + return ret; +} + +PP_Var Construct(PP_Var var, + uint32_t argc, + PP_Var* argv, + PP_Var* exception) { + TryCatch try_catch(exception); + if (try_catch.HasException()) + return PP_MakeVoid(); + + NPObject* object = GetNPObject(var); + if (!object) { + try_catch.SetException(kInvalidObjectException); + return PP_MakeVoid(); + } + + scoped_array<NPVariant> args; + if (argc) { + args.reset(new NPVariant[argc]); + for (uint32_t i = 0; i < argc; ++i) + args[i] = PPVarToNPVariantNoCopy(argv[i]); + } + + NPVariant result; + if (!WebBindings::construct(NULL, object, args.get(), argc, &result)) { + // An exception may have been raised. + if (!try_catch.HasException()) + try_catch.SetException(kUnableToConstructException); + return PP_MakeVoid(); + } + + PP_Var ret = NPVariantToPPVar(&result); + WebBindings::releaseVariantValue(&result); + return ret; +} + +bool IsInstanceOf(PP_Var var, const PPP_Class* ppp_class, + void** ppp_class_data) { + NPObject* object = GetNPObject(var); + if (!object) + return false; + + if (object->_class != &wrapper_class) + return false; + + WrapperObject* wrapper = ToWrapper(object); + if (wrapper->ppp_class != ppp_class) + return false; + + if (ppp_class_data) + *ppp_class_data = wrapper->ppp_class_data; + return true; +} + +PP_Var CreateObject(const PPP_Class* ppp_class, void* ppp_class_data) { + NPObject* object = + WebBindings::createObject(NULL, const_cast<NPClass*>(&wrapper_class)); + static_cast<WrapperObject*>(object)->ppp_class = ppp_class; + static_cast<WrapperObject*>(object)->ppp_class_data = ppp_class_data; + PP_Var ret = NPObjectToPPVar(object); + WebBindings::releaseObject(object); // Release reference from createObject + return ret; +} + +const PPB_Var var_interface = { + &AddRef, + &Release, + &VarFromUtf8, + &VarToUtf8, + &HasProperty, + &HasMethod, + &GetProperty, + &GetAllPropertyNames, + &SetProperty, + &RemoveProperty, + &Call, + &Construct, + &IsInstanceOf, + &CreateObject +}; + +} // namespace + +const PPB_Var* GetVarInterface() { + return &var_interface; +} + +PP_Var NPObjectToPPVar(NPObject* object) { + PP_Var ret; + ret.type = PP_VARTYPE_OBJECT; + ret.value.as_id = reinterpret_cast<intptr_t>(object); + WebBindings::retainObject(object); + return ret; +} + +NPObject* GetNPObject(PP_Var var) { + if (var.type != PP_VARTYPE_OBJECT) + return NULL; + return GetNPObjectUnchecked(var); +} + +PP_Var StringToPPVar(const std::string& str) { + DCHECK(IsStringUTF8(str)); + return VarFromUtf8(str.data(), str.size()); +} + +String* GetString(PP_Var var) { + if (var.type != PP_VARTYPE_STRING) + return NULL; + return GetStringUnchecked(var); +} + +} // namespace pepper |