summaryrefslogtreecommitdiffstats
path: root/ppapi/native_client/src/trusted/plugin/pnacl_srpc_lib.cc
blob: 7fd33b5aa3961d5787c1993ca5badc97a09e61b1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright (c) 2011 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/trusted/plugin/pnacl_srpc_lib.h"

#include <stdarg.h>

#include "native_client/src/trusted/plugin/browser_interface.h"
#include "native_client/src/trusted/plugin/method_map.h"
#include "native_client/src/trusted/plugin/nacl_subprocess.h"

namespace plugin {

bool PnaclSrpcLib::InvokeSrpcMethod(BrowserInterface* browser_interface,
                                    const NaClSubprocess* subprocess,
                                    const nacl::string& method_name,
                                    const nacl::string& input_signature,
                                    SrpcParams* params,
                                    ...) {
  va_list vl;
  va_start(vl, params);
  bool result = VInvokeSrpcMethod(browser_interface,
                                  subprocess,
                                  method_name,
                                  input_signature,
                                  params,
                                  vl);
  va_end(vl);
  return result;
}

bool PnaclSrpcLib::VInvokeSrpcMethod(BrowserInterface* browser_interface,
                                     const NaClSubprocess* subprocess,
                                     const nacl::string& method_name,
                                     const nacl::string& input_signature,
                                     SrpcParams* params,
                                     va_list vl) {
  uintptr_t kMethodIdent;
  if (!SetupSrpcInvocation(browser_interface,
                           subprocess,
                           method_name,
                           params,
                           &kMethodIdent)) {
    return false;
  }

  // Set up inputs.
  for (size_t i = 0; i < input_signature.length(); ++i) {
    char c = input_signature[i];
    // Only handle the limited number of SRPC types used for PNaCl.
    // Add more as needed.
    switch (c) {
      default:
        PLUGIN_PRINTF(("PnaclSrpcLib::InvokeSrpcMethod unhandled type: %c\n",
                       c));
        return false;
      case NACL_SRPC_ARG_TYPE_BOOL: {
        int input = va_arg(vl, int);
        params->ins()[i]->u.bval = input;
        break;
      }
      case NACL_SRPC_ARG_TYPE_DOUBLE: {
        double input = va_arg(vl, double);
        params->ins()[i]->u.dval = input;
        break;
      }
      case NACL_SRPC_ARG_TYPE_CHAR_ARRAY: {
        // SrpcParam's destructor *should* free the dup'ed string.
        const char* orig_str = va_arg(vl, const char*);
        char* input = strdup(orig_str);
        params->ins()[i]->arrays.str = input;
        break;
      }
      case NACL_SRPC_ARG_TYPE_HANDLE: {
        NaClSrpcImcDescType input = va_arg(vl, NaClSrpcImcDescType);
        params->ins()[i]->u.hval = input;
        break;
      }
      case NACL_SRPC_ARG_TYPE_INT: {
        int32_t input = va_arg(vl, int32_t);
        params->ins()[i]->u.ival = input;
        break;
      }
      case NACL_SRPC_ARG_TYPE_LONG: {
        int64_t input = va_arg(vl, int64_t);
        params->ins()[i]->u.lval = input;
        break;
      }
    }
  }

  return subprocess->Invoke(kMethodIdent, params);
}


bool PnaclSrpcLib::SetupSrpcInvocation(BrowserInterface* browser_interface,
                                       const NaClSubprocess* subprocess,
                                       const nacl::string& method_name,
                                       SrpcParams* params,
                                       uintptr_t* kMethodIdent) {
  *kMethodIdent = browser_interface->StringToIdentifier(method_name);
  if (!(subprocess->HasMethod(*kMethodIdent))) {
    PLUGIN_PRINTF(("SetupSrpcInvocation (no %s method found)\n",
                   method_name.c_str()));
    return false;
  }
  return subprocess->InitParams(*kMethodIdent, params);
}

}  // namespace plugin