Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / pepper / pepper_try_catch.cc
index f5d8b3b..ec84369 100644 (file)
@@ -21,20 +21,19 @@ const char kInvalidException[] = "Error: An invalid exception was thrown.";
 }  // 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>();
@@ -43,13 +42,13 @@ v8::Handle<v8::Value> PepperTryCatch::ToV8(PP_Var var) {
 }
 
 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();
@@ -58,15 +57,18 @@ ppapi::ScopedPPVar PepperTryCatch::FromV8(v8::Handle<v8::Value> v8_value) {
 }
 
 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() {
@@ -74,13 +76,23 @@ 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)
@@ -99,47 +111,60 @@ void PepperTryCatchV8::ThrowException(const char* message) {
 }
 
 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;