summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorneb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-25 18:23:32 +0000
committerneb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-25 18:23:32 +0000
commite340dd3131637817f78de99896f9a2fccfc6dbba (patch)
treef4089bb5aa66753fddea0d05530bd9e6ebc831ee /webkit
parentd78a6c99e67e2b89506ab666870f8d3e43e9ef4a (diff)
downloadchromium_src-e340dd3131637817f78de99896f9a2fccfc6dbba.zip
chromium_src-e340dd3131637817f78de99896f9a2fccfc6dbba.tar.gz
chromium_src-e340dd3131637817f78de99896f9a2fccfc6dbba.tar.bz2
PPB_Var implementation, Chrome side.
This implements the new PPB_Var interface on pepper. BUG=57613 TEST=ppapi_tests, yet uncommitted. Review URL: http://codereview.chromium.org/3801006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63752 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc3
-rw-r--r--webkit/glue/plugins/pepper_var.cc230
-rw-r--r--webkit/glue/plugins/pepper_var.h4
3 files changed, 235 insertions, 2 deletions
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index 13390d5..52a8916 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -44,6 +44,7 @@
#include "third_party/ppapi/c/ppb_graphics_2d.h"
#include "third_party/ppapi/c/ppb_image_data.h"
#include "third_party/ppapi/c/ppb_instance.h"
+#include "third_party/ppapi/c/ppb_var.h"
#include "third_party/ppapi/c/ppp.h"
#include "third_party/ppapi/c/ppp_instance.h"
#include "webkit/glue/plugins/pepper_audio.h"
@@ -199,6 +200,8 @@ const void* GetInterface(const char* name) {
return &core_interface;
if (strcmp(name, PPB_VAR_DEPRECATED_INTERFACE) == 0)
return Var::GetDeprecatedInterface();
+ if (strcmp(name, PPB_VAR_INTERFACE) == 0)
+ return Var::GetInterface();
if (strcmp(name, PPB_INSTANCE_INTERFACE) == 0)
return PluginInstance::GetInterface();
if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc
index 6daece9..b9d019d 100644
--- a/webkit/glue/plugins/pepper_var.cc
+++ b/webkit/glue/plugins/pepper_var.cc
@@ -4,12 +4,16 @@
#include "webkit/glue/plugins/pepper_var.h"
+#include <limits>
+
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "third_party/ppapi/c/dev/ppb_var_deprecated.h"
+#include "third_party/ppapi/c/ppb_var.h"
#include "third_party/ppapi/c/pp_var.h"
#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
#include "webkit/glue/plugins/pepper_plugin_module.h"
#include "webkit/glue/plugins/pepper_plugin_object.h"
#include "v8/include/v8.h"
@@ -154,6 +158,63 @@ class ObjectAccessorWithIdentifierTryCatch : public ObjectAccessorTryCatch {
DISALLOW_COPY_AND_ASSIGN(ObjectAccessorWithIdentifierTryCatch);
};
+PP_Var RunJSFunction(PP_Var scope_var,
+ const char* function_script,
+ PP_Var* argv,
+ unsigned argc,
+ PP_Var* exception) {
+ TryCatch try_catch(NULL, exception);
+ if (try_catch.has_exception())
+ return PP_MakeUndefined();
+
+ scoped_refptr<ObjectVar> obj = ObjectVar::FromPPVar(scope_var);
+ if (!obj) {
+ try_catch.SetInvalidObjectException();
+ return PP_MakeUndefined();
+ }
+
+ try_catch.set_module(obj->module());
+
+ scoped_array<NPVariant> args;
+ if (argc) {
+ args.reset(new NPVariant[argc]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ try_catch.SetException(kInvalidValueException);
+ return PP_MakeUndefined();
+ }
+ }
+ }
+
+ NPVariant function_var;
+ VOID_TO_NPVARIANT(function_var);
+ NPString function_string = { function_script, strlen(function_script) };
+ if (!WebBindings::evaluate(NULL, obj->np_object(), &function_string,
+ &function_var)) {
+ try_catch.SetException(kInvalidValueException);
+ return PP_MakeUndefined();
+ }
+ DCHECK(NPVARIANT_IS_OBJECT(function_var));
+ DCHECK(!try_catch.has_exception());
+
+ NPVariant result_var;
+ VOID_TO_NPVARIANT(result_var);
+ PP_Var result;
+
+ if (WebBindings::invokeDefault(NULL, NPVARIANT_TO_OBJECT(function_var),
+ args.get(), argc, &result_var)) {
+ result = Var::NPVariantToPPVar(obj->module(), &result_var);
+ } else {
+ DCHECK(try_catch.has_exception());
+ result = PP_MakeUndefined();
+ }
+
+ WebBindings::releaseVariantValue(&function_var);
+ WebBindings::releaseVariantValue(&result_var);
+ return result;
+}
+
// PPB_Var methods -------------------------------------------------------------
PP_Var VarFromUtf8(PP_Module module_id, const char* data, uint32_t len) {
@@ -175,6 +236,99 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) {
return str->value().data();
}
+PP_Var ConvertType(PP_Instance instance,
+ struct PP_Var var,
+ PP_VarType new_type,
+ PP_Var* exception) {
+ TryCatch try_catch(NULL, exception);
+ if (try_catch.has_exception())
+ return PP_MakeUndefined();
+
+ if (var.type == new_type)
+ return var;
+
+ PluginInstance* plugin_instance =
+ ResourceTracker::Get()->GetInstance(instance);
+ if (!plugin_instance) {
+ try_catch.SetInvalidObjectException();
+ return PP_MakeUndefined();
+ }
+
+ try_catch.set_module(plugin_instance->module());
+ PP_Var object = plugin_instance->GetWindowObject();
+
+ PP_Var params[] = {
+ var,
+ PP_MakeInt32(new_type),
+ PP_MakeInt32(PP_VARTYPE_NULL),
+ PP_MakeInt32(PP_VARTYPE_BOOL),
+ PP_MakeInt32(PP_VARTYPE_INT32),
+ PP_MakeInt32(PP_VARTYPE_DOUBLE),
+ PP_MakeInt32(PP_VARTYPE_STRING),
+ PP_MakeInt32(PP_VARTYPE_OBJECT)
+ };
+ PP_Var result = RunJSFunction(object,
+ "(function(v, new_type, type_null, type_bool, type_int32, type_double,"
+ " type_string, type_object) {"
+ " switch(new_type) {"
+ " case type_null: return null;"
+ " case type_bool: return Boolean(v);"
+ " case type_int32: case type_double: return Number(v);"
+ " case type_string: return String(v);"
+ " case type_object: return Object(v);"
+ " default: return undefined;"
+ " }})",
+ params, sizeof(params) / sizeof(PP_Var), exception);
+
+ // Massage Number into the correct type.
+ if (new_type == PP_VARTYPE_INT32 && result.type == PP_VARTYPE_DOUBLE) {
+ double value = result.value.as_double;
+ // Exclusive test wouldn't deal with NaNs correctly.
+ if (value >= std::numeric_limits<int32_t>::max()
+ && value <= std::numeric_limits<int32_t>::min())
+ result = PP_MakeInt32(static_cast<int32_t>(value));
+ else
+ result = PP_MakeInt32(0);
+ } else if (new_type == PP_VARTYPE_DOUBLE && result.type == PP_VARTYPE_INT32) {
+ result = PP_MakeDouble(result.value.as_int);
+ }
+
+ Var::PluginReleasePPVar(object);
+ return result;
+}
+
+void DefineProperty(struct PP_Var object,
+ struct PP_ObjectProperty property,
+ PP_Var* exception) {
+ PP_Var params[] = {
+ object, property.name,
+ PP_MakeBool(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_HASVALUE)),
+ property.value,
+ PP_MakeBool(property.getter.type == PP_VARTYPE_OBJECT),
+ property.getter,
+ PP_MakeBool(property.setter.type == PP_VARTYPE_OBJECT),
+ property.setter,
+ PP_MakeBool(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_READONLY)),
+ PP_MakeBool(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTDELETE)),
+ PP_MakeBool(!!(property.modifiers & PP_OBJECTPROPERTY_MODIFIER_DONTENUM))
+ };
+
+ RunJSFunction(object,
+ "(function(o, name,"
+ " has_value, value,"
+ " has_getter, getter,"
+ " has_setter, setter,"
+ " modifier_readonly, modifier_dontdelete, modifier_dontenum) {"
+ " prop = { 'enumerable': !modifier_dontenum,"
+ " 'configurable': !modifier_dontdelete };"
+ " if (has_value && !modifier_readonly) prop.writable = true;"
+ " if (has_value) prop.value = value;"
+ " if (has_getter) prop.get = getter;"
+ " if (has_setter) prop.set = setter;"
+ " return Object.defineProperty(o, name, prop); })",
+ params, sizeof(params) / sizeof(PP_Var), exception);
+}
+
bool HasProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
@@ -264,11 +418,22 @@ void SetPropertyDeprecated(PP_Var var,
accessor.SetException(kUnableToSetPropertyException);
}
-void DeleteProperty(PP_Var var,
+bool DeleteProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
if (accessor.has_exception())
+ return false;
+
+ return WebBindings::removeProperty(NULL, accessor.object()->np_object(),
+ accessor.identifier());
+}
+
+void DeletePropertyDeprecated(PP_Var var,
+ PP_Var name,
+ PP_Var* exception) {
+ ObjectAccessorWithIdentifierTryCatch accessor(var, name, exception);
+ if (accessor.has_exception())
return;
if (!WebBindings::removeProperty(NULL, accessor.object()->np_object(),
@@ -276,6 +441,46 @@ void DeleteProperty(PP_Var var,
accessor.SetException(kUnableToRemovePropertyException);
}
+bool IsCallable(struct PP_Var object) {
+ PP_Var result = RunJSFunction(object,
+ "(function() { return typeof(this) == 'function' })", NULL, 0, NULL);
+ return result.type == PP_VARTYPE_BOOL && result.value.as_bool;
+}
+
+struct PP_Var Call(struct PP_Var object,
+ struct PP_Var this_object,
+ uint32_t argc,
+ struct PP_Var* argv,
+ struct PP_Var* exception) {
+ ObjectAccessorTryCatch accessor(object, exception);
+ if (accessor.has_exception())
+ return PP_MakeUndefined();
+
+ scoped_array<NPVariant> args;
+ if (argc) {
+ args.reset(new NPVariant[argc]);
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (!PPVarToNPVariantNoCopy(argv[i], &args[i])) {
+ // This argument was invalid, throw an exception & give up.
+ accessor.SetException(kInvalidValueException);
+ return PP_MakeUndefined();
+ }
+ }
+ }
+
+ NPVariant result;
+ if (!WebBindings::invokeDefault(NULL, accessor.object()->np_object(),
+ args.get(), argc, &result)) {
+ // An exception may have been raised.
+ accessor.SetException(kUnableToCallMethodException);
+ return PP_MakeUndefined();
+ }
+
+ PP_Var ret = Var::NPVariantToPPVar(accessor.module(), &result);
+ WebBindings::releaseVariantValue(&result);
+ return ret;
+}
+
PP_Var CallDeprecated(PP_Var var,
PP_Var method_name,
uint32_t argc,
@@ -397,13 +602,30 @@ const PPB_Var_Deprecated var_deprecated_interface = {
&GetProperty,
&EnumerateProperties,
&SetPropertyDeprecated,
- &DeleteProperty,
+ &DeletePropertyDeprecated,
&CallDeprecated,
&Construct,
&IsInstanceOfDeprecated,
&CreateObjectDeprecated
};
+const PPB_Var var_interface = {
+ &Var::PluginAddRefPPVar,
+ &Var::PluginReleasePPVar,
+ &VarFromUtf8,
+ &VarToUtf8,
+ &ConvertType,
+ &DefineProperty,
+ &HasProperty,
+ &GetProperty,
+ &DeleteProperty,
+ &EnumerateProperties,
+ &IsCallable,
+ &Call,
+ &Construct,
+};
+
+
} // namespace
// Var -------------------------------------------------------------------------
@@ -492,6 +714,10 @@ const PPB_Var_Deprecated* Var::GetDeprecatedInterface() {
return &var_deprecated_interface;
}
+const PPB_Var* Var::GetInterface() {
+ return &var_interface;
+}
+
// StringVar -------------------------------------------------------------------
StringVar::StringVar(PluginModule* module, const char* str, uint32 len)
diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h
index 0eb1807..8929448 100644
--- a/webkit/glue/plugins/pepper_var.h
+++ b/webkit/glue/plugins/pepper_var.h
@@ -10,6 +10,7 @@
#include "webkit/glue/plugins/pepper_resource.h"
struct PP_Var;
+struct PPB_Var;
struct PPB_Var_Deprecated;
typedef struct NPObject NPObject;
typedef struct _NPVariant NPVariant;
@@ -82,6 +83,9 @@ class Var : public Resource {
// Returns the PPB_Var_Deprecated interface for the plugin to use.
static const PPB_Var_Deprecated* GetDeprecatedInterface();
+ // Returns the PPB_Var interface for the plugin to use.
+ static const PPB_Var* GetInterface();
+
protected:
// This can only be constructed as a StringVar or an ObjectVar.
explicit Var(PluginModule* module);