Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Unified Diff: webkit/glue/plugins/pepper_var.cc

Issue 2123009: Add initial support for exceptions.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/glue/plugins/pepper_var.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/glue/plugins/pepper_var.cc
===================================================================
--- webkit/glue/plugins/pepper_var.cc (revision 47484)
+++ webkit/glue/plugins/pepper_var.cc (working copy)
@@ -11,13 +11,69 @@
#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;
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} else {
identifier = PPVarToNPIdentifier(method_name);
if (!identifier) {
- // TODO(darin): raise exception
+ try_catch.SetException(kInvalidPropertyException);
return PP_MakeVoid();
}
}
@@ -218,7 +399,9 @@
}
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 @@
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 @@
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 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 @@
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
« no previous file with comments | « webkit/glue/plugins/pepper_var.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698