Chromium Code Reviews| Index: ppapi/nacl_irt/irt_pnacl_translator_compile.cc |
| diff --git a/ppapi/nacl_irt/irt_pnacl_translator_compile.cc b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e546098c3de817a94d1e44eacb41f216461012e9 |
| --- /dev/null |
| +++ b/ppapi/nacl_irt/irt_pnacl_translator_compile.cc |
| @@ -0,0 +1,117 @@ |
| +// Copyright 2015 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 <argz.h> |
| +#include <string.h> |
|
jvoung (off chromium)
2015/07/21 21:58:06
Could use cstring
Mark Seaborn
2015/07/21 23:32:30
To be honest, I don't actually know the difference
jvoung (off chromium)
2015/07/21 23:39:48
As is is fine =)
I think the difference is that i
|
| + |
| +#include "native_client/src/shared/platform/nacl_log.h" |
| +#include "native_client/src/shared/srpc/nacl_srpc.h" |
| +#include "native_client/src/untrusted/irt/irt_dev.h" |
| +#include "ppapi/nacl_irt/irt_interfaces.h" |
| + |
| +namespace { |
| + |
| +const int kMaxObjectFiles = 16; |
| + |
| +const struct nacl_irt_pnacl_compile_funcs* g_funcs; |
| + |
| +void StreamInitWithSplit(NaClSrpcRpc* rpc, |
| + NaClSrpcArg** in_args, |
| + NaClSrpcArg** out_args, |
| + NaClSrpcClosure* done) { |
| + int num_threads = in_args[0]->u.ival; |
| + if (num_threads < 0 || num_threads > kMaxObjectFiles) { |
| + NaClLog(LOG_FATAL, "Invalid # of threads (%d)\n", num_threads); |
| + } |
| + int fd_start = 1; |
| + int i = fd_start; |
| + int num_valid_fds = 0; |
| + int obj_fds[kMaxObjectFiles]; |
| + while (num_valid_fds < kMaxObjectFiles && in_args[i]->u.hval >= 0) { |
| + obj_fds[num_valid_fds] = in_args[i]->u.hval; |
| + ++i; |
| + ++num_valid_fds; |
| + } |
| + // Convert the null-delimited strings into an array of |
| + // null-terminated strings. |
| + char* cmd_argz = in_args[kMaxObjectFiles + fd_start]->arrays.carr; |
| + size_t cmd_argz_len = in_args[kMaxObjectFiles + fd_start]->u.count; |
| + size_t argc = argz_count(cmd_argz, cmd_argz_len); |
| + char** argv = (char**)malloc((argc + 1) * sizeof(char*)); |
| + argz_extract(cmd_argz, cmd_argz_len, argv); |
| + char* result = |
| + g_funcs->init_callback(num_threads, obj_fds, num_valid_fds, argv, argc); |
| + free(argv); |
| + if (result != NULL) { |
| + rpc->result = NACL_SRPC_RESULT_APP_ERROR; |
| + // SRPC wants to free() the string, so just strdup here so that the |
| + // init_callback implementation doesn't have to know if the string |
| + // comes from malloc or new. On error, we don't care so much |
| + // about leaking this bit of memory. |
| + out_args[0]->arrays.str = strdup(result); |
| + } else { |
| + rpc->result = NACL_SRPC_RESULT_OK; |
| + out_args[0]->arrays.str = strdup(""); |
| + } |
| + done->Run(done); |
| +} |
| + |
| +void StreamChunk(NaClSrpcRpc* rpc, |
| + NaClSrpcArg** in_args, |
| + NaClSrpcArg** out_args, |
| + NaClSrpcClosure* done) { |
| + int result = |
| + g_funcs->data_callback(in_args[0]->arrays.carr, in_args[0]->u.count); |
| + rpc->result = result == 0 ? NACL_SRPC_RESULT_OK : NACL_SRPC_RESULT_APP_ERROR; |
| + done->Run(done); |
| +} |
| + |
| +void StreamEnd(NaClSrpcRpc* rpc, |
| + NaClSrpcArg** in_args, |
| + NaClSrpcArg** out_args, |
| + NaClSrpcClosure* done) { |
| + char* result = g_funcs->end_callback(); |
| + // Fill in the deprecated return values with dummy values. |
| + out_args[0]->u.ival = 0; |
| + out_args[1]->arrays.str = strdup(""); |
| + out_args[2]->arrays.str = strdup(""); |
| + if (result != NULL) { |
| + rpc->result = NACL_SRPC_RESULT_APP_ERROR; |
| + // SRPC wants to free(), so strdup() and leak to hide this detail. |
| + out_args[3]->arrays.str = strdup(result); |
| + } else { |
| + rpc->result = NACL_SRPC_RESULT_OK; |
| + out_args[3]->arrays.str = strdup(""); |
| + } |
| + done->Run(done); |
| +} |
| + |
| +const struct NaClSrpcHandlerDesc kSrpcMethods[] = { |
| + // Protocol for streaming: |
| + // StreamInitWithSplit(num_threads, obj_fd x 16, cmdline_flags) -> error_str |
| + // StreamChunk(data) + |
| + // TODO(jvoung): remove these is_shared_lib, etc. |
| + // StreamEnd() -> (is_shared_lib, soname, dependencies, error_str) |
| + { "StreamInitWithSplit:ihhhhhhhhhhhhhhhhC:s", StreamInitWithSplit }, |
| + { "StreamChunk:C:", StreamChunk }, |
| + { "StreamEnd::isss", StreamEnd }, |
| + { NULL, NULL }, |
| +}; |
| + |
| +void ServeTranslateRequest(const struct nacl_irt_pnacl_compile_funcs* funcs) { |
| + g_funcs = funcs; |
| + if (!NaClSrpcModuleInit()) { |
| + NaClLog(LOG_FATAL, "NaClSrpcModuleInit() failed\n"); |
| + } |
| + if (!NaClSrpcAcceptClientConnection(kSrpcMethods)) { |
| + NaClLog(LOG_FATAL, "NaClSrpcAcceptClientConnection() failed\n"); |
| + } |
| +} |
| + |
| +} |
| + |
| +const struct nacl_irt_private_pnacl_translator_compile |
| + nacl_irt_private_pnacl_translator_compile = { |
| + ServeTranslateRequest |
| +}; |