summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authordarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-19 22:20:05 +0000
committerdarin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-19 22:20:05 +0000
commit518209e0679963a6916eac655925d9932fd3018d (patch)
tree1fe98d9ac1f39aaef55e10710d29735d2560c4a2 /webkit
parentc6934a9b4ffbbd30bba71a8dc8157b9f2335702f (diff)
downloadchromium_src-518209e0679963a6916eac655925d9932fd3018d.zip
chromium_src-518209e0679963a6916eac655925d9932fd3018d.tar.gz
chromium_src-518209e0679963a6916eac655925d9932fd3018d.tar.bz2
Add initial support for exceptions.
Move some code into the anonymous namespace since it doesn't need to be exposed outside of pepper_var.cc. R=brettw BUG=none TEST=To be written once the new framework is available. Review URL: http://codereview.chromium.org/2123009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47738 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/pepper_var.cc333
-rw-r--r--webkit/glue/plugins/pepper_var.h18
2 files changed, 211 insertions, 140 deletions
diff --git a/webkit/glue/plugins/pepper_var.cc b/webkit/glue/plugins/pepper_var.cc
index 23894f7..1620ccc2 100644
--- a/webkit/glue/plugins/pepper_var.cc
+++ b/webkit/glue/plugins/pepper_var.cc
@@ -11,6 +11,10 @@
#include "third_party/ppapi/c/ppb_var.h"
#include "third_party/WebKit/WebKit/chromium/public/WebBindings.h"
#include "webkit/glue/plugins/pepper_string.h"
+#include "v8/include/v8.h"
+
+// Uncomment to enable catching JS exceptions
+// #define HAVE_WEBBINDINGS_EXCEPTION_HANDLER 1
using WebKit::WebBindings;
@@ -18,6 +22,58 @@ namespace pepper {
namespace {
+PP_Var VarFromUtf8(const char* data, uint32_t len);
+
+// ---------------------------------------------------------------------------
+// Exceptions
+
+class TryCatch {
+ public:
+ TryCatch(PP_Var* exception) : exception_(exception) {
+#ifdef HAVE_WEBBINDINGS_EXCEPTION_HANDLER
+ WebBindings::pushExceptionHandler(&TryCatch::Catch, this);
+#endif
+ }
+
+ ~TryCatch() {
+#ifdef HAVE_WEBBINDINGS_EXCEPTION_HANDLER
+ WebBindings::popExceptionHandler();
+#endif
+ }
+
+ 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);
}
@@ -32,6 +88,116 @@ NPObject* GetNPObject(PP_Var var) {
return GetNPObjectUnchecked(var);
}
+// 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(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;
+ }
+}
+
+// ---------------------------------------------------------------------------
+// PPB_Var methods
+
void AddRef(PP_Var var) {
if (var.type == PP_VarType_String) {
GetStringUnchecked(var)->AddRef();
@@ -74,18 +240,19 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) {
bool HasProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return false;
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return false;
}
NPIdentifier identifier = PPVarToNPIdentifier(name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return false;
}
@@ -95,24 +262,27 @@ bool HasProperty(PP_Var var,
PP_Var GetProperty(PP_Var var,
PP_Var name,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return PP_MakeVoid();
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return PP_MakeVoid();
}
NPIdentifier identifier = PPVarToNPIdentifier(name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return PP_MakeVoid();
}
NPVariant result;
if (!WebBindings::getProperty(NULL, object, identifier, &result)) {
- // TODO(darin): raise exception
+ // An exception may have been raised.
+ if (!try_catch.HasException())
+ try_catch.SetException(kUnableToGetPropertyException);
return PP_MakeVoid();
}
@@ -125,54 +295,64 @@ void GetAllPropertyNames(PP_Var var,
uint32_t* property_count,
PP_Var** properties,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return;
- // TODO(darin)
+ // TODO(darin): Implement this method!
+ try_catch.SetException(kUnableToGetAllPropertiesException);
}
void SetProperty(PP_Var var,
PP_Var name,
PP_Var value,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return;
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return;
}
NPIdentifier identifier = PPVarToNPIdentifier(name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return;
}
NPVariant variant = PPVarToNPVariantNoCopy(value);
- WebBindings::setProperty(NULL, object, identifier, &variant);
+ 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) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return;
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return;
}
NPIdentifier identifier = PPVarToNPIdentifier(name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return;
}
- WebBindings::removeProperty(NULL, object, identifier);
+ if (!WebBindings::removeProperty(NULL, object, identifier)) {
+ if (!try_catch.HasException())
+ try_catch.SetException(kUnableToRemovePropertyException);
+ }
}
PP_Var Call(PP_Var var,
@@ -180,12 +360,13 @@ PP_Var Call(PP_Var var,
int32_t argc,
PP_Var* argv,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return PP_MakeVoid();
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return PP_MakeVoid();
}
@@ -195,7 +376,7 @@ PP_Var Call(PP_Var var,
} else {
identifier = PPVarToNPIdentifier(method_name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return PP_MakeVoid();
}
}
@@ -218,7 +399,9 @@ PP_Var Call(PP_Var var,
}
if (!ok) {
- // TODO(darin): raise exception
+ // An exception may have been raised.
+ if (!try_catch.HasException())
+ try_catch.SetException(kUnableToCallMethodException);
return PP_MakeVoid();
}
@@ -231,12 +414,13 @@ PP_Var Construct(PP_Var var,
int32_t argc,
PP_Var* argv,
PP_Var* exception) {
- if (exception && exception->type != PP_VarType_Void)
+ TryCatch try_catch(exception);
+ if (try_catch.HasException())
return PP_MakeVoid();
NPObject* object = GetNPObject(var);
if (!object) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidObjectException);
return PP_MakeVoid();
}
@@ -249,7 +433,9 @@ PP_Var Construct(PP_Var var,
NPVariant result;
if (!WebBindings::construct(NULL, object, args.get(), argc, &result)) {
- // TODO(darin): raise exception
+ // An exception may have been raised.
+ if (!try_catch.HasException())
+ try_catch.SetException(kUnableToConstructException);
return PP_MakeVoid();
}
@@ -260,7 +446,7 @@ PP_Var Construct(PP_Var var,
PP_Var CreateObject(const PPP_Class* object_class,
void* object_data) {
- return PP_MakeVoid(); // TODO(darin)
+ return PP_MakeVoid(); // TODO(darin): Implement this method!
}
const PPB_Var var_interface = {
@@ -292,101 +478,4 @@ PP_Var NPObjectToPPVar(NPObject* object) {
return ret;
}
-PP_Var NPVariantToPPVar(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();
-}
-
-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;
-}
-
-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;
-}
-
-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;
- }
-}
-
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_var.h b/webkit/glue/plugins/pepper_var.h
index 6c8c6b5..4c5c221 100644
--- a/webkit/glue/plugins/pepper_var.h
+++ b/webkit/glue/plugins/pepper_var.h
@@ -22,24 +22,6 @@ const PPB_Var* GetVarInterface();
// function multiple times given the same NPObject results in the same PP_Var.
PP_Var NPObjectToPPVar(NPObject* object);
-// 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(NPVariant* variant);
-
-// 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);
-
-// 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);
-
-// 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);
-
} // namespace pepper
#endif // WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_