OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" | 5 #include "native_client/src/trusted/plugin/pnacl_coordinator.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "native_client/src/include/checked_cast.h" | 10 #include "native_client/src/include/checked_cast.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 PnaclManifest(const pp::URLUtil_Dev* url_util, bool use_extension) | 41 PnaclManifest(const pp::URLUtil_Dev* url_util, bool use_extension) |
42 : url_util_(url_util), | 42 : url_util_(url_util), |
43 manifest_base_url_(PnaclUrls::GetBaseUrl(use_extension)) { | 43 manifest_base_url_(PnaclUrls::GetBaseUrl(use_extension)) { |
44 // TODO(jvoung): get rid of use_extension when we no longer rely | 44 // TODO(jvoung): get rid of use_extension when we no longer rely |
45 // on the chrome webstore extension. Most of this Manifest stuff | 45 // on the chrome webstore extension. Most of this Manifest stuff |
46 // can also be simplified then. | 46 // can also be simplified then. |
47 } | 47 } |
48 virtual ~PnaclManifest() { } | 48 virtual ~PnaclManifest() { } |
49 | 49 |
50 virtual bool GetProgramURL(nacl::string* full_url, | 50 virtual bool GetProgramURL(nacl::string* full_url, |
51 nacl::string* cache_identity, | 51 PnaclOptions* pnacl_options, |
52 ErrorInfo* error_info, | 52 ErrorInfo* error_info) const { |
53 bool* pnacl_translate) const { | |
54 // Does not contain program urls. | 53 // Does not contain program urls. |
55 UNREFERENCED_PARAMETER(full_url); | 54 UNREFERENCED_PARAMETER(full_url); |
56 UNREFERENCED_PARAMETER(cache_identity); | 55 UNREFERENCED_PARAMETER(pnacl_options); |
57 UNREFERENCED_PARAMETER(error_info); | 56 UNREFERENCED_PARAMETER(error_info); |
58 UNREFERENCED_PARAMETER(pnacl_translate); | |
59 PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); | 57 PLUGIN_PRINTF(("PnaclManifest does not contain a program\n")); |
60 error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, | 58 error_info->SetReport(ERROR_MANIFEST_GET_NEXE_URL, |
61 "pnacl manifest does not contain a program."); | 59 "pnacl manifest does not contain a program."); |
62 return false; | 60 return false; |
63 } | 61 } |
64 | 62 |
65 virtual bool ResolveURL(const nacl::string& relative_url, | 63 virtual bool ResolveURL(const nacl::string& relative_url, |
66 nacl::string* full_url, | 64 nacl::string* full_url, |
67 ErrorInfo* error_info) const { | 65 ErrorInfo* error_info) const { |
68 // Does not do general URL resolution, simply appends relative_url to | 66 // Does not do general URL resolution, simply appends relative_url to |
69 // the end of manifest_base_url_. | 67 // the end of manifest_base_url_. |
70 UNREFERENCED_PARAMETER(error_info); | 68 UNREFERENCED_PARAMETER(error_info); |
71 *full_url = manifest_base_url_ + relative_url; | 69 *full_url = manifest_base_url_ + relative_url; |
72 return true; | 70 return true; |
73 } | 71 } |
74 | 72 |
75 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { | 73 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { |
76 // Does not support enumeration. | 74 // Does not support enumeration. |
77 PLUGIN_PRINTF(("PnaclManifest does not support key enumeration\n")); | 75 PLUGIN_PRINTF(("PnaclManifest does not support key enumeration\n")); |
78 UNREFERENCED_PARAMETER(keys); | 76 UNREFERENCED_PARAMETER(keys); |
79 return false; | 77 return false; |
80 } | 78 } |
81 | 79 |
82 virtual bool ResolveKey(const nacl::string& key, | 80 virtual bool ResolveKey(const nacl::string& key, |
83 nacl::string* full_url, | 81 nacl::string* full_url, |
84 nacl::string* cache_identity, | 82 PnaclOptions* pnacl_options, |
85 ErrorInfo* error_info, | 83 ErrorInfo* error_info) const { |
86 bool* pnacl_translate) const { | |
87 // All of the extension files are native (do not require pnacl translate). | 84 // All of the extension files are native (do not require pnacl translate). |
88 *pnacl_translate = false; | 85 pnacl_options->set_translate(false); |
89 // Do not cache these entries. | |
90 *cache_identity = ""; | |
91 // We can only resolve keys in the files/ namespace. | 86 // We can only resolve keys in the files/ namespace. |
92 const nacl::string kFilesPrefix = "files/"; | 87 const nacl::string kFilesPrefix = "files/"; |
93 size_t files_prefix_pos = key.find(kFilesPrefix); | 88 size_t files_prefix_pos = key.find(kFilesPrefix); |
94 if (files_prefix_pos == nacl::string::npos) { | 89 if (files_prefix_pos == nacl::string::npos) { |
95 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, | 90 error_info->SetReport(ERROR_MANIFEST_RESOLVE_URL, |
96 "key did not start with files/"); | 91 "key did not start with files/"); |
97 return false; | 92 return false; |
98 } | 93 } |
99 // Append what follows files to the pnacl URL prefix. | 94 // Append what follows files to the pnacl URL prefix. |
100 nacl::string key_basename = key.substr(kFilesPrefix.length()); | 95 nacl::string key_basename = key.substr(kFilesPrefix.length()); |
(...skipping 17 matching lines...) Expand all Loading... |
118 PnaclLDManifest(const Manifest* nexe_manifest, | 113 PnaclLDManifest(const Manifest* nexe_manifest, |
119 const Manifest* extension_manifest) | 114 const Manifest* extension_manifest) |
120 : nexe_manifest_(nexe_manifest), | 115 : nexe_manifest_(nexe_manifest), |
121 extension_manifest_(extension_manifest) { | 116 extension_manifest_(extension_manifest) { |
122 CHECK(nexe_manifest != NULL); | 117 CHECK(nexe_manifest != NULL); |
123 CHECK(extension_manifest != NULL); | 118 CHECK(extension_manifest != NULL); |
124 } | 119 } |
125 virtual ~PnaclLDManifest() { } | 120 virtual ~PnaclLDManifest() { } |
126 | 121 |
127 virtual bool GetProgramURL(nacl::string* full_url, | 122 virtual bool GetProgramURL(nacl::string* full_url, |
128 nacl::string* cache_identity, | 123 PnaclOptions* pnacl_options, |
129 ErrorInfo* error_info, | 124 ErrorInfo* error_info) const { |
130 bool* pnacl_translate) const { | 125 if (nexe_manifest_->GetProgramURL(full_url, pnacl_options, error_info)) { |
131 if (nexe_manifest_->GetProgramURL(full_url, cache_identity, | |
132 error_info, pnacl_translate)) { | |
133 return true; | 126 return true; |
134 } | 127 } |
135 return extension_manifest_->GetProgramURL(full_url, cache_identity, | 128 return extension_manifest_->GetProgramURL(full_url, |
136 error_info, pnacl_translate); | 129 pnacl_options, |
| 130 error_info); |
137 } | 131 } |
138 | 132 |
139 virtual bool ResolveURL(const nacl::string& relative_url, | 133 virtual bool ResolveURL(const nacl::string& relative_url, |
140 nacl::string* full_url, | 134 nacl::string* full_url, |
141 ErrorInfo* error_info) const { | 135 ErrorInfo* error_info) const { |
142 if (nexe_manifest_->ResolveURL(relative_url, full_url, error_info)) { | 136 if (nexe_manifest_->ResolveURL(relative_url, full_url, error_info)) { |
143 return true; | 137 return true; |
144 } | 138 } |
145 return extension_manifest_->ResolveURL(relative_url, full_url, error_info); | 139 return extension_manifest_->ResolveURL(relative_url, full_url, error_info); |
146 } | 140 } |
147 | 141 |
148 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { | 142 virtual bool GetFileKeys(std::set<nacl::string>* keys) const { |
149 if (nexe_manifest_->GetFileKeys(keys)) { | 143 if (nexe_manifest_->GetFileKeys(keys)) { |
150 return true; | 144 return true; |
151 } | 145 } |
152 return extension_manifest_->GetFileKeys(keys); | 146 return extension_manifest_->GetFileKeys(keys); |
153 } | 147 } |
154 | 148 |
155 virtual bool ResolveKey(const nacl::string& key, | 149 virtual bool ResolveKey(const nacl::string& key, |
156 nacl::string* full_url, | 150 nacl::string* full_url, |
157 nacl::string* cache_identity, | 151 PnaclOptions* pnacl_options, |
158 ErrorInfo* error_info, | 152 ErrorInfo* error_info) const { |
159 bool* pnacl_translate) const { | 153 if (nexe_manifest_->ResolveKey(key, full_url, pnacl_options, error_info)) { |
160 if (nexe_manifest_->ResolveKey(key, full_url, cache_identity, | |
161 error_info, pnacl_translate)) { | |
162 return true; | 154 return true; |
163 } | 155 } |
164 return extension_manifest_->ResolveKey(key, full_url, cache_identity, | 156 return extension_manifest_->ResolveKey(key, full_url, |
165 error_info, pnacl_translate); | 157 pnacl_options, |
| 158 error_info); |
166 } | 159 } |
167 | 160 |
168 private: | 161 private: |
169 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclLDManifest); | 162 NACL_DISALLOW_COPY_AND_ASSIGN(PnaclLDManifest); |
170 | 163 |
171 const Manifest* nexe_manifest_; | 164 const Manifest* nexe_manifest_; |
172 const Manifest* extension_manifest_; | 165 const Manifest* extension_manifest_; |
173 }; | 166 }; |
174 | 167 |
175 ////////////////////////////////////////////////////////////////////// | 168 ////////////////////////////////////////////////////////////////////// |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 ////////////////////////////////////////////////////////////////////// | 259 ////////////////////////////////////////////////////////////////////// |
267 | 260 |
268 // Out-of-line destructor to keep it from getting put in every .o where | 261 // Out-of-line destructor to keep it from getting put in every .o where |
269 // callback_source.h is included | 262 // callback_source.h is included |
270 template<> | 263 template<> |
271 CallbackSource<FileStreamData>::~CallbackSource() {} | 264 CallbackSource<FileStreamData>::~CallbackSource() {} |
272 | 265 |
273 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( | 266 PnaclCoordinator* PnaclCoordinator::BitcodeToNative( |
274 Plugin* plugin, | 267 Plugin* plugin, |
275 const nacl::string& pexe_url, | 268 const nacl::string& pexe_url, |
276 const nacl::string& cache_identity, | 269 const PnaclOptions& pnacl_options, |
277 const pp::CompletionCallback& translate_notify_callback) { | 270 const pp::CompletionCallback& translate_notify_callback) { |
278 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", | 271 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (plugin=%p, pexe=%s)\n", |
279 static_cast<void*>(plugin), pexe_url.c_str())); | 272 static_cast<void*>(plugin), pexe_url.c_str())); |
280 PnaclCoordinator* coordinator = | 273 PnaclCoordinator* coordinator = |
281 new PnaclCoordinator(plugin, pexe_url, | 274 new PnaclCoordinator(plugin, pexe_url, |
282 cache_identity, translate_notify_callback); | 275 pnacl_options, |
| 276 translate_notify_callback); |
283 coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); | 277 coordinator->pnacl_init_time_ = NaClGetTimeOfDayMicroseconds(); |
284 coordinator->off_the_record_ = | 278 coordinator->off_the_record_ = |
285 plugin->nacl_interface()->IsOffTheRecord(); | 279 plugin->nacl_interface()->IsOffTheRecord(); |
286 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, " | 280 PLUGIN_PRINTF(("PnaclCoordinator::BitcodeToNative (manifest=%p, " |
287 "off_the_record=%d)\n", | 281 "off_the_record=%d)\n", |
288 reinterpret_cast<const void*>(coordinator->manifest_.get()), | 282 reinterpret_cast<const void*>(coordinator->manifest_.get()), |
289 coordinator->off_the_record_)); | 283 coordinator->off_the_record_)); |
290 | 284 |
291 // Load llc and ld. | 285 // Load llc and ld. |
292 std::vector<nacl::string> resource_urls; | 286 std::vector<nacl::string> resource_urls; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 component + " load failed."); | 318 component + " load failed."); |
325 } | 319 } |
326 return NACL_NO_FILE_DESC; | 320 return NACL_NO_FILE_DESC; |
327 } | 321 } |
328 return file_desc_ok_to_close; | 322 return file_desc_ok_to_close; |
329 } | 323 } |
330 | 324 |
331 PnaclCoordinator::PnaclCoordinator( | 325 PnaclCoordinator::PnaclCoordinator( |
332 Plugin* plugin, | 326 Plugin* plugin, |
333 const nacl::string& pexe_url, | 327 const nacl::string& pexe_url, |
334 const nacl::string& cache_identity, | 328 const PnaclOptions& pnacl_options, |
335 const pp::CompletionCallback& translate_notify_callback) | 329 const pp::CompletionCallback& translate_notify_callback) |
336 : translate_finish_error_(PP_OK), | 330 : translate_finish_error_(PP_OK), |
337 plugin_(plugin), | 331 plugin_(plugin), |
338 translate_notify_callback_(translate_notify_callback), | 332 translate_notify_callback_(translate_notify_callback), |
339 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), | 333 file_system_(new pp::FileSystem(plugin, PP_FILESYSTEMTYPE_LOCALTEMPORARY)), |
340 manifest_(new PnaclManifest( | 334 manifest_(new PnaclManifest( |
341 plugin->url_util(), | 335 plugin->url_util(), |
342 plugin::PnaclUrls::UsePnaclExtension(plugin))), | 336 plugin::PnaclUrls::UsePnaclExtension(plugin))), |
343 pexe_url_(pexe_url), | 337 pexe_url_(pexe_url), |
344 cache_identity_(cache_identity), | 338 pnacl_options_(pnacl_options), |
345 error_already_reported_(false), | 339 error_already_reported_(false), |
346 off_the_record_(false), | 340 off_the_record_(false), |
347 pnacl_init_time_(0), | 341 pnacl_init_time_(0), |
348 pexe_size_(0), | 342 pexe_size_(0), |
349 pexe_bytes_compiled_(0), | 343 pexe_bytes_compiled_(0), |
350 expected_pexe_size_(-1) { | 344 expected_pexe_size_(-1) { |
351 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", | 345 PLUGIN_PRINTF(("PnaclCoordinator::PnaclCoordinator (this=%p, plugin=%p)\n", |
352 static_cast<void*>(this), static_cast<void*>(plugin))); | 346 static_cast<void*>(this), static_cast<void*>(plugin))); |
353 callback_factory_.Initialize(this); | 347 callback_factory_.Initialize(this); |
354 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); | 348 ld_manifest_.reset(new PnaclLDManifest(plugin_->manifest(), manifest_.get())); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 size_t nexe_size = stbuf.nacl_abi_st_size; | 441 size_t nexe_size = stbuf.nacl_abi_st_size; |
448 HistogramSizeKB("NaCl.Perf.Size.PNaClTranslatedNexe", | 442 HistogramSizeKB("NaCl.Perf.Size.PNaClTranslatedNexe", |
449 static_cast<int64_t>(nexe_size / 1024)); | 443 static_cast<int64_t>(nexe_size / 1024)); |
450 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); | 444 HistogramRatio("NaCl.Perf.Size.PexeNexeSizePct", pexe_size_, nexe_size); |
451 } | 445 } |
452 | 446 |
453 // The nexe is written to the temp_nexe_file_. We must Reset() the file | 447 // The nexe is written to the temp_nexe_file_. We must Reset() the file |
454 // pointer to be able to read it again from the beginning. | 448 // pointer to be able to read it again from the beginning. |
455 temp_nexe_file_->Reset(); | 449 temp_nexe_file_->Reset(); |
456 | 450 |
457 if (cache_identity_ != "" && cached_nexe_file_ != NULL) { | 451 if (pnacl_options_.HasCacheKey() && cached_nexe_file_ != NULL) { |
458 // We are using a cache, but had a cache miss, which is why we did the | 452 // We are using a cache, but had a cache miss, which is why we did the |
459 // translation. Reset cached_nexe_file_ to have a random name, | 453 // translation. Reset cached_nexe_file_ to have a random name, |
460 // for scratch purposes, before renaming to the final cache_identity_. | 454 // for scratch purposes, before renaming to the final cache_identity. |
461 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), | 455 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), |
462 nacl::string(kPnaclTempDir))); | 456 nacl::string(kPnaclTempDir))); |
463 pp::CompletionCallback cb = callback_factory_.NewCallback( | 457 pp::CompletionCallback cb = callback_factory_.NewCallback( |
464 &PnaclCoordinator::CachedNexeOpenedForWrite); | 458 &PnaclCoordinator::CachedNexeOpenedForWrite); |
465 cached_nexe_file_->OpenWrite(cb); | 459 cached_nexe_file_->OpenWrite(cb); |
466 } else { | 460 } else { |
467 // For now, tolerate bitcode that is missing a cache identity, and | 461 // For now, tolerate bitcode that is missing a cache identity, and |
468 // tolerate the lack of caching in incognito mode. | 462 // tolerate the lack of caching in incognito mode. |
469 PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n")); | 463 PLUGIN_PRINTF(("PnaclCoordinator -- not caching.\n")); |
470 NexeReadDidOpen(PP_OK); | 464 NexeReadDidOpen(PP_OK); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 // returning. We pass the current pp_error along so that it can be reported | 595 // returning. We pass the current pp_error along so that it can be reported |
602 // before returning. | 596 // before returning. |
603 pp::CompletionCallback cb = callback_factory_.NewCallback( | 597 pp::CompletionCallback cb = callback_factory_.NewCallback( |
604 &PnaclCoordinator::CorruptCacheFileWasDeleted, pp_error); | 598 &PnaclCoordinator::CorruptCacheFileWasDeleted, pp_error); |
605 cached_nexe_file_->Delete(cb); | 599 cached_nexe_file_->Delete(cb); |
606 return; | 600 return; |
607 } | 601 } |
608 // Rename the cached_nexe_file_ file to the cache id, to finalize. | 602 // Rename the cached_nexe_file_ file to the cache id, to finalize. |
609 pp::CompletionCallback cb = | 603 pp::CompletionCallback cb = |
610 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); | 604 callback_factory_.NewCallback(&PnaclCoordinator::NexeFileWasRenamed); |
611 cached_nexe_file_->Rename(cache_identity_, cb); | 605 cached_nexe_file_->Rename(pnacl_options_.GetCacheKey(), cb); |
612 } | 606 } |
613 | 607 |
614 void PnaclCoordinator::CorruptCacheFileWasDeleted(int32_t delete_pp_error, | 608 void PnaclCoordinator::CorruptCacheFileWasDeleted(int32_t delete_pp_error, |
615 int32_t orig_pp_error) { | 609 int32_t orig_pp_error) { |
616 if (delete_pp_error != PP_OK) { | 610 if (delete_pp_error != PP_OK) { |
617 // The cache file was certainly already opened by the time we tried | 611 // The cache file was certainly already opened by the time we tried |
618 // to write to it, so it should certainly be deletable. | 612 // to write to it, so it should certainly be deletable. |
619 PLUGIN_PRINTF(("PnaclCoordinator::CorruptCacheFileWasDeleted " | 613 PLUGIN_PRINTF(("PnaclCoordinator::CorruptCacheFileWasDeleted " |
620 "delete failed with pp_error=%"NACL_PRId32"\n", | 614 "delete failed with pp_error=%"NACL_PRId32"\n", |
621 delete_pp_error)); | 615 delete_pp_error)); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 "PNaCl translation cache directory creation/check failed " | 796 "PNaCl translation cache directory creation/check failed " |
803 "(no access)."); | 797 "(no access)."); |
804 return; | 798 return; |
805 } | 799 } |
806 ReportPpapiError( | 800 ReportPpapiError( |
807 ERROR_PNACL_CACHE_DIRECTORY_CREATE, | 801 ERROR_PNACL_CACHE_DIRECTORY_CREATE, |
808 pp_error, | 802 pp_error, |
809 "PNaCl translation cache directory creation/check failed."); | 803 "PNaCl translation cache directory creation/check failed."); |
810 return; | 804 return; |
811 } | 805 } |
812 if (cache_identity_ != "") { | 806 if (pnacl_options_.HasCacheKey()) { |
813 cached_nexe_file_.reset(new LocalTempFile(plugin_, file_system_.get(), | 807 cached_nexe_file_.reset(new LocalTempFile( |
814 nacl::string(kPnaclTempDir), | 808 plugin_, file_system_.get(), |
815 cache_identity_)); | 809 nacl::string(kPnaclTempDir), |
| 810 pnacl_options_.GetCacheKey())); |
816 pp::CompletionCallback cb = | 811 pp::CompletionCallback cb = |
817 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); | 812 callback_factory_.NewCallback(&PnaclCoordinator::CachedFileDidOpen); |
818 cached_nexe_file_->OpenRead(cb); | 813 cached_nexe_file_->OpenRead(cb); |
819 } else { | 814 } else { |
820 // For now, tolerate lack of cache identity... | 815 // For now, tolerate lack of cache identity... |
821 CachedFileDidOpen(PP_ERROR_FAILED); | 816 CachedFileDidOpen(PP_ERROR_FAILED); |
822 } | 817 } |
823 } | 818 } |
824 | 819 |
825 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { | 820 void PnaclCoordinator::CachedFileDidOpen(int32_t pp_error) { |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); | 959 callback_factory_.NewCallback(&PnaclCoordinator::TranslateFinished); |
965 | 960 |
966 CHECK(translate_thread_ != NULL); | 961 CHECK(translate_thread_ != NULL); |
967 translate_thread_->RunTranslate(report_translate_finished, | 962 translate_thread_->RunTranslate(report_translate_finished, |
968 manifest_.get(), | 963 manifest_.get(), |
969 ld_manifest_.get(), | 964 ld_manifest_.get(), |
970 obj_file_.get(), | 965 obj_file_.get(), |
971 temp_nexe_file_.get(), | 966 temp_nexe_file_.get(), |
972 &error_info_, | 967 &error_info_, |
973 resources_.get(), | 968 resources_.get(), |
| 969 &pnacl_options_, |
974 this, | 970 this, |
975 plugin_); | 971 plugin_); |
976 } | 972 } |
977 | 973 |
978 } // namespace plugin | 974 } // namespace plugin |
OLD | NEW |