cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / ppapi / native_client / src / trusted / plugin / scriptable_plugin.cc
blob5e395675aeb80b81f53f268398440dcae6607bdd
1 // Copyright (c) 2012 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 // Scriptable plugin implementation.
7 #include "ppapi/native_client/src/trusted/plugin/scriptable_plugin.h"
9 #include <string.h>
11 #include <sstream>
12 #include <string>
13 #include <vector>
15 #include "native_client/src/include/nacl_macros.h"
16 #include "native_client/src/include/nacl_string.h"
17 #include "native_client/src/include/portability.h"
18 #include "native_client/src/shared/platform/nacl_check.h"
19 #include "native_client/src/shared/srpc/nacl_srpc.h"
20 #include "ppapi/native_client/src/trusted/plugin/plugin.h"
21 #include "ppapi/native_client/src/trusted/plugin/utility.h"
24 namespace plugin {
26 namespace {
28 pp::Var Error(const nacl::string& call_name, const char* caller,
29 const char* error, pp::Var* exception) {
30 nacl::stringstream error_stream;
31 error_stream << call_name << ": " << error;
32 if (!exception->is_undefined()) {
33 error_stream << " - " + exception->AsString();
35 // Get the error string in 2 steps; otherwise, the temporary string returned
36 // by the stream is destructed, causing a dangling pointer.
37 std::string str = error_stream.str();
38 const char* e = str.c_str();
39 PLUGIN_PRINTF(("ScriptablePlugin::%s (%s)\n", caller, e));
40 *exception = pp::Var(e);
41 return pp::Var();
44 // In JavaScript, foo[1] is equivalent to foo["1"], so map both indexed and
45 // string names to a string.
46 nacl::string NameAsString(const pp::Var& name) {
47 if (name.is_string())
48 return name.AsString();
49 CHECK(name.is_int());
50 nacl::stringstream namestream;
51 namestream << name.AsInt();
52 return namestream.str();
55 // Returns a pp::Var corresponding to |arg| or void. Sets |exception| on error.
56 pp::Var NaClSrpcArgToPPVar(const NaClSrpcArg* arg, pp::Var* exception) {
57 PLUGIN_PRINTF((" NaClSrpcArgToPPVar (arg->tag='%c')\n", arg->tag));
58 pp::Var var;
59 switch (arg->tag) {
60 case NACL_SRPC_ARG_TYPE_BOOL:
61 var = pp::Var(arg->u.bval != 0);
62 break;
63 case NACL_SRPC_ARG_TYPE_DOUBLE:
64 var = pp::Var(arg->u.dval);
65 break;
66 case NACL_SRPC_ARG_TYPE_INT:
67 var = pp::Var(arg->u.ival);
68 break;
69 case NACL_SRPC_ARG_TYPE_LONG:
70 // PPAPI does not have a 64-bit integral type. Downcast.
71 var = pp::Var(static_cast<int32_t>(arg->u.lval));
72 break;
73 case NACL_SRPC_ARG_TYPE_STRING:
74 var = pp::Var(arg->arrays.str);
75 break;
76 case NACL_SRPC_ARG_TYPE_CHAR_ARRAY:
77 case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY:
78 case NACL_SRPC_ARG_TYPE_INT_ARRAY:
79 case NACL_SRPC_ARG_TYPE_LONG_ARRAY:
80 case NACL_SRPC_ARG_TYPE_OBJECT:
81 case NACL_SRPC_ARG_TYPE_HANDLE:
82 case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY:
83 case NACL_SRPC_ARG_TYPE_INVALID:
84 default:
85 *exception = "variant array and invalid argument types are not supported";
87 PLUGIN_PRINTF((" NaClSrpcArgToPPVar (return var=%s, exception=%s)\n",
88 var.DebugString().c_str(), exception->DebugString().c_str()));
89 return var;
92 } // namespace
94 ScriptablePlugin::ScriptablePlugin(Plugin* plugin)
95 : var_(NULL), num_unref_calls_(0), plugin_(plugin) {
96 PLUGIN_PRINTF(("ScriptablePlugin::ScriptablePlugin (this=%p, plugin=%p)\n",
97 static_cast<void*>(this),
98 static_cast<void*>(plugin)));
101 ScriptablePlugin::~ScriptablePlugin() {
102 PLUGIN_PRINTF(("ScriptablePlugin::~ScriptablePlugin (this=%p)\n",
103 static_cast<void*>(this)));
104 PLUGIN_PRINTF(("ScriptablePlugin::~ScriptablePlugin (this=%p, return)\n",
105 static_cast<void*>(this)));
108 void ScriptablePlugin::Unref(ScriptablePlugin** handle) {
109 if (*handle != NULL) {
110 (*handle)->Unref();
111 *handle = NULL;
115 ScriptablePlugin* ScriptablePlugin::NewPlugin(Plugin* plugin) {
116 PLUGIN_PRINTF(("ScriptablePlugin::NewPlugin (plugin=%p)\n",
117 static_cast<void*>(plugin)));
118 if (plugin == NULL) {
119 return NULL;
121 ScriptablePlugin* scriptable_plugin = new ScriptablePlugin(plugin);
122 if (scriptable_plugin == NULL) {
123 return NULL;
125 PLUGIN_PRINTF(("ScriptablePlugin::NewPlugin (return %p)\n",
126 static_cast<void*>(scriptable_plugin)));
127 return scriptable_plugin;
130 bool ScriptablePlugin::HasProperty(const pp::Var& name, pp::Var* exception) {
131 UNREFERENCED_PARAMETER(exception);
132 PLUGIN_PRINTF(("ScriptablePlugin::HasProperty (this=%p, name=%s)\n",
133 static_cast<void*>(this), name.DebugString().c_str()));
134 if (plugin_ == NULL) {
135 return false;
137 if (!name.is_string() && !name.is_int())
138 return false;
139 bool has_property = plugin_->HasProperty(name.AsString());
140 PLUGIN_PRINTF(("ScriptablePlugin::HasProperty (has_property=%d)\n",
141 has_property));
142 return has_property;
146 bool ScriptablePlugin::HasMethod(const pp::Var& name, pp::Var* exception) {
147 UNREFERENCED_PARAMETER(exception);
148 PLUGIN_PRINTF(("ScriptablePlugin::HasMethod (this=%p, name='%s')\n",
149 static_cast<void*>(this), name.DebugString().c_str()));
150 return false;
154 pp::Var ScriptablePlugin::GetProperty(const pp::Var& name,
155 pp::Var* exception) {
156 PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (name=%s)\n",
157 name.DebugString().c_str()));
158 if (plugin_ == NULL) {
159 return pp::Var();
161 // Get the property.
162 NaClSrpcArg prop_value;
163 nacl::string prop_name = NameAsString(name);
164 if (!plugin_->GetProperty(prop_name, &prop_value)) {
165 return Error(prop_name, "GetProperty", "invocation failed", exception);
167 PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (invocation done)\n"));
168 // Marshall output parameter.
169 pp::Var property = NaClSrpcArgToPPVar(&prop_value, exception);
170 if (!exception->is_undefined()) {
171 return Error(prop_name, "GetProperty", "output marshalling failed",
172 exception);
174 PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (property=%s)\n",
175 property.DebugString().c_str()));
176 return property;
180 void ScriptablePlugin::SetProperty(const pp::Var& name,
181 const pp::Var& value,
182 pp::Var* exception) {
183 PLUGIN_PRINTF(("ScriptablePlugin::SetProperty (name=%s, value=%s)\n",
184 name.DebugString().c_str(), value.DebugString().c_str()));
185 Error("SetProperty", name.DebugString().c_str(),
186 "property setting is not supported", exception);
190 void ScriptablePlugin::RemoveProperty(const pp::Var& name,
191 pp::Var* exception) {
192 PLUGIN_PRINTF(("ScriptablePlugin::RemoveProperty (name=%s)\n",
193 name.DebugString().c_str()));
194 Error(NameAsString(name), "RemoveProperty",
195 "property removal is not supported", exception);
198 void ScriptablePlugin::GetAllPropertyNames(std::vector<pp::Var>* properties,
199 pp::Var* exception) {
200 PLUGIN_PRINTF(("ScriptablePlugin::GetAllPropertyNames ()\n"));
201 UNREFERENCED_PARAMETER(properties);
202 UNREFERENCED_PARAMETER(exception);
203 Error("GetAllPropertyNames", "", "GetAllPropertyNames is not supported",
204 exception);
208 pp::Var ScriptablePlugin::Call(const pp::Var& name,
209 const std::vector<pp::Var>& args,
210 pp::Var* exception) {
211 PLUGIN_PRINTF(("ScriptablePlugin::Call (name=%s, %" NACL_PRIuS
212 " args)\n", name.DebugString().c_str(), args.size()));
213 return Error("Call", name.DebugString().c_str(),
214 "method invocation is not supported", exception);
218 pp::Var ScriptablePlugin::Construct(const std::vector<pp::Var>& args,
219 pp::Var* exception) {
220 PLUGIN_PRINTF(("ScriptablePlugin::Construct (%" NACL_PRIuS
221 " args)\n", args.size()));
222 return Error("constructor", "Construct", "constructor is not supported",
223 exception);
227 ScriptablePlugin* ScriptablePlugin::AddRef() {
228 // This is called when we are about to share this object with the browser,
229 // and we need to make sure we have an internal plugin reference, so this
230 // object doesn't get deallocated when the browser discards its references.
231 if (var_ == NULL) {
232 var_ = new pp::VarPrivate(plugin_, this);
233 CHECK(var_ != NULL);
235 PLUGIN_PRINTF(("ScriptablePlugin::AddRef (this=%p, var=%p)\n",
236 static_cast<void*>(this), static_cast<void*>(var_)));
237 return this;
241 void ScriptablePlugin::Unref() {
242 // We should have no more than one internal owner of this object, so this
243 // should be called no more than once.
244 CHECK(++num_unref_calls_ == 1);
245 PLUGIN_PRINTF(("ScriptablePlugin::Unref (this=%p, var=%p)\n",
246 static_cast<void*>(this), static_cast<void*>(var_)));
247 if (var_ != NULL) {
248 // We have shared this with the browser while keeping our own var
249 // reference, but we no longer need ours. If the browser has copies,
250 // it will clean things up later, otherwise this object will get
251 // deallocated right away.
252 PLUGIN_PRINTF(("ScriptablePlugin::Unref (delete var)\n"));
253 pp::Var* var = var_;
254 var_ = NULL;
255 delete var;
256 } else {
257 // Neither the browser nor plugin ever var referenced this object,
258 // so it can safely discarded.
259 PLUGIN_PRINTF(("ScriptablePlugin::Unref (delete this)\n"));
260 CHECK(var_ == NULL);
261 delete this;
266 } // namespace plugin