} // namespace
PepperTryCatch::PepperTryCatch(PepperPluginInstanceImpl* instance,
- bool convert_objects)
- : instance_(instance),
- convert_objects_(convert_objects) {}
+ V8VarConverter* var_converter)
+ : instance_(instance), var_converter_(var_converter) {}
PepperTryCatch::~PepperTryCatch() {}
-v8::Handle<v8::Context> PepperTryCatch::GetContext() {
- return instance_->GetContext();
-}
-
v8::Handle<v8::Value> PepperTryCatch::ToV8(PP_Var var) {
- V8VarConverter converter(instance_->pp_instance(), convert_objects_);
+ if (HasException()) {
+ SetException(kConversionException);
+ return v8::Handle<v8::Value>();
+ }
+
v8::Handle<v8::Value> result;
- bool success = converter.ToV8Value(var, GetContext(), &result);
+ bool success = var_converter_->ToV8Value(var, GetContext(), &result);
if (!success) {
SetException(kConversionException);
return v8::Handle<v8::Value>();
}
ppapi::ScopedPPVar PepperTryCatch::FromV8(v8::Handle<v8::Value> v8_value) {
- if (v8_value.IsEmpty()) {
+ if (HasException() || v8_value.IsEmpty()) {
SetException(kConversionException);
return ppapi::ScopedPPVar();
}
ppapi::ScopedPPVar result;
- V8VarConverter converter(instance_->pp_instance(), convert_objects_);
- bool success = converter.FromV8ValueSync(v8_value, GetContext(), &result);
+ bool success =
+ var_converter_->FromV8ValueSync(v8_value, GetContext(), &result);
if (!success) {
SetException(kConversionException);
return ppapi::ScopedPPVar();
}
PepperTryCatchV8::PepperTryCatchV8(PepperPluginInstanceImpl* instance,
- bool convert_objects,
+ V8VarConverter* var_converter,
v8::Isolate* isolate)
- : PepperTryCatch(instance, convert_objects),
+ : PepperTryCatch(instance, var_converter),
exception_(PP_MakeUndefined()) {
// Typically when using PepperTryCatchV8 we are passed an isolate. We verify
// that this isolate is the same as the plugin isolate.
DCHECK(isolate == instance_->GetIsolate());
- // We assume we are already in the plugin context for PepperTryCatchV8.
- DCHECK(GetContext() == isolate->GetCurrentContext());
+
+ // We assume that a handle scope and context has been setup by the user of
+ // this class. This is typically true because this class is used when calling
+ // into the plugin from JavaScript. We want to use whatever v8 context the
+ // caller is in.
}
PepperTryCatchV8::~PepperTryCatchV8() {
}
bool PepperTryCatchV8::HasException() {
- return exception_.type != PP_VARTYPE_UNDEFINED;
+ return GetContext().IsEmpty() || exception_.type != PP_VARTYPE_UNDEFINED;
+}
+
+v8::Handle<v8::Context> PepperTryCatchV8::GetContext() {
+ // When calling from JS into the plugin always use the current context.
+ return instance_->GetIsolate()->GetCurrentContext();
}
bool PepperTryCatchV8::ThrowException() {
if (!HasException())
return false;
+ // If there is no context then we have an exception but we don't try to throw
+ // it into v8.
+ if (GetContext().IsEmpty())
+ return true;
+
std::string message(kInvalidException);
ppapi::StringVar* message_var = ppapi::StringVar::FromPPVar(exception_);
if (message_var)
}
void PepperTryCatchV8::SetException(const char* message) {
- if (HasException()) {
- NOTREACHED();
+ if (HasException())
return;
- }
+
exception_ = ppapi::StringVar::StringToPPVar(message);
}
PepperTryCatchVar::PepperTryCatchVar(PepperPluginInstanceImpl* instance,
- bool convert_objects,
+ V8VarConverter* var_converter,
PP_Var* exception)
- : PepperTryCatch(instance, convert_objects),
+ : PepperTryCatch(instance, var_converter),
handle_scope_(instance_->GetIsolate()),
+ context_(GetContext()),
exception_(exception),
exception_is_set_(false) {
- // We switch to the plugin context.
- GetContext()->Enter();
+ // We switch to the plugin context if it's not empty.
+ if (!context_.IsEmpty())
+ context_->Enter();
}
PepperTryCatchVar::~PepperTryCatchVar() {
- GetContext()->Exit();
+ if (!context_.IsEmpty())
+ context_->Exit();
}
bool PepperTryCatchVar::HasException() {
- // Check if a v8 exception was caught.
- if (!exception_is_set_ && try_catch_.HasCaught()) {
+ if (exception_is_set_)
+ return true;
+
+ std::string exception_message;
+ if (GetContext().IsEmpty()) {
+ exception_message = "The v8 context has been destroyed.";
+ } else if (try_catch_.HasCaught()) {
v8::String::Utf8Value utf8(try_catch_.Message()->Get());
- if (exception_) {
- *exception_ = ppapi::StringVar::StringToPPVar(
- std::string(*utf8, utf8.length()));
- }
+ exception_message = std::string(*utf8, utf8.length());
+ }
+
+ if (!exception_message.empty()) {
exception_is_set_ = true;
+ if (exception_)
+ *exception_ = ppapi::StringVar::StringToPPVar(exception_message);
}
return exception_is_set_;
}
+v8::Handle<v8::Context> PepperTryCatchVar::GetContext() {
+ // When calling into JS from the plugin, always use the plugin context.
+ return instance_->GetMainWorldContext();
+}
+
void PepperTryCatchVar::SetException(const char* message) {
- if (exception_is_set_) {
- NOTREACHED();
+ if (exception_is_set_)
return;
- }
+
if (exception_)
*exception_ = ppapi::StringVar::StringToPPVar(message, strlen(message));
exception_is_set_ = true;