diff options
author | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-27 18:39:19 +0000 |
---|---|---|
committer | teravest@chromium.org <teravest@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-27 18:39:19 +0000 |
commit | 0554b5d365446ffb5ab617edd27921ee9d9de31d (patch) | |
tree | 50b49038ee17d26a0a6a537ba21a2b2f7c10b2cb /ppapi/native_client | |
parent | 27b8d3b2ccd88b256dd378045a183cfe987e7140 (diff) | |
download | chromium_src-0554b5d365446ffb5ab617edd27921ee9d9de31d.zip chromium_src-0554b5d365446ffb5ab617edd27921ee9d9de31d.tar.gz chromium_src-0554b5d365446ffb5ab617edd27921ee9d9de31d.tar.bz2 |
Pepper: Refactor trusted plugin properties.
As part of the "trusted plugin refactor", we need to change properties on the
plugin's embed element to be set through an interface instead of PPAPI
scripting. This is one of a series of changes to carve up functionality in the
trusted plugin and move it elsewhere.
After this change, ScriptablePlugin doesn't seem very useful, but I'm not
completely sure if it (and PPP_Instance_Private) can be removed. I'll look at
that separately.
BUG=239656
Review URL: https://codereview.chromium.org/84773004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@237604 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/native_client')
6 files changed, 78 insertions, 178 deletions
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc index f348b0f..2bf3021 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/plugin.cc @@ -246,49 +246,6 @@ void HistogramHTTPStatusCode(const std::string& name, int status) { } // namespace -void Plugin::AddPropertyGet(const nacl::string& prop_name, - Plugin::PropertyGetter getter) { - PLUGIN_PRINTF(("Plugin::AddPropertyGet (prop_name='%s')\n", - prop_name.c_str())); - property_getters_[nacl::string(prop_name)] = getter; -} - -bool Plugin::HasProperty(const nacl::string& prop_name) { - PLUGIN_PRINTF(("Plugin::HasProperty (prop_name=%s)\n", - prop_name.c_str())); - return property_getters_.find(prop_name) != property_getters_.end(); -} - -bool Plugin::GetProperty(const nacl::string& prop_name, - NaClSrpcArg* prop_value) { - PLUGIN_PRINTF(("Plugin::GetProperty (prop_name=%s)\n", prop_name.c_str())); - - if (property_getters_.find(prop_name) == property_getters_.end()) { - return false; - } - PropertyGetter getter = property_getters_[prop_name]; - (this->*getter)(prop_value); - return true; -} - -void Plugin::GetExitStatus(NaClSrpcArg* prop_value) { - PLUGIN_PRINTF(("GetExitStatus (this=%p)\n", reinterpret_cast<void*>(this))); - prop_value->tag = NACL_SRPC_ARG_TYPE_INT; - prop_value->u.ival = exit_status(); -} - -void Plugin::GetLastError(NaClSrpcArg* prop_value) { - PLUGIN_PRINTF(("GetLastError (this=%p)\n", reinterpret_cast<void*>(this))); - prop_value->tag = NACL_SRPC_ARG_TYPE_STRING; - prop_value->arrays.str = strdup(last_error_string().c_str()); -} - -void Plugin::GetReadyStateProperty(NaClSrpcArg* prop_value) { - PLUGIN_PRINTF(("GetReadyState (this=%p)\n", reinterpret_cast<void*>(this))); - prop_value->tag = NACL_SRPC_ARG_TYPE_INT; - prop_value->u.ival = nacl_ready_state_; -} - bool Plugin::EarlyInit(int argc, const char* argn[], const char* argv[]) { PLUGIN_PRINTF(("Plugin::EarlyInit (instance=%p)\n", static_cast<void*>(this))); @@ -330,13 +287,6 @@ bool Plugin::EarlyInit(int argc, const char* argn[], const char* argv[]) { PLUGIN_PRINTF(("Plugin::Init (wrapper_factory=%p)\n", static_cast<void*>(wrapper_factory_))); - // Export a property to allow us to get the exit status of a nexe. - AddPropertyGet("exitStatus", &Plugin::GetExitStatus); - // Export a property to allow us to get the last error description. - AddPropertyGet("lastError", &Plugin::GetLastError); - // Export a property to allow us to get the ready state of a nexe during load. - AddPropertyGet("readyState", &Plugin::GetReadyStateProperty); - PLUGIN_PRINTF(("Plugin::Init (return 1)\n")); // Return success. return true; @@ -692,7 +642,6 @@ Plugin::Plugin(PP_Instance pp_instance) argn_(NULL), argv_(NULL), main_subprocess_("main subprocess", NULL, NULL), - nacl_ready_state_(UNSENT), nexe_error_reported_(false), wrapper_factory_(NULL), enable_dev_interfaces_(false), @@ -701,6 +650,7 @@ Plugin::Plugin(PP_Instance pp_instance) ready_time_(0), nexe_size_(0), time_of_last_progress_event_(0), + exit_status_(-1), nacl_interface_(NULL) { PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%" NACL_PRId32 ")\n", static_cast<void*>(this), pp_instance)); @@ -708,6 +658,11 @@ Plugin::Plugin(PP_Instance pp_instance) nexe_downloader_.Initialize(this); nacl_interface_ = GetNaClInterface(); CHECK(nacl_interface_ != NULL); + set_nacl_ready_state(UNSENT); + set_last_error_string(""); + // We call set_exit_status() here to ensure that the 'exitStatus' property is + // set. This can only be called when nacl_interface_ is not NULL. + set_exit_status(-1); } @@ -936,14 +891,13 @@ void Plugin::NexeDidCrash(int32_t pp_error) { " non-PP_OK arg -- SHOULD NOT HAPPEN\n")); } PLUGIN_PRINTF(("Plugin::NexeDidCrash: crash event!\n")); - int exit_status = main_subprocess_.service_runtime()->exit_status(); - if (-1 != exit_status) { + if (-1 != exit_status()) { // The NaCl module voluntarily exited. However, this is still a // crash from the point of view of Pepper, since PPAPI plugins are // event handlers and should never exit. PLUGIN_PRINTF((("Plugin::NexeDidCrash: nexe exited with status %d" " so this is a \"controlled crash\".\n"), - exit_status)); + exit_status())); } // If the crash occurs during load, we just want to report an error // that fits into our load progress event grammar. If the crash @@ -1164,7 +1118,7 @@ void Plugin::ProcessNaClManifest(const nacl::string& manifest_json) { if (manifest_->GetProgramURL(&program_url, &pnacl_options, &error_info)) { is_installed_ = GetUrlScheme(program_url) == SCHEME_CHROME_EXTENSION; - nacl_ready_state_ = LOADING; + set_nacl_ready_state(LOADING); // Inform JavaScript that we found a nexe URL to load. EnqueueProgressEvent(PP_NACL_EVENT_PROGRESS); if (pnacl_options.translate()) { @@ -1223,7 +1177,7 @@ void Plugin::RequestNaClManifest(const nacl::string& url) { set_manifest_base_url(nmf_resolved_url.AsString()); set_manifest_url(url); // Inform JavaScript that a load is starting. - nacl_ready_state_ = OPENED; + set_nacl_ready_state(OPENED); EnqueueProgressEvent(PP_NACL_EVENT_LOADSTART); bool is_data_uri = GetUrlScheme(nmf_resolved_url.AsString()) == SCHEME_DATA; HistogramEnumerateManifestIsDataURI(static_cast<int>(is_data_uri)); @@ -1342,7 +1296,7 @@ void Plugin::ReportLoadSuccess(LengthComputable length_computable, uint64_t loaded_bytes, uint64_t total_bytes) { // Set the readyState attribute to indicate loaded. - nacl_ready_state_ = DONE; + set_nacl_ready_state(DONE); // Inform JavaScript that loading was successful and is complete. const nacl::string& url = nexe_downloader_.url_to_open(); EnqueueProgressEvent( @@ -1369,7 +1323,7 @@ void Plugin::ReportLoadError(const ErrorInfo& error_info) { } // Set the readyState attribute to indicate we need to start over. - nacl_ready_state_ = DONE; + set_nacl_ready_state(DONE); set_nexe_error_reported(true); // Report an error in lastError and on the JavaScript console. nacl::string message = nacl::string("NaCl module load failed: ") + @@ -1389,7 +1343,7 @@ void Plugin::ReportLoadError(const ErrorInfo& error_info) { void Plugin::ReportLoadAbort() { PLUGIN_PRINTF(("Plugin::ReportLoadAbort\n")); // Set the readyState attribute to indicate we need to start over. - nacl_ready_state_ = DONE; + set_nacl_ready_state(DONE); set_nexe_error_reported(true); // Report an error in lastError and on the JavaScript console. nacl::string error_string("NaCl module load failed: user aborted"); @@ -1605,4 +1559,42 @@ void Plugin::AddToConsole(const nacl::string& text) { var_interface->Release(str); } +void Plugin::set_last_error_string(const nacl::string& error) { + DCHECK(nacl_interface_); + nacl_interface_->SetReadOnlyProperty(pp_instance(), + pp::Var("lastError").pp_var(), + pp::Var(error).pp_var()); +} + +void Plugin::set_nacl_ready_state(ReadyState state) { + nacl_ready_state_ = state; + DCHECK(nacl_interface_); + nacl_interface_->SetReadOnlyProperty(pp_instance(), + pp::Var("readyState").pp_var(), + pp::Var(state).pp_var()); +} + +void Plugin::set_exit_status(int exit_status) { + pp::Core* core = pp::Module::Get()->core(); + if (core->IsMainThread()) { + SetExitStatusOnMainThread(PP_OK, exit_status); + } else { + pp::CompletionCallback callback = + callback_factory_.NewCallback(&Plugin::SetExitStatusOnMainThread, + exit_status); + core->CallOnMainThread(0, callback, 0); + } +} + +void Plugin::SetExitStatusOnMainThread(int32_t pp_error, + int exit_status) { + DCHECK(pp::Module::Get()->core()->IsMainThread()); + DCHECK(nacl_interface_); + exit_status_ = exit_status; + nacl_interface_->SetReadOnlyProperty(pp_instance(), + pp::Var("exitStatus").pp_var(), + pp::Var(exit_status_).pp_var()); +} + + } // namespace plugin diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h index 401978d..ca83489 100644 --- a/ppapi/native_client/src/trusted/plugin/plugin.h +++ b/ppapi/native_client/src/trusted/plugin/plugin.h @@ -202,16 +202,6 @@ class Plugin : public pp::InstancePrivate { // Requests a NaCl manifest download from a |url| relative to the page origin. void RequestNaClManifest(const nacl::string& url); - // Support for property getting. - typedef void (Plugin::* PropertyGetter)(NaClSrpcArg* prop_value); - void AddPropertyGet(const nacl::string& prop_name, PropertyGetter getter); - bool HasProperty(const nacl::string& prop_name); - bool GetProperty(const nacl::string& prop_name, NaClSrpcArg* prop_value); - // The supported property getters. - void GetExitStatus(NaClSrpcArg* prop_value); - void GetLastError(NaClSrpcArg* prop_value); - void GetReadyStateProperty(NaClSrpcArg* prop_value); - // The size returned when a file download operation is unable to determine // the size of the file to load. W3C ProgressEvents specify that unknown // sizes return 0. @@ -241,11 +231,7 @@ class Plugin : public pp::InstancePrivate { // document to request the URL using CORS even if this function returns false. bool DocumentCanRequest(const std::string& url); - // Get the text description of the last error reported by the plugin. - const nacl::string& last_error_string() const { return last_error_string_; } - void set_last_error_string(const nacl::string& error) { - last_error_string_ = error; - } + void set_last_error_string(const nacl::string& error); // The MIME type used to instantiate this instance of the NaCl plugin. // Typically, the MIME type will be application/x-nacl. However, if the NEXE @@ -262,13 +248,9 @@ class Plugin : public pp::InstancePrivate { Manifest const* manifest() const { return manifest_.get(); } const pp::URLUtil_Dev* url_util() const { return url_util_; } - // Extracts the exit status from the (main) service runtime. - int exit_status() const { - if (NULL == main_service_runtime()) { - return -1; - } - return main_service_runtime()->exit_status(); - } + int exit_status() const { return exit_status_; } + // set_exit_status may be called off the main thread. + void set_exit_status(int exit_status); const PPB_NaCl_Private* nacl_interface() const { return nacl_interface_; } @@ -386,6 +368,10 @@ class Plugin : public pp::InstancePrivate { // request so it won't slow down non-installed file downloads. bool OpenURLFast(const nacl::string& url, FileDownloader* downloader); + void set_nacl_ready_state(ReadyState state); + + void SetExitStatusOnMainThread(int32_t pp_error, int exit_status); + ScriptablePlugin* scriptable_plugin_; int argc_; @@ -403,8 +389,6 @@ class Plugin : public pp::InstancePrivate { nacl::DescWrapperFactory* wrapper_factory_; - std::map<nacl::string, PropertyGetter> property_getters_; - // File download support. |nexe_downloader_| can be opened with a specific // callback to run when the file has been downloaded and is opened for // reading. We use one downloader for all URL downloads to prevent issuing @@ -421,10 +405,6 @@ class Plugin : public pp::InstancePrivate { // URL processing interface for use in looking up resources in manifests. const pp::URLUtil_Dev* url_util_; - // A string containing the text description of the last error - // produced by this plugin. - nacl::string last_error_string_; - // PPAPI Dev interfaces are disabled by default. bool enable_dev_interfaces_; @@ -482,6 +462,7 @@ class Plugin : public pp::InstancePrivate { const FileDownloader* FindFileDownloader(PP_Resource url_loader) const; int64_t time_of_last_progress_event_; + int exit_status_; const PPB_NaCl_Private* nacl_interface_; }; diff --git a/ppapi/native_client/src/trusted/plugin/scriptable_plugin.cc b/ppapi/native_client/src/trusted/plugin/scriptable_plugin.cc index 5e39567..05c0455 100644 --- a/ppapi/native_client/src/trusted/plugin/scriptable_plugin.cc +++ b/ppapi/native_client/src/trusted/plugin/scriptable_plugin.cc @@ -41,54 +41,6 @@ pp::Var Error(const nacl::string& call_name, const char* caller, return pp::Var(); } -// In JavaScript, foo[1] is equivalent to foo["1"], so map both indexed and -// string names to a string. -nacl::string NameAsString(const pp::Var& name) { - if (name.is_string()) - return name.AsString(); - CHECK(name.is_int()); - nacl::stringstream namestream; - namestream << name.AsInt(); - return namestream.str(); -} - -// Returns a pp::Var corresponding to |arg| or void. Sets |exception| on error. -pp::Var NaClSrpcArgToPPVar(const NaClSrpcArg* arg, pp::Var* exception) { - PLUGIN_PRINTF((" NaClSrpcArgToPPVar (arg->tag='%c')\n", arg->tag)); - pp::Var var; - switch (arg->tag) { - case NACL_SRPC_ARG_TYPE_BOOL: - var = pp::Var(arg->u.bval != 0); - break; - case NACL_SRPC_ARG_TYPE_DOUBLE: - var = pp::Var(arg->u.dval); - break; - case NACL_SRPC_ARG_TYPE_INT: - var = pp::Var(arg->u.ival); - break; - case NACL_SRPC_ARG_TYPE_LONG: - // PPAPI does not have a 64-bit integral type. Downcast. - var = pp::Var(static_cast<int32_t>(arg->u.lval)); - break; - case NACL_SRPC_ARG_TYPE_STRING: - var = pp::Var(arg->arrays.str); - break; - case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: - case NACL_SRPC_ARG_TYPE_DOUBLE_ARRAY: - case NACL_SRPC_ARG_TYPE_INT_ARRAY: - case NACL_SRPC_ARG_TYPE_LONG_ARRAY: - case NACL_SRPC_ARG_TYPE_OBJECT: - case NACL_SRPC_ARG_TYPE_HANDLE: - case NACL_SRPC_ARG_TYPE_VARIANT_ARRAY: - case NACL_SRPC_ARG_TYPE_INVALID: - default: - *exception = "variant array and invalid argument types are not supported"; - } - PLUGIN_PRINTF((" NaClSrpcArgToPPVar (return var=%s, exception=%s)\n", - var.DebugString().c_str(), exception->DebugString().c_str())); - return var; -} - } // namespace ScriptablePlugin::ScriptablePlugin(Plugin* plugin) @@ -131,18 +83,9 @@ bool ScriptablePlugin::HasProperty(const pp::Var& name, pp::Var* exception) { UNREFERENCED_PARAMETER(exception); PLUGIN_PRINTF(("ScriptablePlugin::HasProperty (this=%p, name=%s)\n", static_cast<void*>(this), name.DebugString().c_str())); - if (plugin_ == NULL) { - return false; - } - if (!name.is_string() && !name.is_int()) - return false; - bool has_property = plugin_->HasProperty(name.AsString()); - PLUGIN_PRINTF(("ScriptablePlugin::HasProperty (has_property=%d)\n", - has_property)); - return has_property; + return false; } - bool ScriptablePlugin::HasMethod(const pp::Var& name, pp::Var* exception) { UNREFERENCED_PARAMETER(exception); PLUGIN_PRINTF(("ScriptablePlugin::HasMethod (this=%p, name='%s')\n", @@ -150,33 +93,15 @@ bool ScriptablePlugin::HasMethod(const pp::Var& name, pp::Var* exception) { return false; } - pp::Var ScriptablePlugin::GetProperty(const pp::Var& name, pp::Var* exception) { PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (name=%s)\n", name.DebugString().c_str())); - if (plugin_ == NULL) { - return pp::Var(); - } - // Get the property. - NaClSrpcArg prop_value; - nacl::string prop_name = NameAsString(name); - if (!plugin_->GetProperty(prop_name, &prop_value)) { - return Error(prop_name, "GetProperty", "invocation failed", exception); - } - PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (invocation done)\n")); - // Marshall output parameter. - pp::Var property = NaClSrpcArgToPPVar(&prop_value, exception); - if (!exception->is_undefined()) { - return Error(prop_name, "GetProperty", "output marshalling failed", - exception); - } - PLUGIN_PRINTF(("ScriptablePlugin::GetProperty (property=%s)\n", - property.DebugString().c_str())); - return property; + Error("GetProperty", name.DebugString().c_str(), + "property getting is not supported", exception); + return pp::Var(); } - void ScriptablePlugin::SetProperty(const pp::Var& name, const pp::Var& value, pp::Var* exception) { @@ -191,7 +116,7 @@ void ScriptablePlugin::RemoveProperty(const pp::Var& name, pp::Var* exception) { PLUGIN_PRINTF(("ScriptablePlugin::RemoveProperty (name=%s)\n", name.DebugString().c_str())); - Error(NameAsString(name), "RemoveProperty", + Error("RemoveProperty", name.DebugString().c_str(), "property removal is not supported", exception); } diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.cc b/ppapi/native_client/src/trusted/plugin/service_runtime.cc index 5b678b9..8a5a11a 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.cc +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.cc @@ -472,11 +472,11 @@ void PluginReverseInterface::AddTempQuotaManagedFile( ServiceRuntime::ServiceRuntime(Plugin* plugin, const Manifest* manifest, - bool should_report_uma, + bool main_service_runtime, pp::CompletionCallback init_done_cb, pp::CompletionCallback crash_cb) : plugin_(plugin), - should_report_uma_(should_report_uma), + main_service_runtime_(main_service_runtime), reverse_service_(NULL), anchor_(new nacl::WeakRefAnchor()), rev_interface_(new PluginReverseInterface(anchor_, plugin, @@ -551,7 +551,7 @@ bool ServiceRuntime::InitCommunication(nacl::DescWrapper* nacl_desc, } NaClLog(4, "ServiceRuntime::InitCommunication (load_status=%d)\n", load_status); - if (should_report_uma_) { + if (main_service_runtime_) { plugin_->ReportSelLdrLoadStatus(load_status); } if (LOAD_OK != load_status) { @@ -711,14 +711,10 @@ ServiceRuntime::~ServiceRuntime() { NaClMutexDtor(&mu_); } -int ServiceRuntime::exit_status() { - nacl::MutexLocker take(&mu_); - return exit_status_; -} - void ServiceRuntime::set_exit_status(int exit_status) { nacl::MutexLocker take(&mu_); - exit_status_ = exit_status & 0xff; + if (main_service_runtime_) + plugin_->set_exit_status(exit_status & 0xff); } nacl::string ServiceRuntime::GetCrashLogOutput() { diff --git a/ppapi/native_client/src/trusted/plugin/service_runtime.h b/ppapi/native_client/src/trusted/plugin/service_runtime.h index 7f6f198..78c781b 100644 --- a/ppapi/native_client/src/trusted/plugin/service_runtime.h +++ b/ppapi/native_client/src/trusted/plugin/service_runtime.h @@ -280,7 +280,7 @@ class ServiceRuntime { NaClSrpcChannel command_channel_; Plugin* plugin_; - bool should_report_uma_; + bool main_service_runtime_; nacl::ReverseService* reverse_service_; nacl::scoped_ptr<nacl::SelLdrLauncherBase> subprocess_; diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index 8f5ea4f..5edbe5c 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -3013,6 +3013,11 @@ static void Pnacl_M25_PPB_NaCl_Private_DispatchEvent(PP_Instance instance, PP_Na iface->DispatchEvent(instance, event_type, *resource_url, length_is_computable, loaded_bytes, total_bytes); } +static void Pnacl_M25_PPB_NaCl_Private_SetReadOnlyProperty(PP_Instance instance, struct PP_Var* key, struct PP_Var* value) { + const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface; + iface->SetReadOnlyProperty(instance, *key, *value); +} + /* End wrapper methods for PPB_NaCl_Private_1_0 */ /* Begin wrapper methods for PPB_NetAddress_Private_0_1 */ @@ -4888,7 +4893,8 @@ struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = { .IsOffTheRecord = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_IsOffTheRecord, .ReportNaClError = (PP_ExternalPluginResult (*)(PP_Instance instance, PP_NaClError message_id))&Pnacl_M25_PPB_NaCl_Private_ReportNaClError, .OpenNaClExecutable = (PP_FileHandle (*)(PP_Instance instance, const char* file_url, uint64_t* file_token_lo, uint64_t* file_token_hi))&Pnacl_M25_PPB_NaCl_Private_OpenNaClExecutable, - .DispatchEvent = (void (*)(PP_Instance instance, PP_NaClEventType event_type, struct PP_Var resource_url, PP_Bool length_is_computable, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_DispatchEvent + .DispatchEvent = (void (*)(PP_Instance instance, PP_NaClEventType event_type, struct PP_Var resource_url, PP_Bool length_is_computable, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_DispatchEvent, + .SetReadOnlyProperty = (void (*)(PP_Instance instance, struct PP_Var key, struct PP_Var value))&Pnacl_M25_PPB_NaCl_Private_SetReadOnlyProperty }; struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = { |