Merge from Chromium at DEPS revision 262940

This commit was generated by merge_to_master.py.

Change-Id: I9a3fddbb29857fa8f68a18c6a0115862b65f84d1
diff --git a/ppapi/PRESUBMIT.py b/ppapi/PRESUBMIT.py
index 4a71f49..2d83ef8 100644
--- a/ppapi/PRESUBMIT.py
+++ b/ppapi/PRESUBMIT.py
@@ -172,7 +172,7 @@
       has_histogram_xml_change = True
 
   if interface_changes and not has_histogram_xml_change:
-    return [output_api.PresubmitPromptWarning(
+    return [output_api.PresubmitNotifyResult(
         'Missing change to tools/metrics/histograms/histograms.xml.\n' +
         'Run pepper_hash_for_uma to make get values for new interfaces.\n' +
         'Interface changes:\n' + '\n'.join(interface_changes))]
diff --git a/ppapi/api/private/ppb_nacl_private.idl b/ppapi/api/private/ppb_nacl_private.idl
index f3416a8..cb2b1b7 100644
--- a/ppapi/api/private/ppb_nacl_private.idl
+++ b/ppapi/api/private/ppb_nacl_private.idl
@@ -168,14 +168,9 @@
                     [in] PP_CompletionCallback callback);
 
   /* This function starts the IPC proxy so the nexe can communicate with the
-   * browser. Returns PP_EXTERNAL_PLUGIN_OK on success, otherwise a result code
-   * indicating the failure. PP_EXTERNAL_PLUGIN_FAILED is returned if
-   * LaunchSelLdr wasn't called with the instance.
-   * PP_EXTERNAL_PLUGIN_ERROR_MODULE is returned if the module can't be
-   * initialized. PP_EXTERNAL_PLUGIN_ERROR_INSTANCE is returned if the instance
-   * can't be initialized.
+   * browser.
    */
-  PP_ExternalPluginResult StartPpapiProxy(PP_Instance instance);
+  PP_Bool StartPpapiProxy(PP_Instance instance);
 
   /* On POSIX systems, this function returns the file descriptor of
    * /dev/urandom.  On non-POSIX systems, this function returns 0.
@@ -276,13 +271,6 @@
                      [in] uint64_t loaded_bytes,
                      [in] uint64_t total_bytes);
 
-  /* Sets a read-only property on the <embed> DOM element that corresponds to
-   * the given instance.
-   */
-  void SetReadOnlyProperty([in] PP_Instance instance,
-                           [in] PP_Var key,
-                           [in] PP_Var value);
-
   /* Report that the nexe loaded successfully. */
   void ReportLoadSuccess([in] PP_Instance instance,
                          [in] str_t url,
@@ -298,9 +286,9 @@
   /* Reports that loading a nexe was aborted. */
   void ReportLoadAbort([in] PP_Instance instance);
 
-  /* Reports that the nexe has crashed or is otherwise dead. */
-  void ReportDeadNexe([in] PP_Instance instance,
-                      [in] int64_t crash_time);
+  /* Reports that the nexe has crashed. */
+  void NexeDidCrash([in] PP_Instance instance,
+                    [in] str_t crash_log);
 
   /* Performs internal setup when an instance is created. */
   void InstanceCreated([in] PP_Instance instance);
@@ -325,9 +313,6 @@
   void LogToConsole([in] PP_Instance instance,
                     [in] str_t message);
 
-  /* Returns PP_TRUE if an error has been reported loading the nexe. */
-  PP_Bool GetNexeErrorReported([in] PP_Instance instance);
-
   /* Returns the NaCl readiness status for this instance. */
   PP_NaClReadyState GetNaClReadyState([in] PP_Instance instance);
 
@@ -342,10 +327,26 @@
   void SetIsInstalled([in] PP_Instance instance,
                       [in] PP_Bool is_installed);
 
-  /* Returns the time the nexe became ready. */
-  int64_t GetReadyTime([in] PP_Instance instance);
-
   /* Sets the time the nexe became ready. */
-  void SetReadyTime([in] PP_Instance instance,
-                    [in] int64_t ready_time);
+  void SetReadyTime([in] PP_Instance instance);
+
+  /* Returns the exit status of the plugin process. */
+  int32_t GetExitStatus([in] PP_Instance instance);
+
+  /* Sets the exit status of the plugin process. */
+  void SetExitStatus([in] PP_Instance instance,
+                     [in] int32_t exit_status);
+
+  /* Logs the message via VLOG. */
+  void Vlog([in] str_t message);
+
+  /* Sets the time the plugin was initialized. */
+  void SetInitTime([in] PP_Instance instance);
+
+  /* Returns the size of the nexe. */
+  int64_t GetNexeSize([in] PP_Instance instance);
+
+  /* Sets the size of the nexe. */
+  void SetNexeSize([in] PP_Instance instance,
+                   [in] int64_t nexe_size);
 };
diff --git a/ppapi/c/private/ppb_nacl_private.h b/ppapi/c/private/ppb_nacl_private.h
index 709f958..c259cbe 100644
--- a/ppapi/c/private/ppb_nacl_private.h
+++ b/ppapi/c/private/ppb_nacl_private.h
@@ -3,7 +3,7 @@
  * found in the LICENSE file.
  */
 
-/* From private/ppb_nacl_private.idl modified Mon Mar 31 13:29:26 2014. */
+/* From private/ppb_nacl_private.idl modified Mon Apr  7 13:43:24 2014. */
 
 #ifndef PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
 #define PPAPI_C_PRIVATE_PPB_NACL_PRIVATE_H_
@@ -14,7 +14,6 @@
 #include "ppapi/c/pp_macros.h"
 #include "ppapi/c/pp_stdint.h"
 #include "ppapi/c/pp_var.h"
-#include "ppapi/c/private/ppb_instance_private.h"
 
 #define PPB_NACL_PRIVATE_INTERFACE_1_0 "PPB_NaCl_Private;1.0"
 #define PPB_NACL_PRIVATE_INTERFACE PPB_NACL_PRIVATE_INTERFACE_1_0
@@ -190,14 +189,9 @@
                        struct PP_Var* error_message,
                        struct PP_CompletionCallback callback);
   /* This function starts the IPC proxy so the nexe can communicate with the
-   * browser. Returns PP_EXTERNAL_PLUGIN_OK on success, otherwise a result code
-   * indicating the failure. PP_EXTERNAL_PLUGIN_FAILED is returned if
-   * LaunchSelLdr wasn't called with the instance.
-   * PP_EXTERNAL_PLUGIN_ERROR_MODULE is returned if the module can't be
-   * initialized. PP_EXTERNAL_PLUGIN_ERROR_INSTANCE is returned if the instance
-   * can't be initialized.
+   * browser.
    */
-  PP_ExternalPluginResult (*StartPpapiProxy)(PP_Instance instance);
+  PP_Bool (*StartPpapiProxy)(PP_Instance instance);
   /* On POSIX systems, this function returns the file descriptor of
    * /dev/urandom.  On non-POSIX systems, this function returns 0.
    */
@@ -284,12 +278,6 @@
                         PP_Bool length_is_computable,
                         uint64_t loaded_bytes,
                         uint64_t total_bytes);
-  /* Sets a read-only property on the <embed> DOM element that corresponds to
-   * the given instance.
-   */
-  void (*SetReadOnlyProperty)(PP_Instance instance,
-                              struct PP_Var key,
-                              struct PP_Var value);
   /* Report that the nexe loaded successfully. */
   void (*ReportLoadSuccess)(PP_Instance instance,
                             const char* url,
@@ -302,8 +290,8 @@
                           const char* console_message);
   /* Reports that loading a nexe was aborted. */
   void (*ReportLoadAbort)(PP_Instance instance);
-  /* Reports that the nexe has crashed or is otherwise dead. */
-  void (*ReportDeadNexe)(PP_Instance instance, int64_t crash_time);
+  /* Reports that the nexe has crashed. */
+  void (*NexeDidCrash)(PP_Instance instance, const char* crash_log);
   /* Performs internal setup when an instance is created. */
   void (*InstanceCreated)(PP_Instance instance);
   /* Performs internal cleanup when an instance is destroyed. */
@@ -320,8 +308,6 @@
   PP_UrlSchemeType (*GetUrlScheme)(struct PP_Var url);
   /* Logs the message to the console. */
   void (*LogToConsole)(PP_Instance instance, const char* message);
-  /* Returns PP_TRUE if an error has been reported loading the nexe. */
-  PP_Bool (*GetNexeErrorReported)(PP_Instance instance);
   /* Returns the NaCl readiness status for this instance. */
   PP_NaClReadyState (*GetNaClReadyState)(PP_Instance instance);
   /* Sets the NaCl readiness status for this instance. */
@@ -331,10 +317,20 @@
   PP_Bool (*GetIsInstalled)(PP_Instance instance);
   /* Sets whether the plugin is an installed app. */
   void (*SetIsInstalled)(PP_Instance instance, PP_Bool is_installed);
-  /* Returns the time the nexe became ready. */
-  int64_t (*GetReadyTime)(PP_Instance instance);
   /* Sets the time the nexe became ready. */
-  void (*SetReadyTime)(PP_Instance instance, int64_t ready_time);
+  void (*SetReadyTime)(PP_Instance instance);
+  /* Returns the exit status of the plugin process. */
+  int32_t (*GetExitStatus)(PP_Instance instance);
+  /* Sets the exit status of the plugin process. */
+  void (*SetExitStatus)(PP_Instance instance, int32_t exit_status);
+  /* Logs the message via VLOG. */
+  void (*Vlog)(const char* message);
+  /* Sets the time the plugin was initialized. */
+  void (*SetInitTime)(PP_Instance instance);
+  /* Returns the size of the nexe. */
+  int64_t (*GetNexeSize)(PP_Instance instance);
+  /* Sets the size of the nexe. */
+  void (*SetNexeSize)(PP_Instance instance, int64_t nexe_size);
 };
 
 typedef struct PPB_NaCl_Private_1_0 PPB_NaCl_Private;
diff --git a/ppapi/examples/media_stream_video/media_stream_video.cc b/ppapi/examples/media_stream_video/media_stream_video.cc
index adb1eba..71e6641 100644
--- a/ppapi/examples/media_stream_video/media_stream_video.cc
+++ b/ppapi/examples/media_stream_video/media_stream_video.cc
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <string.h>
+
 #include <vector>
 
 #include "ppapi/c/pp_errors.h"
@@ -15,8 +19,7 @@
 #include "ppapi/cpp/rect.h"
 #include "ppapi/cpp/var.h"
 #include "ppapi/cpp/video_frame.h"
-#include "ppapi/lib/gl/include/GLES2/gl2.h"
-#include "ppapi/lib/gl/include/GLES2/gl2ext.h"
+#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
 #include "ppapi/utility/completion_callback_factory.h"
 
 // When compiling natively on Windows, PostMessage can be #define-d to
@@ -28,7 +31,7 @@
 // Assert |context_| isn't holding any GL Errors.  Done as a macro instead of a
 // function to preserve line number information in the failure message.
 #define AssertNoGLError() \
-  PP_DCHECK(!gles2_if_->GetError(context_->pp_resource()));
+  PP_DCHECK(!glGetError());
 
 namespace {
 
@@ -69,7 +72,7 @@
   void InitGL();
   GLuint CreateTexture(int32_t width, int32_t height, int unit, bool rgba);
   void CreateGLObjects();
-  void CreateShader(GLuint program, GLenum type, const char* source, int size);
+  void CreateShader(GLuint program, GLenum type, const char* source);
   void PaintFinished(int32_t result);
   void CreateTextures();
   void ConfigureTrack();
@@ -100,9 +103,6 @@
   int32_t attrib_width_;
   int32_t attrib_height_;
 
-  // Unowned pointers.
-  const struct PPB_OpenGLES2* gles2_if_;
-
   // Owned data.
   pp::Graphics3D* context_;
 
@@ -126,9 +126,10 @@
       attrib_width_(0),
       attrib_height_(0),
       context_(NULL) {
-  gles2_if_ = static_cast<const struct PPB_OpenGLES2*>(
-      module->GetBrowserInterface(PPB_OPENGLES2_INTERFACE));
-  PP_DCHECK(gles2_if_);
+  if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
+    LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Unable to initialize GL PPAPI!"));
+    assert(false);
+  }
 }
 
 MediaStreamVideoDemoInstance::~MediaStreamVideoDemoInstance() {
@@ -150,8 +151,10 @@
 }
 
 void MediaStreamVideoDemoInstance::HandleMessage(const pp::Var& var_message) {
-  if (!var_message.is_dictionary())
+  if (!var_message.is_dictionary()) {
+    LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid message!"));
     return;
+  }
 
   pp::VarDictionary var_dictionary_message(var_message);
   std::string command = var_dictionary_message.Get("command").AsString();
@@ -164,7 +167,7 @@
     video_track_ = pp::MediaStreamVideoTrack(resource_track);
     ConfigureTrack();
   } else if (command == "format") {
-    std::string str_format =  var_dictionary_message.Get("format").AsString();
+    std::string str_format = var_dictionary_message.Get("format").AsString();
     if (str_format == "YV12") {
       attrib_format_ = PP_VIDEOFRAME_FORMAT_YV12;
     } else if (str_format == "I420") {
@@ -179,6 +182,8 @@
     attrib_width_ = var_dictionary_message.Get("width").AsInt();
     attrib_height_ = var_dictionary_message.Get("height").AsInt();
     need_config_ = true;
+  } else {
+    LogToConsole(PP_LOGLEVEL_ERROR, pp::Var("Invalid command!"));
   }
 }
 
@@ -203,11 +208,12 @@
   context_ = new pp::Graphics3D(this, attributes);
   PP_DCHECK(!context_->is_null());
 
+  glSetCurrentContextPPAPI(context_->pp_resource());
+
   // Set viewport window size and clear color bit.
-  gles2_if_->ClearColor(context_->pp_resource(), 1, 0, 0, 1);
-  gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
-  gles2_if_->Viewport(context_->pp_resource(), 0, 0,
-                      position_size_.width(), position_size_.height());
+  glClearColor(1, 0, 0, 1);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glViewport(0, 0, position_size_.width(), position_size_.height());
 
   BindGraphics(*context_);
   AssertNoGLError();
@@ -216,66 +222,50 @@
 }
 
 void MediaStreamVideoDemoInstance::DrawYUV() {
-  PP_Resource context = context_->pp_resource();
   static const float kColorMatrix[9] = {
     1.1643828125f, 1.1643828125f, 1.1643828125f,
     0.0f, -0.39176171875f, 2.017234375f,
     1.59602734375f, -0.81296875f, 0.0f
   };
 
-  gles2_if_->UseProgram(context, program_yuv_);
-  gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
-        context, program_yuv_, "y_texture"), 0);
-  gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
-        context, program_yuv_, "u_texture"), 1);
-  gles2_if_->Uniform1i(context, gles2_if_->GetUniformLocation(
-        context, program_yuv_, "v_texture"), 2);
-  gles2_if_->UniformMatrix3fv(
-      context,
-      gles2_if_->GetUniformLocation(context, program_yuv_, "color_matrix"),
+  glUseProgram(program_yuv_);
+  glUniform1i(glGetUniformLocation(program_yuv_, "y_texture"), 0);
+  glUniform1i(glGetUniformLocation(program_yuv_, "u_texture"), 1);
+  glUniform1i(glGetUniformLocation(program_yuv_, "v_texture"), 2);
+  glUniformMatrix3fv(glGetUniformLocation(program_yuv_, "color_matrix"),
       1, GL_FALSE, kColorMatrix);
   AssertNoGLError();
 
-  GLint pos_location = gles2_if_->GetAttribLocation(
-      context, program_yuv_, "a_position");
-  GLint tc_location = gles2_if_->GetAttribLocation(
-      context, program_yuv_, "a_texCoord");
+  GLint pos_location = glGetAttribLocation(program_yuv_, "a_position");
+  GLint tc_location = glGetAttribLocation(program_yuv_, "a_texCoord");
   AssertNoGLError();
-  gles2_if_->EnableVertexAttribArray(context, pos_location);
-  gles2_if_->VertexAttribPointer(context, pos_location, 2,
-                                 GL_FLOAT, GL_FALSE, 0, 0);
-  gles2_if_->EnableVertexAttribArray(context, tc_location);
-  gles2_if_->VertexAttribPointer(
-      context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
+  glEnableVertexAttribArray(pos_location);
+  glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
+  glEnableVertexAttribArray(tc_location);
+  glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0,
       static_cast<float*>(0) + 16);  // Skip position coordinates.
   AssertNoGLError();
 
-  gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 0, 4);
+  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   AssertNoGLError();
 }
 
 void MediaStreamVideoDemoInstance::DrawRGB() {
-  PP_Resource context = context_->pp_resource();
-  gles2_if_->UseProgram(context, program_rgb_);
-  gles2_if_->Uniform1i(context,
-      gles2_if_->GetUniformLocation(context, program_rgb_, "rgb_texture"), 3);
+  glUseProgram(program_rgb_);
+  glUniform1i(glGetUniformLocation(program_rgb_, "rgb_texture"), 3);
   AssertNoGLError();
 
-  GLint pos_location = gles2_if_->GetAttribLocation(
-      context, program_rgb_, "a_position");
-  GLint tc_location = gles2_if_->GetAttribLocation(
-      context, program_rgb_, "a_texCoord");
+  GLint pos_location = glGetAttribLocation(program_rgb_, "a_position");
+  GLint tc_location = glGetAttribLocation(program_rgb_, "a_texCoord");
   AssertNoGLError();
-  gles2_if_->EnableVertexAttribArray(context, pos_location);
-  gles2_if_->VertexAttribPointer(context, pos_location, 2,
-                                 GL_FLOAT, GL_FALSE, 0, 0);
-  gles2_if_->EnableVertexAttribArray(context, tc_location);
-  gles2_if_->VertexAttribPointer(
-      context, tc_location, 2, GL_FLOAT, GL_FALSE, 0,
+  glEnableVertexAttribArray(pos_location);
+  glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0, 0);
+  glEnableVertexAttribArray(tc_location);
+  glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0,
       static_cast<float*>(0) + 16);  // Skip position coordinates.
   AssertNoGLError();
 
-  gles2_if_->DrawArrays(context, GL_TRIANGLE_STRIP, 4, 4);
+  glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
 }
 
 void MediaStreamVideoDemoInstance::Render() {
@@ -287,7 +277,7 @@
     DrawRGB();
     DrawYUV();
   } else {
-    gles2_if_->Clear(context_->pp_resource(), GL_COLOR_BUFFER_BIT);
+    glClear(GL_COLOR_BUFFER_BIT);
   }
   pp::CompletionCallback cb = callback_factory_.NewCallback(
       &MediaStreamVideoDemoInstance::PaintFinished);
@@ -303,30 +293,21 @@
 GLuint MediaStreamVideoDemoInstance::CreateTexture(
     int32_t width, int32_t height, int unit, bool rgba) {
   GLuint texture_id;
-  gles2_if_->GenTextures(context_->pp_resource(), 1, &texture_id);
+  glGenTextures(1, &texture_id);
   AssertNoGLError();
 
   // Assign parameters.
-  gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0 + unit);
-  gles2_if_->BindTexture(context_->pp_resource(), GL_TEXTURE_2D, texture_id);
-  gles2_if_->TexParameteri(
-      context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
-      GL_NEAREST);
-  gles2_if_->TexParameteri(
-      context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
-      GL_NEAREST);
-  gles2_if_->TexParameterf(
-      context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
-      GL_CLAMP_TO_EDGE);
-  gles2_if_->TexParameterf(
-      context_->pp_resource(), GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
-      GL_CLAMP_TO_EDGE);
+  glActiveTexture(GL_TEXTURE0 + unit);
+  glBindTexture(GL_TEXTURE_2D, texture_id);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   // Allocate texture.
-  gles2_if_->TexImage2D(
-      context_->pp_resource(), GL_TEXTURE_2D, 0,
-      rgba ? GL_BGRA_EXT : GL_LUMINANCE,
-      width, height, 0,
-      rgba ? GL_BGRA_EXT : GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
+  glTexImage2D(GL_TEXTURE_2D, 0,
+               rgba ? GL_BGRA_EXT : GL_LUMINANCE,
+               width, height, 0,
+               rgba ? GL_BGRA_EXT : GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
   AssertNoGLError();
   return texture_id;
 }
@@ -369,23 +350,17 @@
       "  gl_FragColor = texture2D(rgb_texture, v_texCoord);       \n"
       "}";
 
-  PP_Resource context = context_->pp_resource();
-
   // Create shader programs.
-  program_yuv_ = gles2_if_->CreateProgram(context);
-  CreateShader(program_yuv_, GL_VERTEX_SHADER,
-               kVertexShader, sizeof(kVertexShader));
-  CreateShader(program_yuv_, GL_FRAGMENT_SHADER,
-               kFragmentShaderYUV, sizeof(kFragmentShaderYUV));
-  gles2_if_->LinkProgram(context, program_yuv_);
+  program_yuv_ = glCreateProgram();
+  CreateShader(program_yuv_, GL_VERTEX_SHADER, kVertexShader);
+  CreateShader(program_yuv_, GL_FRAGMENT_SHADER, kFragmentShaderYUV);
+  glLinkProgram(program_yuv_);
   AssertNoGLError();
 
-  program_rgb_ = gles2_if_->CreateProgram(context);
-  CreateShader(program_rgb_, GL_VERTEX_SHADER,
-               kVertexShader, sizeof(kVertexShader));
-  CreateShader(program_rgb_, GL_FRAGMENT_SHADER,
-               kFragmentShaderRGB, sizeof(kFragmentShaderRGB));
-  gles2_if_->LinkProgram(context, program_rgb_);
+  program_rgb_ = glCreateProgram();
+  CreateShader(program_rgb_, GL_VERTEX_SHADER, kVertexShader);
+  CreateShader(program_rgb_, GL_FRAGMENT_SHADER, kFragmentShaderRGB);
+  glLinkProgram(program_rgb_);
   AssertNoGLError();
 
   // Assign vertex positions and texture coordinates to buffers for use in
@@ -397,21 +372,20 @@
     0, 0, 0, 1, 1, 0, 1, 1,  // Texture coordinates.
   };
 
-  gles2_if_->GenBuffers(context, 1, &buffer_);
-  gles2_if_->BindBuffer(context, GL_ARRAY_BUFFER, buffer_);
-  gles2_if_->BufferData(context, GL_ARRAY_BUFFER,
-                        sizeof(kVertices), kVertices, GL_STATIC_DRAW);
+  glGenBuffers(1, &buffer_);
+  glBindBuffer(GL_ARRAY_BUFFER, buffer_);
+  glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices, GL_STATIC_DRAW);
   AssertNoGLError();
 }
 
 void MediaStreamVideoDemoInstance::CreateShader(
-    GLuint program, GLenum type, const char* source, int size) {
-  PP_Resource context = context_->pp_resource();
-  GLuint shader = gles2_if_->CreateShader(context, type);
-  gles2_if_->ShaderSource(context, shader, 1, &source, &size);
-  gles2_if_->CompileShader(context, shader);
-  gles2_if_->AttachShader(context, program, shader);
-  gles2_if_->DeleteShader(context, shader);
+    GLuint program, GLenum type, const char* source) {
+  GLuint shader = glCreateShader(type);
+  GLint length = static_cast<GLint>(strlen(source) + 1);
+  glShaderSource(shader, 1, &source, &length);
+  glCompileShader(shader);
+  glAttachShader(program, shader);
+  glDeleteShader(shader);
 }
 
 void MediaStreamVideoDemoInstance::CreateTextures() {
@@ -420,13 +394,13 @@
   if (width == 0 || height == 0)
     return;
   if (texture_y_)
-    gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_y_);
+    glDeleteTextures(1, &texture_y_);
   if (texture_u_)
-    gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_u_);
+    glDeleteTextures(1, &texture_u_);
   if (texture_v_)
-    gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_v_);
+    glDeleteTextures(1, &texture_v_);
   if (texture_rgb_)
-    gles2_if_->DeleteTextures(context_->pp_resource(), 1, &texture_rgb_);
+    glDeleteTextures(1, &texture_rgb_);
   texture_y_ = CreateTexture(width, height, 0, false);
 
   texture_u_ = CreateTexture(width / 2, height / 2, 1, false);
@@ -468,30 +442,26 @@
   int32_t width = frame_size_.width();
   int32_t height = frame_size_.height();
   if (!is_bgra_) {
-    gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE0);
-    gles2_if_->TexSubImage2D(
-        context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
-        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+    glActiveTexture(GL_TEXTURE0);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
 
     data += width * height;
     width /= 2;
     height /= 2;
 
-    gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE1);
-    gles2_if_->TexSubImage2D(
-        context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
-        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+    glActiveTexture(GL_TEXTURE1);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
 
     data += width * height;
-    gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE2);
-    gles2_if_->TexSubImage2D(
-        context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
-        GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+    glActiveTexture(GL_TEXTURE2);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
   } else {
-    gles2_if_->ActiveTexture(context_->pp_resource(), GL_TEXTURE3);
-    gles2_if_->TexSubImage2D(
-        context_->pp_resource(), GL_TEXTURE_2D, 0, 0, 0, width, height,
-        GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
+    glActiveTexture(GL_TEXTURE3);
+    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
+                    GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
   }
 
   if (is_painting_)
diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py
index 73b15ca..c304fc9 100755
--- a/ppapi/generators/idl_parser.py
+++ b/ppapi/generators/idl_parser.py
@@ -268,6 +268,33 @@
     if self.parse_debug: DumpReduction('modifiers', p)
 
 #
+# Scoped name is a name with an optional scope.
+#
+# Used for types and namespace names. eg. foo_bar.hello_world, or
+# foo_bar.hello_world.SomeType.
+#
+  def p_scoped_name(self, p):
+    """scoped_name : SYMBOL scoped_name_rest"""
+    p[0] = ''.join(p[1:])
+    if self.parse_debug: DumpReduction('scoped_name', p)
+
+  def p_scoped_name_rest(self, p):
+    """scoped_name_rest : '.' scoped_name
+                        |"""
+    p[0] = ''.join(p[1:])
+    if self.parse_debug: DumpReduction('scoped_name_rest', p)
+
+#
+# Type reference
+#
+#
+  def p_typeref(self, p):
+    """typeref : scoped_name"""
+    p[0] = p[1]
+    if self.parse_debug: DumpReduction('typeref', p)
+
+
+#
 # Comments
 #
 # Comments are optional list of C style comment objects.  Comments are returned
@@ -296,9 +323,8 @@
 
   # We allow namespace names of the form foo.bar.baz.
   def p_namespace_name(self, p):
-    """namespace_name : SYMBOL
-                      | SYMBOL '.' namespace_name"""
-    p[0] = "".join(p[1:])
+    """namespace_name : scoped_name"""
+    p[0] = p[1]
 
 
 #
@@ -621,7 +647,7 @@
     if self.parse_debug: DumpReduction('param_list', p)
 
   def p_param_item(self, p):
-    """param_item : modifiers optional SYMBOL arrays identifier"""
+    """param_item : modifiers optional typeref arrays identifier"""
     typeref = self.BuildAttribute('TYPEREF', p[3])
     children = ListFromConcat(p[1], p[2], typeref, p[4])
     p[0] = self.BuildNamed('Param', p, 5, children)
@@ -760,7 +786,7 @@
 # A member attribute or function of a struct or interface.
 #
   def p_member_attribute(self, p):
-    """member_attribute : modifiers SYMBOL arrays questionmark identifier"""
+    """member_attribute : modifiers typeref arrays questionmark identifier"""
     typeref = self.BuildAttribute('TYPEREF', p[2])
     children = ListFromConcat(p[1], typeref, p[3], p[4])
     p[0] = self.BuildNamed('Member', p, 5, children)
@@ -774,7 +800,7 @@
     if self.parse_debug: DumpReduction('attribute', p)
 
   def p_member_function(self, p):
-    """member_function : modifiers static SYMBOL arrays SYMBOL param_list"""
+    """member_function : modifiers static typeref arrays SYMBOL param_list"""
     typeref = self.BuildAttribute('TYPEREF', p[3])
     children = ListFromConcat(p[1], p[2], typeref, p[4], p[6])
     p[0] = self.BuildNamed('Member', p, 5, children)
diff --git a/ppapi/nacl_irt/DEPS b/ppapi/nacl_irt/DEPS
new file mode 100644
index 0000000..b759edf
--- /dev/null
+++ b/ppapi/nacl_irt/DEPS
@@ -0,0 +1,15 @@
+include_rules = [
+  "+components/tracing",
+
+  # We don't want the proxy to depend on the C++ layer, which is appropriate
+  # for plugins only.
+  "-ppapi/cpp",
+
+  # The untrusted build references the NaCl integrated runtime (IRT).
+  "+native_client/src/public",
+  "+native_client/src/shared/srpc/nacl_srpc.h",
+  "+native_client/src/untrusted/irt/irt.h",
+  "+native_client/src/untrusted/irt/irt_private.h",
+  # The IRT also needs to know the sysconf enums.
+  "+native_client/src/trusted/service_runtime/include/sys/unistd.h",
+]
diff --git a/ppapi/proxy/irt_ppapi.c b/ppapi/nacl_irt/irt_ppapi.cc
similarity index 77%
rename from ppapi/proxy/irt_ppapi.c
rename to ppapi/nacl_irt/irt_ppapi.cc
index 8bf1233..1d41f51 100644
--- a/ppapi/proxy/irt_ppapi.c
+++ b/ppapi/nacl_irt/irt_ppapi.cc
@@ -1,21 +1,20 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #include "native_client/src/public/irt_core.h"
 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h"
 #include "native_client/src/untrusted/irt/irt.h"
 #include "native_client/src/untrusted/irt/irt_private.h"
 #include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/plugin_main.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h"
-#include "ppapi/proxy/plugin_main_irt.h"
 
 static struct PP_StartFunctions g_pp_functions;
 
 int irt_ppapi_start(const struct PP_StartFunctions* funcs) {
-  /* Disable NaCl's open_resource() interface on this thread. */
+  // Disable NaCl's open_resource() interface on this thread.
   g_is_main_thread = 1;
 
   g_pp_functions = *funcs;
@@ -55,16 +54,11 @@
     ppapihook_pnacl_private_filter },
 };
 
-static size_t chrome_irt_query(const char* interface_ident,
-                               void* table, size_t tablesize) {
+size_t chrome_irt_query(const char* interface_ident,
+                        void* table, size_t tablesize) {
   size_t result = nacl_irt_query_core(interface_ident, table, tablesize);
   if (result != 0)
     return result;
   return nacl_irt_query_list(interface_ident, table, tablesize,
                              irt_interfaces, sizeof(irt_interfaces));
 }
-
-void nacl_irt_start(uint32_t* info) {
-  nacl_irt_init(info);
-  nacl_irt_enter_user_code(info, chrome_irt_query);
-}
diff --git a/ppapi/nacl_irt/irt_ppapi.h b/ppapi/nacl_irt/irt_ppapi.h
index 344e10c..bc2e74c 100644
--- a/ppapi/nacl_irt/irt_ppapi.h
+++ b/ppapi/nacl_irt/irt_ppapi.h
@@ -1,42 +1,13 @@
-/*
- * Copyright 2014 The Chromium Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #ifndef PPAPI_NACL_IRT_IRT_PPAPI_H_
 #define PPAPI_NACL_IRT_IRT_PPAPI_H_
 
-#include <stddef.h>
+extern "C" int irt_ppapi_start(const struct PP_StartFunctions* funcs);
 
-#include "ppapi/c/ppp.h"
+size_t chrome_irt_query(const char* interface_ident,
+                        void* table, size_t tablesize);
 
-struct PP_StartFunctions {
-  int32_t (*PPP_InitializeModule)(PP_Module module_id,
-                                  PPB_GetInterface get_browser_interface);
-  void (*PPP_ShutdownModule)();
-  const void* (*PPP_GetInterface)(const char* interface_name);
-};
-
-struct PP_ThreadFunctions {
-  /*
-   * This is a cut-down version of pthread_create()/pthread_join().
-   * We omit thread creation attributes and the thread's return value.
-   *
-   * We use uintptr_t as the thread ID type because pthread_t is not
-   * part of the stable ABI; a user thread library might choose an
-   * arbitrary size for its own pthread_t.
-   */
-  int (*thread_create)(uintptr_t* tid,
-                       void (*func)(void* thread_argument),
-                       void* thread_argument);
-  int (*thread_join)(uintptr_t tid);
-};
-
-#define NACL_IRT_PPAPIHOOK_v0_1 "nacl-irt-ppapihook-0.1"
-struct nacl_irt_ppapihook {
-  int (*ppapi_start)(const struct PP_StartFunctions*);
-  void (*ppapi_register_thread_creator)(const struct PP_ThreadFunctions*);
-};
-
-#endif
+#endif  // PPAPI_NACL_IRT_IRT_PPAPI_H_
diff --git a/ppapi/nacl_irt/irt_start.cc b/ppapi/nacl_irt/irt_start.cc
new file mode 100644
index 0000000..a286737
--- /dev/null
+++ b/ppapi/nacl_irt/irt_start.cc
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/at_exit.h"
+#include "native_client/src/public/chrome_main.h"
+#include "native_client/src/public/irt_core.h"
+#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
+
+void nacl_irt_start(uint32_t* info) {
+  nacl_irt_init(info);
+
+  // Though it isn't referenced here, we must instantiate an AtExitManager.
+  base::AtExitManager exit_manager;
+
+  // In SFI mode, the FDs of IPC channels are NACL_CHROME_DESC_BASE and its
+  // successor, which is set in nacl_listener.cc.
+  ppapi::SetIPCFileDescriptors(
+      NACL_CHROME_DESC_BASE, NACL_CHROME_DESC_BASE + 1);
+  ppapi::StartUpPlugin();
+
+  nacl_irt_enter_user_code(info, chrome_irt_query);
+}
diff --git a/ppapi/nacl_irt/plugin_main.cc b/ppapi/nacl_irt/plugin_main.cc
new file mode 100644
index 0000000..eeeb50b
--- /dev/null
+++ b/ppapi/nacl_irt/plugin_main.cc
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/nacl_irt/plugin_main.h"
+
+#include "build/build_config.h"
+// Need to include this before most other files because it defines
+// IPC_MESSAGE_LOG_ENABLED. We need to use it to define
+// IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the
+// ViewMsgLog et al. functions.
+
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread.h"
+#include "ipc/ipc_logging.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
+#include "ppapi/nacl_irt/ppapi_dispatcher.h"
+#include "ppapi/proxy/plugin_globals.h"
+#include "ppapi/shared_impl/ppb_audio_shared.h"
+
+#if defined(__native_client__)
+#include "native_client/src/shared/srpc/nacl_srpc.h"
+#endif
+
+void PpapiPluginRegisterThreadCreator(
+    const struct PP_ThreadFunctions* thread_functions) {
+#if defined(__native_client__)
+  // TODO(hidehiko): The thread creation for the PPB_Audio is not yet
+  // implemented on non-SFI mode. Support this. Now, this function invocation
+  // is just ignored.
+
+  // Initialize all classes that need to create threads that call back into
+  // user code.
+  ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions);
+#endif
+}
+
+int PpapiPluginMain() {
+  base::MessageLoop loop;
+  ppapi::proxy::PluginGlobals plugin_globals;
+
+#if defined(__native_client__)
+  // Currently on non-SFI mode, we don't use SRPC server on plugin.
+  // TODO(hidehiko): Make sure this SRPC is actually used on SFI-mode.
+
+  // Start up the SRPC server on another thread. Otherwise, when it blocks
+  // on an RPC, the PPAPI proxy will hang. Do this before we initialize the
+  // module and start the PPAPI proxy so that the NaCl plugin can continue
+  // loading the app.
+  static struct NaClSrpcHandlerDesc srpc_methods[] = { { NULL, NULL } };
+  if (!NaClSrpcAcceptClientOnThread(srpc_methods)) {
+    return 1;
+  }
+#endif
+
+  ppapi::PpapiDispatcher ppapi_dispatcher(
+      ppapi::GetIOThread()->message_loop_proxy(),
+      ppapi::GetShutdownEvent(),
+      ppapi::GetBrowserIPCFileDescriptor(),
+      ppapi::GetRendererIPCFileDescriptor());
+  plugin_globals.set_plugin_proxy_delegate(&ppapi_dispatcher);
+
+  loop.Run();
+
+  return 0;
+}
diff --git a/ppapi/nacl_irt/plugin_main.h b/ppapi/nacl_irt/plugin_main.h
new file mode 100644
index 0000000..75fc112
--- /dev/null
+++ b/ppapi/nacl_irt/plugin_main.h
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_NACL_IRT_PLUGIN_MAIN_H_
+#define PPAPI_NACL_IRT_PLUGIN_MAIN_H_
+
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// The entry point for the main thread of the PPAPI plugin process.
+PPAPI_PROXY_EXPORT int PpapiPluginMain(void);
+
+PPAPI_PROXY_EXPORT void PpapiPluginRegisterThreadCreator(
+    const struct PP_ThreadFunctions* new_funcs);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // PPAPI_NACL_IRT_PLUGIN_MAIN_H_
diff --git a/ppapi/nacl_irt/plugin_startup.cc b/ppapi/nacl_irt/plugin_startup.cc
new file mode 100644
index 0000000..a3b5bc2
--- /dev/null
+++ b/ppapi/nacl_irt/plugin_startup.cc
@@ -0,0 +1,64 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/logging.h"
+#include "base/synchronization/waitable_event.h"
+#include "base/threading/thread.h"
+#include "ppapi/nacl_irt/plugin_startup.h"
+
+namespace ppapi {
+namespace {
+
+int g_nacl_browser_ipc_fd = -1;
+int g_nacl_renderer_ipc_fd = -1;
+
+base::WaitableEvent* g_shutdown_event = NULL;
+base::Thread* g_io_thread = NULL;
+
+}  // namespace
+
+void SetIPCFileDescriptors(int browser_ipc_fd, int renderer_ipc_fd) {
+  // The initialization must be only once.
+  DCHECK_EQ(g_nacl_browser_ipc_fd, -1);
+  DCHECK_EQ(g_nacl_renderer_ipc_fd, -1);
+  g_nacl_browser_ipc_fd = browser_ipc_fd;
+  g_nacl_renderer_ipc_fd = renderer_ipc_fd;
+}
+
+void StartUpPlugin() {
+  // The start up must be called only once.
+  DCHECK(!g_shutdown_event);
+  DCHECK(!g_io_thread);
+
+  g_shutdown_event = new base::WaitableEvent(true, false);
+  g_io_thread = new base::Thread("Chrome_NaClIOThread");
+  g_io_thread->StartWithOptions(
+      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
+}
+
+int GetBrowserIPCFileDescriptor() {
+  // The descriptor must be initialized in advance.
+  DCHECK_NE(g_nacl_browser_ipc_fd, -1);
+  return g_nacl_browser_ipc_fd;
+}
+
+int GetRendererIPCFileDescriptor() {
+  // The descriptor must be initialized in advance.
+  DCHECK_NE(g_nacl_renderer_ipc_fd, -1);
+  return g_nacl_renderer_ipc_fd;
+}
+
+base::WaitableEvent* GetShutdownEvent() {
+  // The shutdown event must be initialized in advance.
+  DCHECK(g_shutdown_event);
+  return g_shutdown_event;
+}
+
+base::Thread* GetIOThread() {
+  // The IOThread must be initialized in advance.
+  DCHECK(g_io_thread);
+  return g_io_thread;
+}
+
+}  // namespace ppapi
diff --git a/ppapi/nacl_irt/plugin_startup.h b/ppapi/nacl_irt/plugin_startup.h
new file mode 100644
index 0000000..73c3495
--- /dev/null
+++ b/ppapi/nacl_irt/plugin_startup.h
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_NACL_IRT_PLUGIN_STARTUP_H_
+#define PPAPI_NACL_IRT_PLUGIN_STARTUP_H_
+
+#include "ppapi/proxy/ppapi_proxy_export.h"
+
+namespace base {
+class Thread;
+class WaitableEvent;
+}  // namespace base
+
+namespace ppapi {
+
+// Sets the IPC channels for the browser and the renderer by the given FD
+// numbers. This will be used for non-SFI mode. Must be called before
+// PpapiPluginMain is called.
+PPAPI_PROXY_EXPORT void SetIPCFileDescriptors(
+    int browser_ipc_fd, int renderer_ipc_fd);
+
+// Runs start up procedure for the plugin.
+// Specifically, start background IO thread for IPC, and prepare
+// shutdown event instance.
+PPAPI_PROXY_EXPORT void StartUpPlugin();
+
+// Returns IPC file descriptor for PPAPI to the browser.
+int GetBrowserIPCFileDescriptor();
+
+// Returns IPC file descriptor for PPAPI to the renderer.
+int GetRendererIPCFileDescriptor();
+
+// Returns the shutdown event instance for the plugin.
+// Must be called after StartUpPlugin().
+base::WaitableEvent* GetShutdownEvent();
+
+// Returns the IOThread for the plugin. Must be called after StartUpPlugin().
+base::Thread* GetIOThread();
+
+}  // namespace ppapi
+
+#endif  // PPAPI_NACL_IRT_PLUGIN_STARTUP_H_
diff --git a/ppapi/nacl_irt/ppapi_dispatcher.cc b/ppapi/nacl_irt/ppapi_dispatcher.cc
new file mode 100644
index 0000000..c0aa400
--- /dev/null
+++ b/ppapi/nacl_irt/ppapi_dispatcher.cc
@@ -0,0 +1,219 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/nacl_irt/ppapi_dispatcher.h"
+
+#include <map>
+#include <set>
+
+#include "build/build_config.h"
+// Need to include this before most other files because it defines
+// IPC_MESSAGE_LOG_ENABLED. We need to use it to define
+// IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the
+// ViewMsgLog et al. functions.
+
+#include "base/command_line.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/synchronization/waitable_event.h"
+#include "components/tracing/child_trace_message_filter.h"
+#include "ipc/ipc_channel_handle.h"
+#include "ipc/ipc_logging.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/c/ppp_instance.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_globals.h"
+#include "ppapi/proxy/plugin_message_filter.h"
+#include "ppapi/proxy/plugin_proxy_delegate.h"
+#include "ppapi/proxy/resource_reply_thread_registrar.h"
+
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+#include "base/containers/hash_tables.h"
+
+LogFunctionMap g_log_function_mapping;
+
+#define IPC_MESSAGE_MACROS_LOG_ENABLED
+#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
+  g_log_function_mapping[msg_id] = logger
+
+#endif
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace ppapi {
+
+PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop,
+                                 base::WaitableEvent* shutdown_event,
+                                 int browser_ipc_fd,
+                                 int renderer_ipc_fd)
+    : next_plugin_dispatcher_id_(0),
+      message_loop_(io_loop),
+      shutdown_event_(shutdown_event),
+      renderer_ipc_fd_(renderer_ipc_fd) {
+#if defined(IPC_MESSAGE_LOG_ENABLED)
+  IPC::Logging::set_log_function_map(&g_log_function_mapping);
+#endif
+
+  IPC::ChannelHandle channel_handle(
+      "NaCl IPC", base::FileDescriptor(browser_ipc_fd, false));
+
+  // Delay initializing the SyncChannel until after we add filters. This
+  // ensures that the filters won't miss any messages received by
+  // the channel.
+  channel_.reset(new IPC::SyncChannel(
+      this, GetIPCMessageLoop(), GetShutdownEvent()));
+  channel_->AddFilter(new proxy::PluginMessageFilter(
+      NULL, proxy::PluginGlobals::Get()->resource_reply_thread_registrar()));
+  channel_->AddFilter(
+      new tracing::ChildTraceMessageFilter(message_loop_.get()));
+  channel_->Init(channel_handle, IPC::Channel::MODE_SERVER, true);
+}
+
+base::MessageLoopProxy* PpapiDispatcher::GetIPCMessageLoop() {
+  return message_loop_.get();
+}
+
+base::WaitableEvent* PpapiDispatcher::GetShutdownEvent() {
+  return shutdown_event_;
+}
+
+IPC::PlatformFileForTransit PpapiDispatcher::ShareHandleWithRemote(
+    base::PlatformFile handle,
+    base::ProcessId peer_pid,
+    bool should_close_source) {
+  return IPC::InvalidPlatformFileForTransit();
+}
+
+std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() {
+  return &instances_;
+}
+
+uint32 PpapiDispatcher::Register(proxy::PluginDispatcher* plugin_dispatcher) {
+  if (!plugin_dispatcher ||
+      plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
+    return 0;
+  }
+
+  uint32 id = 0;
+  do {
+    // Although it is unlikely, make sure that we won't cause any trouble
+    // when the counter overflows.
+    id = next_plugin_dispatcher_id_++;
+  } while (id == 0 ||
+           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
+  plugin_dispatchers_[id] = plugin_dispatcher;
+  return id;
+}
+
+void PpapiDispatcher::Unregister(uint32 plugin_dispatcher_id) {
+  plugin_dispatchers_.erase(plugin_dispatcher_id);
+}
+
+IPC::Sender* PpapiDispatcher::GetBrowserSender() {
+  return this;
+}
+
+std::string PpapiDispatcher::GetUILanguage() {
+  NOTIMPLEMENTED();
+  return std::string();
+}
+
+void PpapiDispatcher::PreCacheFont(const void* logfontw) {
+  NOTIMPLEMENTED();
+}
+
+void PpapiDispatcher::SetActiveURL(const std::string& url) {
+  NOTIMPLEMENTED();
+}
+
+PP_Resource PpapiDispatcher::CreateBrowserFont(
+    proxy::Connection connection,
+    PP_Instance instance,
+    const PP_BrowserFont_Trusted_Description& desc,
+    const Preferences& prefs) {
+  NOTIMPLEMENTED();
+  return 0;
+}
+
+bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) {
+  IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg)
+    IPC_MESSAGE_HANDLER(PpapiMsg_InitializeNaClDispatcher,
+                        OnMsgInitializeNaClDispatcher)
+    // All other messages are simply forwarded to a PluginDispatcher.
+    IPC_MESSAGE_UNHANDLED(OnPluginDispatcherMessageReceived(msg))
+  IPC_END_MESSAGE_MAP()
+  return true;
+}
+
+void PpapiDispatcher::OnChannelError() {
+  exit(1);
+}
+
+bool PpapiDispatcher::Send(IPC::Message* msg) {
+  return channel_->Send(msg);
+}
+
+void PpapiDispatcher::OnMsgInitializeNaClDispatcher(
+    const PpapiNaClPluginArgs& args) {
+  static bool command_line_and_logging_initialized = false;
+  if (command_line_and_logging_initialized) {
+    LOG(FATAL) << "InitializeNaClDispatcher must be called once per plugin.";
+    return;
+  }
+
+  command_line_and_logging_initialized = true;
+  CommandLine::Init(0, NULL);
+  for (size_t i = 0; i < args.switch_names.size(); ++i) {
+    DCHECK(i < args.switch_values.size());
+    CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+        args.switch_names[i], args.switch_values[i]);
+  }
+  logging::LoggingSettings settings;
+  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
+  logging::InitLogging(settings);
+
+  proxy::PluginGlobals::Get()->set_keepalive_throttle_interval_milliseconds(
+      args.keepalive_throttle_interval_milliseconds);
+
+  // Tell the process-global GetInterface which interfaces it can return to the
+  // plugin.
+  proxy::InterfaceList::SetProcessGlobalPermissions(args.permissions);
+
+  int32_t error = ::PPP_InitializeModule(
+      0 /* module */,
+      &proxy::PluginDispatcher::GetBrowserInterface);
+  if (error)
+    ::exit(error);
+
+  proxy::PluginDispatcher* dispatcher =
+      new proxy::PluginDispatcher(::PPP_GetInterface, args.permissions,
+                                  args.off_the_record);
+  IPC::ChannelHandle channel_handle(
+      "nacl",
+      base::FileDescriptor(renderer_ipc_fd_, false));
+  if (!dispatcher->InitPluginWithChannel(this, base::kNullProcessId,
+                                         channel_handle, false)) {
+    delete dispatcher;
+    return;
+  }
+  // From here, the dispatcher will manage its own lifetime according to the
+  // lifetime of the attached channel.
+}
+
+void PpapiDispatcher::OnPluginDispatcherMessageReceived(
+    const IPC::Message& msg) {
+  // The first parameter should be a plugin dispatcher ID.
+  PickleIterator iter(msg);
+  uint32 id = 0;
+  if (!msg.ReadUInt32(&iter, &id)) {
+    NOTREACHED();
+    return;
+  }
+  std::map<uint32, proxy::PluginDispatcher*>::iterator dispatcher =
+      plugin_dispatchers_.find(id);
+  if (dispatcher != plugin_dispatchers_.end())
+    dispatcher->second->OnMessageReceived(msg);
+}
+
+}  // namespace ppapi
diff --git a/ppapi/nacl_irt/ppapi_dispatcher.h b/ppapi/nacl_irt/ppapi_dispatcher.h
new file mode 100644
index 0000000..21829db
--- /dev/null
+++ b/ppapi/nacl_irt/ppapi_dispatcher.h
@@ -0,0 +1,100 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_NACL_IRT_PPAPI_DISPATCHER_H_
+#define PPAPI_NACL_IRT_PPAPI_DISPATCHER_H_
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/platform_file.h"
+#include "base/process/process_handle.h"
+#include "ipc/ipc_listener.h"
+#include "ipc/ipc_platform_file.h"
+#include "ipc/ipc_sender.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/trusted/ppb_browser_font_trusted.h"
+#include "ppapi/proxy/connection.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/plugin_proxy_delegate.h"
+
+struct PP_BrowserFont_Trusted_Description;
+
+namespace base {
+class MessageLoopProxy;
+class WaitableEvent;
+}  // namespace base
+
+namespace IPC {
+class Message;
+class SyncChannel;
+}  // namespace IPC
+
+namespace ppapi {
+
+struct PpapiNaClPluginArgs;
+struct Preferences;
+
+// This class manages communication between the plugin and the browser, and
+// manages the PluginDispatcher instances for communication between the plugin
+// and the renderer.
+class PpapiDispatcher : public proxy::PluginDispatcher::PluginDelegate,
+                        public proxy::PluginProxyDelegate,
+                        public IPC::Listener,
+                        public IPC::Sender {
+ public:
+  PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop,
+                  base::WaitableEvent* shutdown_event,
+                  int browser_ipc_fd,
+                  int renderer_ipc_fd);
+
+  // PluginDispatcher::PluginDelegate implementation.
+  virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE;
+  virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE;
+  virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
+      base::PlatformFile handle,
+      base::ProcessId peer_pid,
+      bool should_close_source) OVERRIDE;
+  virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE;
+  virtual uint32 Register(
+      proxy::PluginDispatcher* plugin_dispatcher) OVERRIDE;
+  virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE;
+
+  // PluginProxyDelegate implementation.
+  virtual IPC::Sender* GetBrowserSender() OVERRIDE;
+  virtual std::string GetUILanguage() OVERRIDE;
+  virtual void PreCacheFont(const void* logfontw) OVERRIDE;
+  virtual void SetActiveURL(const std::string& url) OVERRIDE;
+  virtual PP_Resource CreateBrowserFont(
+      proxy::Connection connection,
+      PP_Instance instance,
+      const PP_BrowserFont_Trusted_Description& desc,
+      const Preferences& prefs) OVERRIDE;
+
+  // IPC::Listener implementation.
+  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+  virtual void OnChannelError() OVERRIDE;
+
+  // IPC::Sender implementation
+  virtual bool Send(IPC::Message* message) OVERRIDE;
+
+ private:
+  void OnMsgInitializeNaClDispatcher(const PpapiNaClPluginArgs& args);
+  void OnPluginDispatcherMessageReceived(const IPC::Message& msg);
+
+  std::set<PP_Instance> instances_;
+  std::map<uint32, proxy::PluginDispatcher*> plugin_dispatchers_;
+  uint32 next_plugin_dispatcher_id_;
+
+  scoped_refptr<base::MessageLoopProxy> message_loop_;
+  base::WaitableEvent* shutdown_event_;
+  int renderer_ipc_fd_;
+  scoped_ptr<IPC::SyncChannel> channel_;
+};
+
+}  // namespace ppapi
+
+#endif  // PPAPI_NACL_IRT_PPAPI_DISPATCHER_H_
diff --git a/ppapi/nacl_irt/README b/ppapi/nacl_irt/public/README
similarity index 100%
rename from ppapi/nacl_irt/README
rename to ppapi/nacl_irt/public/README
diff --git a/ppapi/nacl_irt/public/irt_ppapi.h b/ppapi/nacl_irt/public/irt_ppapi.h
new file mode 100644
index 0000000..04b4f10
--- /dev/null
+++ b/ppapi/nacl_irt/public/irt_ppapi.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef PPAPI_NACL_IRT_PUBLIC_IRT_PPAPI_H_
+#define PPAPI_NACL_IRT_PUBLIC_IRT_PPAPI_H_
+
+#include <stddef.h>
+
+#include "ppapi/c/ppp.h"
+
+struct PP_StartFunctions {
+  int32_t (*PPP_InitializeModule)(PP_Module module_id,
+                                  PPB_GetInterface get_browser_interface);
+  void (*PPP_ShutdownModule)();
+  const void* (*PPP_GetInterface)(const char* interface_name);
+};
+
+struct PP_ThreadFunctions {
+  /*
+   * This is a cut-down version of pthread_create()/pthread_join().
+   * We omit thread creation attributes and the thread's return value.
+   *
+   * We use uintptr_t as the thread ID type because pthread_t is not
+   * part of the stable ABI; a user thread library might choose an
+   * arbitrary size for its own pthread_t.
+   */
+  int (*thread_create)(uintptr_t* tid,
+                       void (*func)(void* thread_argument),
+                       void* thread_argument);
+  int (*thread_join)(uintptr_t tid);
+};
+
+#define NACL_IRT_PPAPIHOOK_v0_1 "nacl-irt-ppapihook-0.1"
+struct nacl_irt_ppapihook {
+  int (*ppapi_start)(const struct PP_StartFunctions*);
+  void (*ppapi_register_thread_creator)(const struct PP_ThreadFunctions*);
+};
+
+#endif  // PPAPI_NACL_IRT_PUBLIC_IRT_PPAPI_H_
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h b/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h
index ac23a34..d8618fb 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h
@@ -8,7 +8,7 @@
 #define NATIVE_CLIENT_SRC_SHARED_PPAPI_PROXY_PPRUNTIME_H_
 
 #include "native_client/src/include/portability.h"
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 
 EXTERN_C_BEGIN
 
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.cc b/ppapi/native_client/src/trusted/plugin/plugin.cc
index 1b735f5..9de8e0f 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.cc
+++ b/ppapi/native_client/src/trusted/plugin/plugin.cc
@@ -80,22 +80,10 @@
 const int64_t kTimeMediumMax = 200000;     // in ms
 const uint32_t kTimeMediumBuckets = 100;
 
-// Up to 33 minutes.
-const int64_t kTimeLargeMin = 100;         // in ms
-const int64_t kTimeLargeMax = 2000000;     // in ms
-const uint32_t kTimeLargeBuckets = 100;
-
 const int64_t kSizeKBMin = 1;
 const int64_t kSizeKBMax = 512*1024;     // very large .nexe
 const uint32_t kSizeKBBuckets = 100;
 
-const PPB_NaCl_Private* GetNaClInterface() {
-  pp::Module *module = pp::Module::Get();
-  CHECK(module);
-  return static_cast<const PPB_NaCl_Private*>(
-      module->GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE));
-}
-
 }  // namespace
 
 bool Plugin::EarlyInit(int argc, const char* argn[], const char* argv[]) {
@@ -163,15 +151,6 @@
                                       kTimeMediumBuckets);
 }
 
-void Plugin::HistogramTimeLarge(const std::string& name,
-                                int64_t ms) {
-  if (ms < 0) return;
-  uma_interface_.HistogramCustomTimes(name,
-                                      ms,
-                                      kTimeLargeMin, kTimeLargeMax,
-                                      kTimeLargeBuckets);
-}
-
 void Plugin::HistogramSizeKB(const std::string& name,
                              int32_t sample) {
   if (sample < 0) return;
@@ -196,40 +175,6 @@
   uma_interface_.HistogramEnumeration(name, sample, maximum);
 }
 
-void Plugin::HistogramEnumerateOsArch(const std::string& sandbox_isa) {
-  enum NaClOSArch {
-    kNaClLinux32 = 0,
-    kNaClLinux64,
-    kNaClLinuxArm,
-    kNaClMac32,
-    kNaClMac64,
-    kNaClMacArm,
-    kNaClWin32,
-    kNaClWin64,
-    kNaClWinArm,
-    kNaClLinuxMips,
-    kNaClOSArchMax
-  };
-
-  NaClOSArch os_arch = kNaClOSArchMax;
-#if NACL_LINUX
-  os_arch = kNaClLinux32;
-#elif NACL_OSX
-  os_arch = kNaClMac32;
-#elif NACL_WINDOWS
-  os_arch = kNaClWin32;
-#endif
-
-  if (sandbox_isa == "x86-64")
-    os_arch = static_cast<NaClOSArch>(os_arch + 1);
-  if (sandbox_isa == "arm")
-    os_arch = static_cast<NaClOSArch>(os_arch + 2);
-  if (sandbox_isa == "mips32")
-    os_arch = kNaClLinuxMips;
-
-  HistogramEnumerate("NaCl.Client.OSArch", os_arch, kNaClOSArchMax, -1);
-}
-
 void Plugin::HistogramEnumerateSelLdrLoadStatus(NaClErrorCode error_code) {
   HistogramEnumerate("NaCl.LoadStatus.SelLdr", error_code,
                      NACL_ERROR_CODE_MAX, LOAD_STATUS_UNKNOWN);
@@ -382,7 +327,8 @@
   }
 }
 
-bool Plugin::LoadNaClModuleContinuationIntern(ErrorInfo* error_info) {
+bool Plugin::LoadNaClModuleContinuationIntern() {
+  ErrorInfo error_info;
   if (!uses_nonsfi_mode_) {
     if (!main_subprocess_.StartSrpcServices()) {
       // The NaCl process probably crashed. On Linux, a crash causes this
@@ -391,35 +337,19 @@
       // to make it less confusing for developers.
       NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: "
               "StartSrpcServices failed\n");
-      error_info->SetReport(PP_NACL_ERROR_START_PROXY_MODULE,
-                            "could not initialize module.");
+      error_info.SetReport(PP_NACL_ERROR_START_PROXY_MODULE,
+                           "could not initialize module.");
+      ReportLoadError(error_info);
       return false;
     }
   }
-  PP_ExternalPluginResult ipc_result =
-      nacl_interface_->StartPpapiProxy(pp_instance());
-  if (ipc_result == PP_EXTERNAL_PLUGIN_OK) {
-    // Log the amound of time that has passed between the trusted plugin being
-    // initialized and the untrusted plugin being initialized.  This is
-    // (roughly) the cost of using NaCl, in terms of startup time.
-    HistogramStartupTimeMedium(
-        "NaCl.Perf.StartupTime.NaClOverhead",
-        static_cast<float>(NaClGetTimeOfDayMicroseconds() - init_time_)
-            / NACL_MICROS_PER_MILLI);
-  } else if (ipc_result == PP_EXTERNAL_PLUGIN_ERROR_MODULE) {
-    NaClLog(LOG_ERROR, "LoadNaClModuleContinuationIntern: "
-            "Got PP_EXTERNAL_PLUGIN_ERROR_MODULE\n");
-    error_info->SetReport(PP_NACL_ERROR_START_PROXY_MODULE,
-                          "could not initialize module.");
-    return false;
-  } else if (ipc_result == PP_EXTERNAL_PLUGIN_ERROR_INSTANCE) {
-    error_info->SetReport(PP_NACL_ERROR_START_PROXY_INSTANCE,
-                          "could not create instance.");
-    return false;
+
+  bool result = PP_ToBool(nacl_interface_->StartPpapiProxy(pp_instance()));
+  if (result) {
+    PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n",
+                   main_subprocess_.detailed_description().c_str()));
   }
-  PLUGIN_PRINTF(("Plugin::LoadNaClModule (%s)\n",
-                 main_subprocess_.detailed_description().c_str()));
-  return true;
+  return result;
 }
 
 NaClSubprocess* Plugin::LoadHelperNaClModule(const nacl::string& helper_url,
@@ -512,8 +442,9 @@
 // failure. Note that module loading functions will log their own errors.
 bool Plugin::Init(uint32_t argc, const char* argn[], const char* argv[]) {
   PLUGIN_PRINTF(("Plugin::Init (argc=%" NACL_PRIu32 ")\n", argc));
-  HistogramEnumerateOsArch(nacl_interface_->GetSandboxArch());
   init_time_ = NaClGetTimeOfDayMicroseconds();
+  nacl_interface_->SetInitTime(pp_instance());
+
   url_util_ = pp::URLUtil_Dev::Get();
   if (url_util_ == NULL)
     return false;
@@ -580,9 +511,8 @@
       wrapper_factory_(NULL),
       enable_dev_interfaces_(false),
       init_time_(0),
-      nexe_size_(0),
+      ready_time_(0),
       time_of_last_progress_event_(0),
-      exit_status_(-1),
       nacl_interface_(NULL),
       uma_interface_(this) {
   PLUGIN_PRINTF(("Plugin::Plugin (this=%p, pp_instance=%"
@@ -609,13 +539,6 @@
   // Destroy the coordinator while the rest of the data is still there
   pnacl_coordinator_.reset(NULL);
 
-  int64_t ready_time = nacl_interface_->GetReadyTime(pp_instance());
-  if (!nacl_interface_->GetNexeErrorReported(pp_instance())) {
-    HistogramTimeLarge(
-        "NaCl.ModuleUptime.Normal",
-        (shutdown_start - ready_time) / NACL_MICROS_PER_MILLI);
-  }
-
   for (std::map<nacl::string, NaClFileInfoAutoCloser*>::iterator it =
            url_file_info_map_.begin();
        it != url_file_info_map_.end();
@@ -673,16 +596,18 @@
 }
 
 void Plugin::HistogramStartupTimeSmall(const std::string& name, float dt) {
-  if (nexe_size_ > 0) {
-    float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f);
+  int64_t nexe_size = nacl_interface_->GetNexeSize(pp_instance());
+  if (nexe_size > 0) {
+    float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
     HistogramTimeSmall(name, static_cast<int64_t>(dt));
     HistogramTimeSmall(name + "PerMB", static_cast<int64_t>(dt / size_in_MB));
   }
 }
 
 void Plugin::HistogramStartupTimeMedium(const std::string& name, float dt) {
-  if (nexe_size_ > 0) {
-    float size_in_MB = static_cast<float>(nexe_size_) / (1024.f * 1024.f);
+  int64_t nexe_size = nacl_interface_->GetNexeSize(pp_instance());
+  if (nexe_size > 0) {
+    float size_in_MB = static_cast<float>(nexe_size) / (1024.f * 1024.f);
     HistogramTimeMedium(name, static_cast<int64_t>(dt));
     HistogramTimeMedium(name + "PerMB", static_cast<int64_t>(dt / size_in_MB));
   }
@@ -723,9 +648,9 @@
   }
   size_t nexe_bytes_read = static_cast<size_t>(stat_buf.st_size);
 
-  nexe_size_ = nexe_bytes_read;
+  nacl_interface_->SetNexeSize(pp_instance(), nexe_bytes_read);
   HistogramSizeKB("NaCl.Perf.Size.Nexe",
-                  static_cast<int32_t>(nexe_size_ / 1024));
+                  static_cast<int32_t>(nexe_bytes_read / 1024));
   HistogramStartupTimeMedium(
       "NaCl.Perf.StartupTime.NexeDownload",
       static_cast<float>(nexe_downloader_.TimeSinceOpenMilliseconds()));
@@ -752,57 +677,33 @@
 }
 
 void Plugin::NexeFileDidOpenContinuation(int32_t pp_error) {
-  ErrorInfo error_info;
   bool was_successful;
 
   UNREFERENCED_PARAMETER(pp_error);
   NaClLog(4, "Entered NexeFileDidOpenContinuation\n");
   NaClLog(4, "NexeFileDidOpenContinuation: invoking"
           " LoadNaClModuleContinuationIntern\n");
-  was_successful = LoadNaClModuleContinuationIntern(&error_info);
+  was_successful = LoadNaClModuleContinuationIntern();
   if (was_successful) {
     NaClLog(4, "NexeFileDidOpenContinuation: success;"
             " setting histograms\n");
-    int64_t ready_time = NaClGetTimeOfDayMicroseconds();
-    nacl_interface_->SetReadyTime(pp_instance(), ready_time);
+    ready_time_ = NaClGetTimeOfDayMicroseconds();
+    nacl_interface_->SetReadyTime(pp_instance());
     HistogramStartupTimeSmall(
         "NaCl.Perf.StartupTime.LoadModule",
-        static_cast<float>(ready_time - load_start_) / NACL_MICROS_PER_MILLI);
+        static_cast<float>(ready_time_ - load_start_) / NACL_MICROS_PER_MILLI);
     HistogramStartupTimeMedium(
         "NaCl.Perf.StartupTime.Total",
-        static_cast<float>(ready_time - init_time_) / NACL_MICROS_PER_MILLI);
+        static_cast<float>(ready_time_ - init_time_) / NACL_MICROS_PER_MILLI);
 
-    ReportLoadSuccess(nexe_size_, nexe_size_);
+    int64_t nexe_size = nacl_interface_->GetNexeSize(pp_instance());
+    ReportLoadSuccess(nexe_size, nexe_size);
   } else {
     NaClLog(4, "NexeFileDidOpenContinuation: failed.");
-    ReportLoadError(error_info);
   }
   NaClLog(4, "Leaving NexeFileDidOpenContinuation\n");
 }
 
-static void LogLineToConsole(Plugin* plugin, const nacl::string& one_line) {
-  PLUGIN_PRINTF(("LogLineToConsole: %s\n",
-                 one_line.c_str()));
-  plugin->nacl_interface()->LogToConsole(plugin->pp_instance(),
-                                         one_line.c_str());
-}
-
-void Plugin::CopyCrashLogToJsConsole() {
-  nacl::string fatal_msg(main_service_runtime()->GetCrashLogOutput());
-  size_t ix_start = 0;
-  size_t ix_end;
-
-  PLUGIN_PRINTF(("Plugin::CopyCrashLogToJsConsole: got %" NACL_PRIuS " bytes\n",
-                 fatal_msg.size()));
-  while (nacl::string::npos != (ix_end = fatal_msg.find('\n', ix_start))) {
-    LogLineToConsole(this, fatal_msg.substr(ix_start, ix_end - ix_start));
-    ix_start = ix_end + 1;
-  }
-  if (ix_start != fatal_msg.size()) {
-    LogLineToConsole(this, fatal_msg.substr(ix_start));
-  }
-}
-
 void Plugin::NexeDidCrash(int32_t pp_error) {
   PLUGIN_PRINTF(("Plugin::NexeDidCrash (pp_error=%" NACL_PRId32 ")\n",
                  pp_error));
@@ -810,44 +711,9 @@
     PLUGIN_PRINTF(("Plugin::NexeDidCrash: CallOnMainThread callback with"
                    " non-PP_OK arg -- SHOULD NOT HAPPEN\n"));
   }
-  PLUGIN_PRINTF(("Plugin::NexeDidCrash: crash event!\n"));
-  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()));
-  }
-  // If the crash occurs during load, we just want to report an error
-  // that fits into our load progress event grammar.  If the crash
-  // occurs after loaded/loadend, then we use ReportDeadNexe to send a
-  // "crash" event.
-  if (nacl_interface_->GetNexeErrorReported(pp_instance())) {
-    PLUGIN_PRINTF(("Plugin::NexeDidCrash: error already reported;"
-                   " suppressing\n"));
-  } else {
-    if (nacl_interface_->GetNaClReadyState(pp_instance()) ==
-        PP_NACL_READY_STATE_DONE) {
-      ReportDeadNexe();
-    } else {
-      ErrorInfo error_info;
-      // The error is not quite right.  In particular, the crash
-      // reported by this path could be due to NaCl application
-      // crashes that occur after the PPAPI proxy has started.
-      error_info.SetReport(PP_NACL_ERROR_START_PROXY_CRASH,
-                           "Nexe crashed during startup");
-      ReportLoadError(error_info);
-    }
-  }
 
-  // In all cases, try to grab the crash log.  The first error
-  // reported may have come from the start_module RPC reply indicating
-  // a validation error or something similar, which wouldn't grab the
-  // crash log.  In the event that this is called twice, the second
-  // invocation will just be a no-op, since all the crash log will
-  // have been received and we'll just get an EOF indication.
-  CopyCrashLogToJsConsole();
+  std::string crash_log = main_service_runtime()->GetCrashLogOutput();
+  nacl_interface_->NexeDidCrash(pp_instance(), crash_log.c_str());
 }
 
 void Plugin::BitcodeDidTranslate(int32_t pp_error) {
@@ -873,8 +739,7 @@
 }
 
 void Plugin::BitcodeDidTranslateContinuation(int32_t pp_error) {
-  ErrorInfo error_info;
-  bool was_successful = LoadNaClModuleContinuationIntern(&error_info);
+  bool was_successful = LoadNaClModuleContinuationIntern();
 
   NaClLog(4, "Entered BitcodeDidTranslateContinuation\n");
   UNREFERENCED_PARAMETER(pp_error);
@@ -883,16 +748,9 @@
     int64_t total;
     pnacl_coordinator_->GetCurrentProgress(&loaded, &total);
     ReportLoadSuccess(loaded, total);
-  } else {
-    ReportLoadError(error_info);
   }
 }
 
-void Plugin::ReportDeadNexe() {
-  nacl_interface_->ReportDeadNexe(
-      pp_instance(), NaClGetTimeOfDayMicroseconds());
-}
-
 void Plugin::NaClManifestBufferReady(int32_t pp_error) {
   PLUGIN_PRINTF(("Plugin::NaClManifestBufferReady (pp_error=%"
                  NACL_PRId32 ")\n", pp_error));
@@ -958,12 +816,10 @@
     }
     return;
   }
-  // SlurpFile closes the file descriptor after reading (or on error).
-  // Duplicate our file descriptor since it will be handled by the browser.
-  int dup_file_desc = DUP(info.get_desc());
   nacl::string json_buffer;
+  // SlurpFile closes the file descriptor after reading (or on error).
   file_utils::StatusCode status = file_utils::SlurpFile(
-      dup_file_desc, json_buffer, kNaClManifestMaxFileBytes);
+      info.Release().desc, json_buffer, kNaClManifestMaxFileBytes);
 
   if (status != file_utils::PLUGIN_FILE_SUCCESS) {
     switch (status) {
@@ -1372,10 +1228,7 @@
                                        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());
+  nacl_interface_->SetExitStatus(pp_instance(), exit_status);
 }
 
 
diff --git a/ppapi/native_client/src/trusted/plugin/plugin.h b/ppapi/native_client/src/trusted/plugin/plugin.h
index f3831d6..7ddff58 100644
--- a/ppapi/native_client/src/trusted/plugin/plugin.h
+++ b/ppapi/native_client/src/trusted/plugin/plugin.h
@@ -95,7 +95,7 @@
 
   // Finish hooking interfaces up, after low-level initialization is
   // complete.
-  bool LoadNaClModuleContinuationIntern(ErrorInfo* error_info);
+  bool LoadNaClModuleContinuationIntern();
 
   // Continuation for starting SRPC/JSProxy services as appropriate.
   // This is invoked as a callback when the NaCl module makes the
@@ -144,9 +144,6 @@
   // Report the error code that sel_ldr produces when starting a nexe.
   void ReportSelLdrLoadStatus(int status);
 
-  // Report nexe death after load to JS and shut down the proxy.
-  void ReportDeadNexe();
-
   // URL resolution support.
   // plugin_base_url is the URL used for resolving relative URLs used in
   // src="...".
@@ -204,7 +201,6 @@
   Manifest const* manifest() const { return manifest_.get(); }
   const pp::URLUtil_Dev* url_util() const { return url_util_; }
 
-  int exit_status() const { return exit_status_; }
   // set_exit_status may be called off the main thread.
   void set_exit_status(int exit_status);
 
@@ -332,12 +328,6 @@
                                  FileDownloader* url_downloader,
                                  pp::CompletionCallback pp_callback);
 
-  // Copy the main service runtime's most recent NaClLog output to the
-  // JavaScript console.  Valid to use only after a crash, e.g., via a
-  // detail level LOG_FATAL NaClLog entry.  If the crash was not due
-  // to a LOG_FATAL this method will do nothing.
-  void CopyCrashLogToJsConsole();
-
   // Open an app file by requesting a file descriptor from the browser. This
   // method first checks that the url is for an installed file before making the
   // request so it won't slow down non-installed file downloads.
@@ -410,7 +400,7 @@
   int64_t load_start_;
 
   int64_t init_time_;
-  size_t nexe_size_;
+  int64_t ready_time_;
 
   // Callback to receive .nexe and .dso download progress notifications.
   static void UpdateDownloadProgress(
diff --git a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
index d2b3508..48b256a 100644
--- a/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
+++ b/ppapi/native_client/src/trusted/plugin/pnacl_resources.cc
@@ -17,14 +17,6 @@
 #include "third_party/jsoncpp/source/include/json/value.h"
 
 namespace plugin {
-namespace {
-const PPB_NaCl_Private* GetNaClInterface() {
-  pp::Module *module = pp::Module::Get();
-  CHECK(module);
-  return static_cast<const PPB_NaCl_Private*>(
-      module->GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE));
-}
-}  // namespace
 
 static const char kPnaclBaseUrl[] = "chrome://pnacl-translator/";
 const char PnaclUrls::kResourceInfoUrl[] = "pnacl.json";
diff --git a/ppapi/native_client/src/trusted/plugin/utility.cc b/ppapi/native_client/src/trusted/plugin/utility.cc
index d800424..b1984ea 100644
--- a/ppapi/native_client/src/trusted/plugin/utility.cc
+++ b/ppapi/native_client/src/trusted/plugin/utility.cc
@@ -10,57 +10,39 @@
 
 #include "native_client/src/include/portability_io.h"
 #include "native_client/src/include/portability_process.h"
+#include "native_client/src/shared/platform/nacl_check.h"
+#include "ppapi/cpp/module.h"
 #include "ppapi/native_client/src/trusted/plugin/utility.h"
 
 namespace plugin {
 
 int gNaClPluginDebugPrintEnabled = -1;
-FILE* gNaClPluginLogFile = NULL;
 
 /*
  * Prints formatted message to the log.
  */
 int NaClPluginPrintLog(const char *format, ...) {
-  if (NULL == gNaClPluginLogFile) {
-    return 0;
-  }
   va_list arg;
-  int done;
-  va_start(arg, format);
-  done = vfprintf(gNaClPluginLogFile, format, arg);
-  va_end(arg);
-  fflush(gNaClPluginLogFile);
-  return done;
-}
+  int out_size;
 
-/*
- * Opens file where plugin log should be written. The file name is
- * taken from NACL_PLUGIN_LOG environment variable and process pid.
- * If environment variable doesn't exist or file can't be opened,
- * the function returns stdout.
- */
-FILE* NaClPluginLogFileEnv() {
-  char* file = getenv("NACL_PLUGIN_LOG");
-  if (NULL != file) {
-    int pid = GETPID();
-    /*
-     * 11 characters for pid, 5 for a glue string and 1 for null terminator.
-     */
-    size_t filename_length = strlen(file) + 32;
-    char* filename = new char[filename_length];
-    int ret = SNPRINTF(filename, filename_length, "%s.%d.log", file, pid);
-    if (ret <= 0 || static_cast<size_t>(ret) >= filename_length) {
-      delete[] filename;
-      return stdout;
-    }
-    FILE* log_file = fopen(filename, "w+");
-    delete[] filename;
-    if (NULL == log_file) {
-        return stdout;
-    }
-    return log_file;
+  static const int kStackBufferSize = 512;
+  char stack_buffer[kStackBufferSize];
+  va_start(arg, format);
+  out_size = vsnprintf(stack_buffer, kStackBufferSize, format, arg);
+  va_end(arg);
+  if (out_size < kStackBufferSize) {
+    GetNaClInterface()->Vlog(stack_buffer);
+  } else {
+    // Message too large for our stack buffer; we have to allocate memory
+    // instead.
+    char *buffer = static_cast<char*>(malloc(out_size + 1));
+    va_start(arg, format);
+    vsnprintf(buffer, out_size + 1, format, arg);
+    va_end(arg);
+    GetNaClInterface()->Vlog(buffer);
+    free(buffer);
   }
-  return stdout;
+  return out_size;
 }
 
 /*
@@ -114,4 +96,20 @@
   return true;
 }
 
+// We cache the NaCl interface pointer and ensure that its set early on, on the
+// main thread. This allows GetNaClInterface() to be used from non-main threads.
+static const PPB_NaCl_Private* g_nacl_interface = NULL;
+
+const PPB_NaCl_Private* GetNaClInterface() {
+  if (g_nacl_interface)
+    return g_nacl_interface;
+
+  pp::Module *module = pp::Module::Get();
+  CHECK(module);
+  CHECK(module->core()->IsMainThread());
+  g_nacl_interface = static_cast<const PPB_NaCl_Private*>(
+      module->GetBrowserInterface(PPB_NACL_PRIVATE_INTERFACE));
+  return g_nacl_interface;
+}
+
 }  // namespace plugin
diff --git a/ppapi/native_client/src/trusted/plugin/utility.h b/ppapi/native_client/src/trusted/plugin/utility.h
index 6b9b27e..758759c 100644
--- a/ppapi/native_client/src/trusted/plugin/utility.h
+++ b/ppapi/native_client/src/trusted/plugin/utility.h
@@ -13,6 +13,7 @@
 #include "native_client/src/include/portability.h"
 #include "native_client/src/shared/platform/nacl_threads.h"
 #include "native_client/src/shared/platform/nacl_time.h"
+#include "ppapi/c/private/ppb_nacl_private.h"
 
 #define SRPC_PLUGIN_DEBUG 1
 
@@ -26,18 +27,17 @@
 // TODO(sehr): add Unicode identifier support.
 bool IsValidIdentifierString(const char* strval, uint32_t* length);
 
+const PPB_NaCl_Private* GetNaClInterface();
+
 // Debugging print utility
 extern int gNaClPluginDebugPrintEnabled;
-extern FILE* gNaClPluginLogFile;
 extern int NaClPluginPrintLog(const char *format, ...);
 extern int NaClPluginDebugPrintCheckEnv();
-extern FILE* NaClPluginLogFileEnv();
 #if SRPC_PLUGIN_DEBUG
 #define INIT_PLUGIN_LOGGING() do {                                    \
     if (-1 == ::plugin::gNaClPluginDebugPrintEnabled) {               \
       ::plugin::gNaClPluginDebugPrintEnabled =                        \
           ::plugin::NaClPluginDebugPrintCheckEnv();                   \
-      ::plugin::gNaClPluginLogFile = ::plugin::NaClPluginLogFileEnv();\
     }                                                                 \
 } while (0)
 
diff --git a/ppapi/native_client/src/untrusted/irt_stub/ppapi_plugin_start.c b/ppapi/native_client/src/untrusted/irt_stub/ppapi_plugin_start.c
index ba55e5d..28a6593 100644
--- a/ppapi/native_client/src/untrusted/irt_stub/ppapi_plugin_start.c
+++ b/ppapi/native_client/src/untrusted/irt_stub/ppapi_plugin_start.c
@@ -11,7 +11,7 @@
 #include "native_client/src/include/elf32.h"
 #include "native_client/src/include/elf_auxv.h"
 #include "native_client/src/untrusted/irt/irt.h"
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"
 #include "ppapi/native_client/src/untrusted/irt_stub/thread_creator.h"
 
diff --git a/ppapi/native_client/src/untrusted/irt_stub/ppapi_start.h b/ppapi/native_client/src/untrusted/irt_stub/ppapi_start.h
index a169451..65babfd 100644
--- a/ppapi/native_client/src/untrusted/irt_stub/ppapi_start.h
+++ b/ppapi/native_client/src/untrusted/irt_stub/ppapi_start.h
@@ -7,7 +7,7 @@
 #ifndef NATIVE_CLIENT_SRC_UNTRUSTED_IRT_STUB_PPAPI_START_H_
 #define NATIVE_CLIENT_SRC_UNTRUSTED_IRT_STUB_PPAPI_START_H_ 1
 
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 
 /*
  * Start PPAPI using the given set of callbacks to invoke the application code.
diff --git a/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h b/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
index 6e7d5a3..ac4258f 100644
--- a/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
+++ b/ppapi/native_client/src/untrusted/irt_stub/thread_creator.h
@@ -8,7 +8,7 @@
 #define NATIVE_CLIENT_SRC_UNTRUSTED_IRT_STUB_THREAD_CREATOR_H_ 1
 
 #include "native_client/src/untrusted/irt/irt.h"
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 
 void __nacl_register_thread_creator(const struct nacl_irt_ppapihook *hooks);
 
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.c
index eeca8cf..4c9df4a 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.c
@@ -7,9 +7,9 @@
 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h"
 
 #include "native_client/src/untrusted/irt/irt.h"
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h"
-#include "ppapi/proxy/plugin_main_irt.h"
+#include "ppapi/nacl_irt/plugin_main.h"
 
 /*
  * Defines a version of the version irt_ppapi_start and of the irt_ppapihook
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h b/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h
index 5654dce..34c23a5 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h
@@ -7,7 +7,7 @@
 #ifndef PPAPI_NATIVE_CLIENT_SRC_UNTRUSTED_PNACL_IRT_SHIM_IRT_SHIM_PPAPI_H_
 #define PPAPI_NATIVE_CLIENT_SRC_UNTRUSTED_PNACL_IRT_SHIM_IRT_SHIM_PPAPI_H_
 
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 
 #ifdef PNACL_SHIM_AOT
 
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
index ba115dd..1dae487 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp
@@ -17,6 +17,7 @@
         'out_pnacl_newlib_x86_32': '>(tc_lib_dir_pnacl_translate)/lib-x86-32/>(nlib_target)',
         'out_pnacl_newlib_x86_64': '>(tc_lib_dir_pnacl_translate)/lib-x86-64/>(nlib_target)',
         'out_pnacl_newlib_mips': '>(tc_lib_dir_pnacl_translate)/lib-mips32/>(nlib_target)',
+        'out_pnacl_newlib_x86_32_nonsfi': '>(tc_lib_dir_pnacl_translate)/lib-x86-32-nonsfi/>(nlib_target)',
         'build_glibc': 0,
         'build_newlib': 0,
         'build_pnacl_newlib': 1,
@@ -25,6 +26,7 @@
         'enable_x86_64': 1,
         'enable_arm': 1,
         'enable_mips': 1,
+        'enable_x86_32_nonsfi': 1,
         'sources': [
           'irt_shim_ppapi.c',
           'pnacl_shim.c',
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 433cd00..8755c1e 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
@@ -2064,10 +2064,6 @@
 
 /* End wrapper methods for PPB_Font_Dev_0_6 */
 
-/* Not generating wrapper methods for PPB_Graphics2D_Dev_0_1 */
-
-/* Not generating wrapper methods for PPB_Graphics2D_Dev_0_2 */
-
 /* Begin wrapper methods for PPB_IMEInputEvent_Dev_0_1 */
 
 static PP_Bool Pnacl_M16_PPB_IMEInputEvent_Dev_IsIMEInputEvent(PP_Resource resource) {
@@ -3096,7 +3092,7 @@
   iface->LaunchSelLdr(instance, alleged_url, uses_irt, uses_ppapi, uses_nonsfi_mode, enable_ppapi_dev, enable_dyncode_syscalls, enable_exception_handling, enable_crash_throttling, imc_handle, error_message, *callback);
 }
 
-static PP_ExternalPluginResult Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy(PP_Instance instance) {
+static PP_Bool Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy(PP_Instance instance) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
   return iface->StartPpapiProxy(instance);
 }
@@ -3156,11 +3152,6 @@
   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);
-}
-
 static void Pnacl_M25_PPB_NaCl_Private_ReportLoadSuccess(PP_Instance instance, const char* url, uint64_t loaded_bytes, uint64_t total_bytes) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
   iface->ReportLoadSuccess(instance, url, loaded_bytes, total_bytes);
@@ -3176,9 +3167,9 @@
   iface->ReportLoadAbort(instance);
 }
 
-static void Pnacl_M25_PPB_NaCl_Private_ReportDeadNexe(PP_Instance instance, int64_t crash_time) {
+static void Pnacl_M25_PPB_NaCl_Private_NexeDidCrash(PP_Instance instance, const char* crash_log) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
-  iface->ReportDeadNexe(instance, crash_time);
+  iface->NexeDidCrash(instance, crash_log);
 }
 
 static void Pnacl_M25_PPB_NaCl_Private_InstanceCreated(PP_Instance instance) {
@@ -3211,11 +3202,6 @@
   iface->LogToConsole(instance, message);
 }
 
-static PP_Bool Pnacl_M25_PPB_NaCl_Private_GetNexeErrorReported(PP_Instance instance) {
-  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
-  return iface->GetNexeErrorReported(instance);
-}
-
 static PP_NaClReadyState Pnacl_M25_PPB_NaCl_Private_GetNaClReadyState(PP_Instance instance) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
   return iface->GetNaClReadyState(instance);
@@ -3236,14 +3222,39 @@
   iface->SetIsInstalled(instance, is_installed);
 }
 
-static int64_t Pnacl_M25_PPB_NaCl_Private_GetReadyTime(PP_Instance instance) {
+static void Pnacl_M25_PPB_NaCl_Private_SetReadyTime(PP_Instance instance) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
-  return iface->GetReadyTime(instance);
+  iface->SetReadyTime(instance);
 }
 
-static void Pnacl_M25_PPB_NaCl_Private_SetReadyTime(PP_Instance instance, int64_t ready_time) {
+static int32_t Pnacl_M25_PPB_NaCl_Private_GetExitStatus(PP_Instance instance) {
   const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
-  iface->SetReadyTime(instance, ready_time);
+  return iface->GetExitStatus(instance);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_SetExitStatus(PP_Instance instance, int32_t exit_status) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->SetExitStatus(instance, exit_status);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_Vlog(const char* message) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->Vlog(message);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_SetInitTime(PP_Instance instance) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->SetInitTime(instance);
+}
+
+static int64_t Pnacl_M25_PPB_NaCl_Private_GetNexeSize(PP_Instance instance) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  return iface->GetNexeSize(instance);
+}
+
+static void Pnacl_M25_PPB_NaCl_Private_SetNexeSize(PP_Instance instance, int64_t nexe_size) {
+  const struct PPB_NaCl_Private_1_0 *iface = Pnacl_WrapperInfo_PPB_NaCl_Private_1_0.real_iface;
+  iface->SetNexeSize(instance, nexe_size);
 }
 
 /* End wrapper methods for PPB_NaCl_Private_1_0 */
@@ -4814,10 +4825,6 @@
     .PixelOffsetForCharacter = (int32_t (*)(PP_Resource font, const struct PP_TextRun_Dev* text, uint32_t char_offset))&Pnacl_M14_PPB_Font_Dev_PixelOffsetForCharacter
 };
 
-/* Not generating wrapper interface for PPB_Graphics2D_Dev_0_1 */
-
-/* Not generating wrapper interface for PPB_Graphics2D_Dev_0_2 */
-
 static const struct PPB_IMEInputEvent_Dev_0_1 Pnacl_Wrappers_PPB_IMEInputEvent_Dev_0_1 = {
     .IsIMEInputEvent = (PP_Bool (*)(PP_Resource resource))&Pnacl_M16_PPB_IMEInputEvent_Dev_IsIMEInputEvent,
     .GetText = (struct PP_Var (*)(PP_Resource ime_event))&Pnacl_M16_PPB_IMEInputEvent_Dev_GetText,
@@ -5125,7 +5132,7 @@
 
 static const struct PPB_NaCl_Private_1_0 Pnacl_Wrappers_PPB_NaCl_Private_1_0 = {
     .LaunchSelLdr = (void (*)(PP_Instance instance, const char* alleged_url, PP_Bool uses_irt, PP_Bool uses_ppapi, PP_Bool uses_nonsfi_mode, PP_Bool enable_ppapi_dev, PP_Bool enable_dyncode_syscalls, PP_Bool enable_exception_handling, PP_Bool enable_crash_throttling, void* imc_handle, struct PP_Var* error_message, struct PP_CompletionCallback callback))&Pnacl_M25_PPB_NaCl_Private_LaunchSelLdr,
-    .StartPpapiProxy = (PP_ExternalPluginResult (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy,
+    .StartPpapiProxy = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_StartPpapiProxy,
     .UrandomFD = (int32_t (*)(void))&Pnacl_M25_PPB_NaCl_Private_UrandomFD,
     .Are3DInterfacesDisabled = (PP_Bool (*)(void))&Pnacl_M25_PPB_NaCl_Private_Are3DInterfacesDisabled,
     .BrokerDuplicateHandle = (int32_t (*)(PP_FileHandle source_handle, uint32_t process_id, PP_FileHandle* target_handle, uint32_t desired_access, uint32_t options))&Pnacl_M25_PPB_NaCl_Private_BrokerDuplicateHandle,
@@ -5137,24 +5144,27 @@
     .ReportTranslationFinished = (void (*)(PP_Instance instance, PP_Bool success))&Pnacl_M25_PPB_NaCl_Private_ReportTranslationFinished,
     .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, const char* 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,
     .ReportLoadSuccess = (void (*)(PP_Instance instance, const char* url, uint64_t loaded_bytes, uint64_t total_bytes))&Pnacl_M25_PPB_NaCl_Private_ReportLoadSuccess,
     .ReportLoadError = (void (*)(PP_Instance instance, PP_NaClError error, const char* error_message, const char* console_message))&Pnacl_M25_PPB_NaCl_Private_ReportLoadError,
     .ReportLoadAbort = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_ReportLoadAbort,
-    .ReportDeadNexe = (void (*)(PP_Instance instance, int64_t crash_time))&Pnacl_M25_PPB_NaCl_Private_ReportDeadNexe,
+    .NexeDidCrash = (void (*)(PP_Instance instance, const char* crash_log))&Pnacl_M25_PPB_NaCl_Private_NexeDidCrash,
     .InstanceCreated = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_InstanceCreated,
     .InstanceDestroyed = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_InstanceDestroyed,
     .NaClDebugEnabledForURL = (PP_Bool (*)(const char* alleged_nmf_url))&Pnacl_M25_PPB_NaCl_Private_NaClDebugEnabledForURL,
     .GetSandboxArch = (const char* (*)(void))&Pnacl_M25_PPB_NaCl_Private_GetSandboxArch,
     .GetUrlScheme = (PP_UrlSchemeType (*)(struct PP_Var url))&Pnacl_M25_PPB_NaCl_Private_GetUrlScheme,
     .LogToConsole = (void (*)(PP_Instance instance, const char* message))&Pnacl_M25_PPB_NaCl_Private_LogToConsole,
-    .GetNexeErrorReported = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetNexeErrorReported,
     .GetNaClReadyState = (PP_NaClReadyState (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetNaClReadyState,
     .SetNaClReadyState = (void (*)(PP_Instance instance, PP_NaClReadyState ready_state))&Pnacl_M25_PPB_NaCl_Private_SetNaClReadyState,
     .GetIsInstalled = (PP_Bool (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetIsInstalled,
     .SetIsInstalled = (void (*)(PP_Instance instance, PP_Bool is_installed))&Pnacl_M25_PPB_NaCl_Private_SetIsInstalled,
-    .GetReadyTime = (int64_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetReadyTime,
-    .SetReadyTime = (void (*)(PP_Instance instance, int64_t ready_time))&Pnacl_M25_PPB_NaCl_Private_SetReadyTime
+    .SetReadyTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetReadyTime,
+    .GetExitStatus = (int32_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetExitStatus,
+    .SetExitStatus = (void (*)(PP_Instance instance, int32_t exit_status))&Pnacl_M25_PPB_NaCl_Private_SetExitStatus,
+    .Vlog = (void (*)(const char* message))&Pnacl_M25_PPB_NaCl_Private_Vlog,
+    .SetInitTime = (void (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_SetInitTime,
+    .GetNexeSize = (int64_t (*)(PP_Instance instance))&Pnacl_M25_PPB_NaCl_Private_GetNexeSize,
+    .SetNexeSize = (void (*)(PP_Instance instance, int64_t nexe_size))&Pnacl_M25_PPB_NaCl_Private_SetNexeSize
 };
 
 static const struct PPB_NetAddress_Private_0_1 Pnacl_Wrappers_PPB_NetAddress_Private_0_1 = {
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.c
index 76952af..e6984ed 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/shim_ppapi.c
@@ -8,7 +8,7 @@
 
 #include <string.h>
 #include "native_client/src/untrusted/irt/irt.h"
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 #include "ppapi/native_client/src/shared/ppapi_proxy/ppruntime.h"
 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/irt_shim_ppapi.h"
 #include "ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.h"
diff --git a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
index 0657e58..0cd6ed8 100644
--- a/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
+++ b/ppapi/native_client/src/untrusted/pnacl_support_extension/pnacl_support_extension.gyp
@@ -29,7 +29,7 @@
             'inputs': [
               'pnacl_component_crx_gen.py',
               # A stamp file representing the contents of pnacl_translator.
-              '<(DEPTH)/native_client/toolchain/pnacl_translator/SOURCE_SHA1',
+              '<(DEPTH)/native_client/toolchain/<(OS)_x86/pnacl_translator/SOURCE_SHA1',
               '<(DEPTH)/native_client/pnacl/driver/pnacl_info_template.json',
               '<(DEPTH)/native_client/TOOL_REVISIONS',
             ],
diff --git a/ppapi/ppapi_nacl.gyp b/ppapi/ppapi_nacl.gyp
index 20d40c3..3f31f57 100644
--- a/ppapi/ppapi_nacl.gyp
+++ b/ppapi/ppapi_nacl.gyp
@@ -176,8 +176,8 @@
         # and in-browser translation is tested elsewhere.
         # NOTE: native_client/build/untrusted.gypi dictates that
         # PNaCl only generate x86-32 and x86-64 on x86 platforms,
-        # or ARM on ARM platforms, not all versions always.
-        # TODO(petarj): Enable tests for MIPS.
+        # ARM on ARM platforms, or MIPS on MIPS platforms, not all
+        # versions always.
         # The same goes for the PNaCl shims. So, we have two variations here.
         ['disable_pnacl==0 and (target_arch=="ia32" or target_arch=="x64")', {
           'variables': {
@@ -188,7 +188,7 @@
           'dependencies': [
             '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_aot',
           ],
-         'actions': [
+          'actions': [
             {
               'action_name': 'Generate PNACL NEWLIB NMF',
               # NOTE: create_nmf must be first, it is the script python executes
@@ -207,6 +207,13 @@
             },
           ],
         }],
+        ['disable_pnacl==0 and target_arch=="ia32" and OS=="linux"', {
+          # In addition to above configuration, build x86-32-nonsfi .nexe file
+          # by translating from .pexe binary, for non-SFI mode PPAPI testing.
+          'variables': {
+            'enable_x86_32_nonsfi': 1,
+          },
+        }],
         ['disable_pnacl==0 and target_arch=="arm"', {
           'variables': {
             'build_pnacl_newlib': 1,
@@ -231,6 +238,28 @@
             },
           ],
         }],
+        ['disable_pnacl==0 and target_arch=="mipsel"', {
+          'variables': {
+            'build_pnacl_newlib': 1,
+            'nmf_pnacl%': '<(PRODUCT_DIR)/>(nexe_target)_pnacl.nmf',
+          },
+          # Shim is a dependency for the nexe because we pre-translate.
+          'dependencies': [
+            '<(DEPTH)/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_irt_shim.gyp:pnacl_irt_shim_aot',
+          ],
+          'actions': [
+            {
+              'action_name': 'Generate PNACL NEWLIB NMF',
+              'inputs': ['>(create_nmf)', '>(out_pnacl_newlib_mips_nexe)'],
+              'outputs': ['>(nmf_pnacl)'],
+              'action': [
+                'python',
+                '>@(_inputs)',
+                '--output=>(nmf_pnacl)',
+              ],
+            },
+          ],
+        }],
       ],
     },
   ],
diff --git a/ppapi/ppapi_nacl_test_common.gypi b/ppapi/ppapi_nacl_test_common.gypi
index e495914..b5c6055 100644
--- a/ppapi/ppapi_nacl_test_common.gypi
+++ b/ppapi/ppapi_nacl_test_common.gypi
@@ -25,6 +25,7 @@
           'out_newlib32%': '>(nacl_newlib_out_dir)/>(nexe_target)_newlib_x86_32.nexe',
           'out_newlib64%': '>(nacl_newlib_out_dir)/>(nexe_target)_newlib_x86_64.nexe',
           'out_newlib_arm%': '>(nacl_newlib_out_dir)/>(nexe_target)_newlib_arm.nexe',
+          'out_newlib_mips%': '>(nacl_newlib_out_dir)/>(nexe_target)_newlib_mips32.nexe',
           'nmf_newlib%': '>(nacl_newlib_out_dir)/>(nexe_target).nmf',
           'out_glibc32%': '>(nacl_glibc_out_dir)/>(nexe_target)_glibc_x86_32.nexe',
           'out_glibc64%': '>(nacl_glibc_out_dir)/>(nexe_target)_glibc_x86_64.nexe',
@@ -51,7 +52,7 @@
           },
         ],
       }],
-      ['test_files!=[] and "<(target_arch)"!="arm" and disable_glibc==0 and build_glibc==1', {
+      ['test_files!=[] and "<(target_arch)"!="arm" and "<(target_arch)"!="mipsel" and disable_glibc==0 and build_glibc==1', {
         'copies': [
           {
             'destination': '>(nacl_glibc_out_dir)',
@@ -78,6 +79,7 @@
           'enable_x86_64%': 0,
           'enable_x86_32%': 0,
           'enable_arm%': 0,
+          'enable_mips%': 0,
           'include_dirs': [
             '<(DEPTH)',
           ],
@@ -118,11 +120,15 @@
                     'inputs': ['>(out_newlib_arm)'],
                     'action': ['>(out_newlib_arm)'],
                   }],
+                  ['enable_mips==1', {
+                    'inputs': ['>(out_newlib_mips)'],
+                    'action': ['>(out_newlib_mips)'],
+                  }],
                 ],
               },
             ],
           }],
-          ['"<(target_arch)"!="arm" and generate_nmf==1 and disable_glibc==0 and build_glibc==1', {
+          ['"<(target_arch)"!="arm" and "<(target_arch)"!="mipsel" and generate_nmf==1 and disable_glibc==0 and build_glibc==1', {
             'variables': {
               # NOTE: Use /lib, not /lib64 here; it is a symbolic link which
               # doesn't work on Windows.
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi
index 49e2232..11eb697 100644
--- a/ppapi/ppapi_proxy.gypi
+++ b/ppapi/ppapi_proxy.gypi
@@ -244,9 +244,15 @@
         'target_conditions': [
           ['>(nacl_untrusted_build)==1', {
             'sources': [
-              'proxy/irt_ppapi.c',
-              'proxy/plugin_main_irt.cc',
-              'proxy/plugin_main_irt.h',
+              'nacl_irt/irt_ppapi.cc',
+              'nacl_irt/irt_ppapi.h',
+              'nacl_irt/irt_start.cc',
+              'nacl_irt/plugin_main.cc',
+              'nacl_irt/plugin_main.h',
+              'nacl_irt/plugin_startup.cc',
+              'nacl_irt/plugin_startup.h',
+              'nacl_irt/ppapi_dispatcher.cc',
+              'nacl_irt/ppapi_dispatcher.h',
             ],
             'sources!': [
               'proxy/audio_input_resource.cc',
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi
index e56a191..0a35aed 100644
--- a/ppapi/ppapi_tests.gypi
+++ b/ppapi/ppapi_tests.gypi
@@ -30,6 +30,7 @@
             'tests/test_case.html.mock-http-headers',
             'tests/test_page.css',
             'tests/ppapi_nacl_tests_newlib.nmf',
+            'tests/ppapi_nacl_tests_pnacl_nonsfi.nmf',
           ],
         },
         {
diff --git a/ppapi/proxy/DEPS b/ppapi/proxy/DEPS
index 0c13d6b..0e60992 100644
--- a/ppapi/proxy/DEPS
+++ b/ppapi/proxy/DEPS
@@ -1,6 +1,5 @@
 include_rules = [
   "+base",
-  "+components/tracing",
   "+gpu",
   "+ipc",
   "+media/audio",
@@ -14,13 +13,4 @@
   "-ppapi/cpp",
   "+ppapi/cpp/completion_callback.h",
   "+ppapi/cpp/output_traits.h",
-
-  # The untrusted build references the NaCl integrated runtime (IRT).
-  "+native_client/src/public",
-  "+native_client/src/shared/srpc/nacl_srpc.h",
-  "+native_client/src/untrusted/irt/irt.h",
-  "+native_client/src/untrusted/irt/irt_private.h",
-  # The IRT also needs to know the sysconf enums.
-  "+native_client/src/trusted/service_runtime/include/sys/unistd.h",
 ]
-
diff --git a/ppapi/proxy/plugin_main_irt.cc b/ppapi/proxy/plugin_main_irt.cc
deleted file mode 100644
index 34e7923..0000000
--- a/ppapi/proxy/plugin_main_irt.cc
+++ /dev/null
@@ -1,354 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ppapi/proxy/plugin_main_irt.h"
-
-#include <unistd.h>
-#include <map>
-#include <set>
-
-#include "build/build_config.h"
-// Need to include this before most other files because it defines
-// IPC_MESSAGE_LOG_ENABLED. We need to use it to define
-// IPC_MESSAGE_MACROS_LOG_ENABLED so ppapi_messages.h will generate the
-// ViewMsgLog et al. functions.
-
-#include "base/command_line.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/message_loop/message_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#include "components/tracing/child_trace_message_filter.h"
-#include "ipc/ipc_channel_handle.h"
-#include "ipc/ipc_logging.h"
-#include "ipc/ipc_message.h"
-#include "ppapi/c/ppp.h"
-#include "ppapi/c/ppp_instance.h"
-#include "ppapi/proxy/plugin_dispatcher.h"
-#include "ppapi/proxy/plugin_globals.h"
-#include "ppapi/proxy/plugin_message_filter.h"
-#include "ppapi/proxy/plugin_proxy_delegate.h"
-#include "ppapi/proxy/resource_reply_thread_registrar.h"
-#include "ppapi/shared_impl/ppb_audio_shared.h"
-
-#if defined(__native_client__)
-#include "base/at_exit.h"
-#include "native_client/src/public/chrome_main.h"
-#include "native_client/src/shared/srpc/nacl_srpc.h"
-#endif
-
-#if defined(IPC_MESSAGE_LOG_ENABLED)
-#include "base/containers/hash_tables.h"
-
-LogFunctionMap g_log_function_mapping;
-
-#define IPC_MESSAGE_MACROS_LOG_ENABLED
-#define IPC_LOG_TABLE_ADD_ENTRY(msg_id, logger) \
-  g_log_function_mapping[msg_id] = logger
-
-#endif
-#include "ppapi/proxy/ppapi_messages.h"
-
-using ppapi::proxy::PluginDispatcher;
-using ppapi::proxy::PluginGlobals;
-using ppapi::proxy::PluginProxyDelegate;
-using ppapi::proxy::ProxyChannel;
-using ppapi::proxy::SerializedHandle;
-
-namespace {
-
-#if defined(__native_client__)
-// In SFI mode, the FDs of IPC channels are NACL_CHROME_DESC_BASE and its
-// successor, which is set in nacl_listener.cc.
-int g_nacl_ipc_browser_fd = NACL_CHROME_DESC_BASE;
-int g_nacl_ipc_renderer_fd = NACL_CHROME_DESC_BASE + 1;
-#else
-// In non-SFI mode, the FDs of IPC channels are different from the hard coded
-// ones. These values will be set by SetIPCFileDescriptors() below.
-// At first, both are initialized to invalid FD number (-1).
-int g_nacl_ipc_browser_fd = -1;
-int g_nacl_ipc_renderer_fd = -1;
-#endif
-
-// This class manages communication between the plugin and the browser, and
-// manages the PluginDispatcher instances for communication between the plugin
-// and the renderer.
-class PpapiDispatcher : public PluginDispatcher::PluginDelegate,
-                        public PluginProxyDelegate,
-                        public IPC::Listener,
-                        public IPC::Sender {
- public:
-  explicit PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop);
-
-  // PluginDispatcher::PluginDelegate implementation.
-  virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE;
-  virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE;
-  virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
-      base::PlatformFile handle,
-      base::ProcessId peer_pid,
-      bool should_close_source) OVERRIDE;
-  virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE;
-  virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE;
-  virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE;
-
-  // PluginProxyDelegate implementation.
-  virtual IPC::Sender* GetBrowserSender() OVERRIDE;
-  virtual std::string GetUILanguage() OVERRIDE;
-  virtual void PreCacheFont(const void* logfontw) OVERRIDE;
-  virtual void SetActiveURL(const std::string& url) OVERRIDE;
-  virtual PP_Resource CreateBrowserFont(
-      ppapi::proxy::Connection connection,
-      PP_Instance instance,
-      const PP_BrowserFont_Trusted_Description& desc,
-      const ppapi::Preferences& prefs) OVERRIDE;
-
-  // IPC::Listener implementation.
-  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-  virtual void OnChannelError() OVERRIDE;
-
-  // IPC::Sender implementation
-  virtual bool Send(IPC::Message* message) OVERRIDE;
-
- private:
-  void OnMsgInitializeNaClDispatcher(const ppapi::PpapiNaClPluginArgs& args);
-  void OnPluginDispatcherMessageReceived(const IPC::Message& msg);
-
-  std::set<PP_Instance> instances_;
-  std::map<uint32, PluginDispatcher*> plugin_dispatchers_;
-  uint32 next_plugin_dispatcher_id_;
-  scoped_refptr<base::MessageLoopProxy> message_loop_;
-  base::WaitableEvent shutdown_event_;
-  scoped_ptr<IPC::SyncChannel> channel_;
-};
-
-PpapiDispatcher::PpapiDispatcher(scoped_refptr<base::MessageLoopProxy> io_loop)
-    : next_plugin_dispatcher_id_(0),
-      message_loop_(io_loop),
-      shutdown_event_(true, false) {
-  DCHECK_NE(g_nacl_ipc_browser_fd, -1)
-      << "g_nacl_ipc_browser_fd must be initialized before the plugin starts";
-  IPC::ChannelHandle channel_handle(
-      "NaCl IPC", base::FileDescriptor(g_nacl_ipc_browser_fd, false));
-
-  // Delay initializing the SyncChannel until after we add filters. This
-  // ensures that the filters won't miss any messages received by
-  // the channel.
-  channel_.reset(new IPC::SyncChannel(
-      this, GetIPCMessageLoop(), GetShutdownEvent()));
-  channel_->AddFilter(new ppapi::proxy::PluginMessageFilter(
-      NULL, PluginGlobals::Get()->resource_reply_thread_registrar()));
-  channel_->AddFilter(
-      new tracing::ChildTraceMessageFilter(message_loop_.get()));
-  channel_->Init(channel_handle, IPC::Channel::MODE_SERVER, true);
-}
-
-base::MessageLoopProxy* PpapiDispatcher::GetIPCMessageLoop() {
-  return message_loop_.get();
-}
-
-base::WaitableEvent* PpapiDispatcher::GetShutdownEvent() {
-  return &shutdown_event_;
-}
-
-IPC::PlatformFileForTransit PpapiDispatcher::ShareHandleWithRemote(
-    base::PlatformFile handle,
-    base::ProcessId peer_pid,
-    bool should_close_source) {
-  return IPC::InvalidPlatformFileForTransit();
-}
-
-std::set<PP_Instance>* PpapiDispatcher::GetGloballySeenInstanceIDSet() {
-  return &instances_;
-}
-
-uint32 PpapiDispatcher::Register(PluginDispatcher* plugin_dispatcher) {
-  if (!plugin_dispatcher ||
-      plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
-    return 0;
-  }
-
-  uint32 id = 0;
-  do {
-    // Although it is unlikely, make sure that we won't cause any trouble
-    // when the counter overflows.
-    id = next_plugin_dispatcher_id_++;
-  } while (id == 0 ||
-           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
-  plugin_dispatchers_[id] = plugin_dispatcher;
-  return id;
-}
-
-void PpapiDispatcher::Unregister(uint32 plugin_dispatcher_id) {
-  plugin_dispatchers_.erase(plugin_dispatcher_id);
-}
-
-IPC::Sender* PpapiDispatcher::GetBrowserSender() {
-  return this;
-}
-
-std::string PpapiDispatcher::GetUILanguage() {
-  NOTIMPLEMENTED();
-  return std::string();
-}
-
-void PpapiDispatcher::PreCacheFont(const void* logfontw) {
-  NOTIMPLEMENTED();
-}
-
-void PpapiDispatcher::SetActiveURL(const std::string& url) {
-  NOTIMPLEMENTED();
-}
-
-PP_Resource PpapiDispatcher::CreateBrowserFont(
-    ppapi::proxy::Connection connection,
-    PP_Instance instance,
-    const PP_BrowserFont_Trusted_Description& desc,
-    const ppapi::Preferences& prefs) {
-  NOTIMPLEMENTED();
-  return 0;
-}
-
-bool PpapiDispatcher::OnMessageReceived(const IPC::Message& msg) {
-  IPC_BEGIN_MESSAGE_MAP(PpapiDispatcher, msg)
-    IPC_MESSAGE_HANDLER(PpapiMsg_InitializeNaClDispatcher,
-                        OnMsgInitializeNaClDispatcher)
-    // All other messages are simply forwarded to a PluginDispatcher.
-    IPC_MESSAGE_UNHANDLED(OnPluginDispatcherMessageReceived(msg))
-  IPC_END_MESSAGE_MAP()
-  return true;
-}
-
-void PpapiDispatcher::OnChannelError() {
-  exit(1);
-}
-
-bool PpapiDispatcher::Send(IPC::Message* msg) {
-  return channel_->Send(msg);
-}
-
-void PpapiDispatcher::OnMsgInitializeNaClDispatcher(
-    const ppapi::PpapiNaClPluginArgs& args) {
-  static bool command_line_and_logging_initialized = false;
-  if (command_line_and_logging_initialized) {
-    LOG(FATAL) << "InitializeNaClDispatcher must be called once per plugin.";
-    return;
-  }
-
-  command_line_and_logging_initialized = true;
-  CommandLine::Init(0, NULL);
-  for (size_t i = 0; i < args.switch_names.size(); ++i) {
-    DCHECK(i < args.switch_values.size());
-    CommandLine::ForCurrentProcess()->AppendSwitchASCII(
-        args.switch_names[i], args.switch_values[i]);
-  }
-  logging::LoggingSettings settings;
-  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
-  logging::InitLogging(settings);
-
-  ppapi::proxy::PluginGlobals::Get()
-      ->set_keepalive_throttle_interval_milliseconds(
-          args.keepalive_throttle_interval_milliseconds);
-
-  // Tell the process-global GetInterface which interfaces it can return to the
-  // plugin.
-  ppapi::proxy::InterfaceList::SetProcessGlobalPermissions(
-      args.permissions);
-
-  int32_t error = ::PPP_InitializeModule(
-      0 /* module */,
-      &ppapi::proxy::PluginDispatcher::GetBrowserInterface);
-  if (error)
-    ::exit(error);
-
-  PluginDispatcher* dispatcher =
-      new PluginDispatcher(::PPP_GetInterface, args.permissions,
-                           args.off_the_record);
-  // The channel handle's true name is not revealed here.
-  DCHECK_NE(g_nacl_ipc_renderer_fd, -1)
-      << "g_nacl_ipc_renderer_fd must be initialized before the plugin starts";
-  IPC::ChannelHandle channel_handle(
-      "nacl", base::FileDescriptor(g_nacl_ipc_renderer_fd, false));
-  if (!dispatcher->InitPluginWithChannel(this, base::kNullProcessId,
-                                         channel_handle, false)) {
-    delete dispatcher;
-    return;
-  }
-  // From here, the dispatcher will manage its own lifetime according to the
-  // lifetime of the attached channel.
-}
-
-void PpapiDispatcher::OnPluginDispatcherMessageReceived(
-    const IPC::Message& msg) {
-  // The first parameter should be a plugin dispatcher ID.
-  PickleIterator iter(msg);
-  uint32 id = 0;
-  if (!msg.ReadUInt32(&iter, &id)) {
-    NOTREACHED();
-    return;
-  }
-  std::map<uint32, ppapi::proxy::PluginDispatcher*>::iterator dispatcher =
-      plugin_dispatchers_.find(id);
-  if (dispatcher != plugin_dispatchers_.end())
-    dispatcher->second->OnMessageReceived(msg);
-}
-
-}  // namespace
-
-void SetIPCFileDescriptors(int ipc_browser_fd, int ipc_renderer_fd) {
-  g_nacl_ipc_browser_fd = ipc_browser_fd;
-  g_nacl_ipc_renderer_fd = ipc_renderer_fd;
-}
-
-void PpapiPluginRegisterThreadCreator(
-    const struct PP_ThreadFunctions* thread_functions) {
-#if defined(__native_client__)
-  // TODO(hidehiko): The thread creation for the PPB_Audio is not yet
-  // implemented on non-SFI mode. Support this. Now, this function invocation
-  // is just ignored.
-
-  // Initialize all classes that need to create threads that call back into
-  // user code.
-  ppapi::PPB_Audio_Shared::SetThreadFunctions(thread_functions);
-#endif
-}
-
-int PpapiPluginMain() {
-  // For non-SFI mode, the manager is already instantiated in nacl_helper,
-  // so we do not need to instantiate it here.
-#if defined(__native_client__)
-  // Though it isn't referenced here, we must instantiate an AtExitManager.
-  base::AtExitManager exit_manager;
-#endif
-  base::MessageLoop loop;
-#if defined(IPC_MESSAGE_LOG_ENABLED)
-  IPC::Logging::set_log_function_map(&g_log_function_mapping);
-#endif
-  ppapi::proxy::PluginGlobals plugin_globals;
-  base::Thread io_thread("Chrome_NaClIOThread");
-  base::Thread::Options options;
-  options.message_loop_type = base::MessageLoop::TYPE_IO;
-  io_thread.StartWithOptions(options);
-
-#if defined(__native_client__)
-  // Currently on non-SFI mode, we don't use SRPC server on plugin.
-  // TODO(hidehiko): Make sure this SRPC is actually used on SFI-mode.
-
-  // Start up the SRPC server on another thread. Otherwise, when it blocks
-  // on an RPC, the PPAPI proxy will hang. Do this before we initialize the
-  // module and start the PPAPI proxy so that the NaCl plugin can continue
-  // loading the app.
-  static struct NaClSrpcHandlerDesc srpc_methods[] = { { NULL, NULL } };
-  if (!NaClSrpcAcceptClientOnThread(srpc_methods)) {
-    return 1;
-  }
-#endif
-
-  PpapiDispatcher ppapi_dispatcher(io_thread.message_loop_proxy());
-  plugin_globals.set_plugin_proxy_delegate(&ppapi_dispatcher);
-
-  loop.Run();
-
-  return 0;
-}
diff --git a/ppapi/proxy/plugin_main_irt.h b/ppapi/proxy/plugin_main_irt.h
deleted file mode 100644
index f9a24cb..0000000
--- a/ppapi/proxy/plugin_main_irt.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PPAPI_PROXY_PLUGIN_MAIN_IRT_H_
-#define PPAPI_PROXY_PLUGIN_MAIN_IRT_H_
-
-#include "ppapi/nacl_irt/irt_ppapi.h"
-#include "ppapi/proxy/ppapi_proxy_export.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// The entry point for the main thread of the PPAPI plugin process.
-PPAPI_PROXY_EXPORT int PpapiPluginMain(void);
-
-PPAPI_PROXY_EXPORT void PpapiPluginRegisterThreadCreator(
-    const struct PP_ThreadFunctions* new_funcs);
-
-// Sets the IPC channels for the browser and the renderer by the given FD
-// numbers. This will be used for non-SFI mode. Must be called before
-// PpapiPluginMain is called.
-PPAPI_PROXY_EXPORT void SetIPCFileDescriptors(
-    int browser_ipc_fd, int renderer_ipc_fd);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  // PPAPI_PROXY_PLUGIN_MAIN_IRT_H_
diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc
index 257d0d2..be0cc34 100644
--- a/ppapi/proxy/ppb_instance_proxy.cc
+++ b/ppapi/proxy/ppb_instance_proxy.cc
@@ -1275,8 +1275,6 @@
 
 void PPB_Instance_Proxy::OnHostMsgSetTextInputType(PP_Instance instance,
                                                    PP_TextInput_Type type) {
-  if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
-    return;
   EnterInstanceNoLock enter(instance);
   if (enter.succeeded())
     enter.functions()->SetTextInputType(instance, type);
@@ -1286,8 +1284,6 @@
     PP_Instance instance,
     const PP_Rect& caret,
     const PP_Rect& bounding_box) {
-  if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
-    return;
   EnterInstanceNoLock enter(instance);
   if (enter.succeeded())
     enter.functions()->UpdateCaretPosition(instance, caret, bounding_box);
@@ -1295,8 +1291,6 @@
 
 void PPB_Instance_Proxy::OnHostMsgCancelCompositionText(PP_Instance instance) {
   EnterInstanceNoLock enter(instance);
-  if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
-    return;
   if (enter.succeeded())
     enter.functions()->CancelCompositionText(instance);
 }
@@ -1306,8 +1300,6 @@
     const std::string& text,
     uint32_t caret,
     uint32_t anchor) {
-  if (!dispatcher()->permissions().HasPermission(PERMISSION_DEV))
-    return;
   EnterInstanceNoLock enter(instance);
   if (enter.succeeded()) {
     enter.functions()->UpdateSurroundingText(instance, text.c_str(), caret,
diff --git a/ppapi/shared_impl/ppb_audio_shared.h b/ppapi/shared_impl/ppb_audio_shared.h
index b503c53..6ba8cac 100644
--- a/ppapi/shared_impl/ppb_audio_shared.h
+++ b/ppapi/shared_impl/ppb_audio_shared.h
@@ -16,7 +16,7 @@
 #include "ppapi/thunk/ppb_audio_api.h"
 
 #if defined(OS_NACL)
-#include "ppapi/nacl_irt/irt_ppapi.h"
+#include "ppapi/nacl_irt/public/irt_ppapi.h"
 #endif
 
 namespace ppapi {
diff --git a/ppapi/tests/ppapi_nacl_tests_newlib.nmf b/ppapi/tests/ppapi_nacl_tests_newlib.nmf
index f0bb249..ffeb778 100644
--- a/ppapi/tests/ppapi_nacl_tests_newlib.nmf
+++ b/ppapi/tests/ppapi_nacl_tests_newlib.nmf
@@ -2,6 +2,7 @@
   "program": {
     "x86-64": {"url": "ppapi_nacl_tests_newlib_x64.nexe"},
     "x86-32": {"url": "ppapi_nacl_tests_newlib_x32.nexe"},
-    "arm": {"url": "ppapi_nacl_tests_newlib_arm.nexe"}
+    "arm": {"url": "ppapi_nacl_tests_newlib_arm.nexe"},
+    "mips32": {"url": "ppapi_nacl_tests_newlib_mips32.nexe"}
   }
 }
diff --git a/ppapi/tests/ppapi_nacl_tests_pnacl_nonsfi.nmf b/ppapi/tests/ppapi_nacl_tests_pnacl_nonsfi.nmf
new file mode 100644
index 0000000..243a2b4
--- /dev/null
+++ b/ppapi/tests/ppapi_nacl_tests_pnacl_nonsfi.nmf
@@ -0,0 +1,5 @@
+{
+  "program": {
+    "x86-32-nonsfi": {"url": "ppapi_nacl_tests_pnacl_newlib_x32_nonsfi.nexe"}
+  }
+}
diff --git a/ppapi/tests/test_case.html b/ppapi/tests/test_case.html
index 12053bc..987c102 100644
--- a/ppapi/tests/test_case.html
+++ b/ppapi/tests/test_case.html
@@ -244,6 +244,11 @@
     obj.setAttribute("src", "ppapi_nacl_tests_pnacl.nmf");
     obj.setAttribute("type", "application/x-nacl");
     obj.setAttribute("mode", mode);
+  } else if (mode == "nacl_pnacl_nonsfi") {
+    obj = document.createElement("EMBED");
+    obj.setAttribute("src", "ppapi_nacl_tests_pnacl_nonsfi.nmf");
+    obj.setAttribute("type", "application/x-nacl");
+    obj.setAttribute("mode", mode);
   } else {
     var mimeType = "application/x-ppapi-tests";
     if (mimeType in navigator.mimeTypes) {
diff --git a/ppapi/tests/test_media_stream_video_track.cc b/ppapi/tests/test_media_stream_video_track.cc
index 10f7f97..b4f0186 100644
--- a/ppapi/tests/test_media_stream_video_track.cc
+++ b/ppapi/tests/test_media_stream_video_track.cc
@@ -98,7 +98,8 @@
     ASSERT_EQ(PP_OK, cc.result());
     pp::VideoFrame frame = cc.output();
     ASSERT_FALSE(frame.is_null());
-    ASSERT_EQ(frame.GetFormat(), PP_VIDEOFRAME_FORMAT_YV12);
+    ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
+                frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
 
     pp::Size size;
     ASSERT_TRUE(frame.GetSize(&size));
@@ -164,7 +165,13 @@
       ASSERT_EQ(PP_OK, cc2.result());
       pp::VideoFrame frame = cc2.output();
       ASSERT_FALSE(frame.is_null());
-      ASSERT_EQ(frame.GetFormat(), formats[i].expected_format);
+      if (formats[i].format != PP_VIDEOFRAME_FORMAT_UNKNOWN) {
+        ASSERT_EQ(frame.GetFormat(), formats[i].expected_format);
+      } else {
+        // Both YV12 and I420 are acceptable as default YUV formats.
+        ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
+                    frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
+      }
 
       pp::Size size;
       ASSERT_TRUE(frame.GetSize(&size));
@@ -206,7 +213,8 @@
       ASSERT_EQ(PP_OK, cc2.result());
       pp::VideoFrame frame = cc2.output();
       ASSERT_FALSE(frame.is_null());
-      ASSERT_EQ(frame.GetFormat(), PP_VIDEOFRAME_FORMAT_YV12);
+      ASSERT_TRUE(frame.GetFormat() == PP_VIDEOFRAME_FORMAT_YV12 ||
+                  frame.GetFormat() == PP_VIDEOFRAME_FORMAT_I420);
 
       pp::Size size;
       ASSERT_TRUE(frame.GetSize(&size));