1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/pepper/pepper_try_catch.h"
7 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
8 #include "content/renderer/pepper/v8_var_converter.h"
9 #include "gin/converter.h"
10 #include "ppapi/shared_impl/ppapi_globals.h"
11 #include "ppapi/shared_impl/var_tracker.h"
17 const char kConversionException
[] =
18 "Error: Failed conversion between PP_Var and V8 value";
19 const char kInvalidException
[] = "Error: An invalid exception was thrown.";
23 PepperTryCatch::PepperTryCatch(PepperPluginInstanceImpl
* instance
,
24 V8VarConverter
* var_converter
)
25 : instance_(instance
), var_converter_(var_converter
) {}
27 PepperTryCatch::~PepperTryCatch() {}
29 v8::Handle
<v8::Value
> PepperTryCatch::ToV8(PP_Var var
) {
31 SetException(kConversionException
);
32 return v8::Handle
<v8::Value
>();
35 v8::Handle
<v8::Value
> result
;
36 bool success
= var_converter_
->ToV8Value(var
, GetContext(), &result
);
38 SetException(kConversionException
);
39 return v8::Handle
<v8::Value
>();
44 ppapi::ScopedPPVar
PepperTryCatch::FromV8(v8::Handle
<v8::Value
> v8_value
) {
45 if (HasException() || v8_value
.IsEmpty()) {
46 SetException(kConversionException
);
47 return ppapi::ScopedPPVar();
49 ppapi::ScopedPPVar result
;
51 var_converter_
->FromV8ValueSync(v8_value
, GetContext(), &result
);
53 SetException(kConversionException
);
54 return ppapi::ScopedPPVar();
59 PepperTryCatchV8::PepperTryCatchV8(PepperPluginInstanceImpl
* instance
,
60 V8VarConverter
* var_converter
,
62 : PepperTryCatch(instance
, var_converter
),
63 exception_(PP_MakeUndefined()) {
64 // Typically when using PepperTryCatchV8 we are passed an isolate. We verify
65 // that this isolate is the same as the plugin isolate.
66 DCHECK(isolate
== instance_
->GetIsolate());
68 // We assume that a handle scope and context has been setup by the user of
69 // this class. This is typically true because this class is used when calling
70 // into the plugin from JavaScript. We want to use whatever v8 context the
74 PepperTryCatchV8::~PepperTryCatchV8() {
75 ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(exception_
);
78 bool PepperTryCatchV8::HasException() {
79 return GetContext().IsEmpty() || exception_
.type
!= PP_VARTYPE_UNDEFINED
;
82 v8::Handle
<v8::Context
> PepperTryCatchV8::GetContext() {
83 // When calling from JS into the plugin always use the current context.
84 return instance_
->GetIsolate()->GetCurrentContext();
87 bool PepperTryCatchV8::ThrowException() {
91 // If there is no context then we have an exception but we don't try to throw
93 if (GetContext().IsEmpty())
96 std::string
message(kInvalidException
);
97 ppapi::StringVar
* message_var
= ppapi::StringVar::FromPPVar(exception_
);
99 message
= message_var
->value();
100 instance_
->GetIsolate()->ThrowException(v8::Exception::Error(
101 gin::StringToV8(instance_
->GetIsolate(), message
)));
103 ppapi::PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(exception_
);
104 exception_
= PP_MakeUndefined();
108 void PepperTryCatchV8::ThrowException(const char* message
) {
109 SetException(message
);
113 void PepperTryCatchV8::SetException(const char* message
) {
117 exception_
= ppapi::StringVar::StringToPPVar(message
);
120 PepperTryCatchVar::PepperTryCatchVar(PepperPluginInstanceImpl
* instance
,
121 V8VarConverter
* var_converter
,
123 : PepperTryCatch(instance
, var_converter
),
124 handle_scope_(instance_
->GetIsolate()),
125 context_(GetContext()),
126 exception_(exception
),
127 exception_is_set_(false) {
128 // We switch to the plugin context if it's not empty.
129 if (!context_
.IsEmpty())
133 PepperTryCatchVar::~PepperTryCatchVar() {
134 if (!context_
.IsEmpty())
138 bool PepperTryCatchVar::HasException() {
139 if (exception_is_set_
)
142 std::string exception_message
;
143 if (GetContext().IsEmpty()) {
144 exception_message
= "The v8 context has been destroyed.";
145 } else if (try_catch_
.HasCaught()) {
146 v8::String::Utf8Value
utf8(try_catch_
.Message()->Get());
147 exception_message
= std::string(*utf8
, utf8
.length());
150 if (!exception_message
.empty()) {
151 exception_is_set_
= true;
153 *exception_
= ppapi::StringVar::StringToPPVar(exception_message
);
156 return exception_is_set_
;
159 v8::Handle
<v8::Context
> PepperTryCatchVar::GetContext() {
160 // When calling into JS from the plugin, always use the plugin context.
161 return instance_
->GetMainWorldContext();
164 void PepperTryCatchVar::SetException(const char* message
) {
165 if (exception_is_set_
)
169 *exception_
= ppapi::StringVar::StringToPPVar(message
, strlen(message
));
170 exception_is_set_
= true;
173 } // namespace content