Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: mojo/monacl/gen/generate_monacl_bindings.py

Issue 385983008: Mojo + NaCl prototype. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Better diff Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import os.path
7 import string
8 import sys
9
10 import interface
11
12 class CodeWriter(object):
13 def __init__(self):
14 self.lines = []
15 self.margin = ""
16 self.margin_stack = []
17
18 def __lshift__(self, line):
19 self.lines.append((self.margin + line).rstrip())
20
21 def pushMargin(self):
22 self.margin_stack.append(self.margin)
23 self.margin += " "
24
25 def popMargin(self):
26 self.margin = self.margin_stack.pop()
27
28 def getValue(self):
29 return "\n".join(self.lines).rstrip() + "\n"
30
31 class Indent(object):
32 def __init__(self, writer):
33 self.writer = writer
34
35 def __enter__(self):
36 self.writer.pushMargin()
37
38 def __exit__(self, type, value, traceback):
39 self.writer.popMargin()
40
41 def templateFile(name):
42 return os.path.join(os.path.dirname(__file__), name)
43
44 def wrap(pre, items, post):
45 complete = pre + ", ".join(items) + post
46 if len(complete) <= 80:
47 return [complete]
48 lines = [pre]
49 indent = " "
50 for i, item in enumerate(items):
51 if i < len(items) - 1:
52 lines.append(indent + item + ",")
53 else:
54 lines.append(indent + item + post)
55 return lines
56
57 def iovDecl(param):
58 if param.isPassedByValue():
59 return "{&%s, sizeof(%s)}" % (param.name, param.name)
60 elif param.isArray:
61 sp = param.getSizeParam()
62 if sp.isPassedByValue():
63 size = sp.name
64 else:
65 # TODO volatile read?
66 size = "(*%s)" % sp.name
67 if param.baseType == "void":
68 return "{(void*)%s, %s}" % (param.name, size)
69 else:
70 return "{(void*)%s, sizeof(*%s)*%s}" % (param.name, param.name, size)
71 else:
72 return "{(void*)%s, sizeof(*%s)}" % (param.name, param.name)
73
74 def loadTemplate(filename):
75 data = open(templateFile(filename)).read()
76 template = string.Template(data)
77 return template
78
79 def generateLibMojo(functions, out):
80 template = loadTemplate("libmojo.cc.template")
81
82 code = CodeWriter()
83
84 for f in functions:
85 for line in wrap("%s %s(" % (f.returnType, f.name), f.paramList(), "){"):
86 code << line
87 numParams = len(f.params) + 2
88
89 with Indent(code):
90 code << "uint32_t params[%d];" % numParams
91 code << f.returnType + " result;"
92
93 # Message ID
94 code << "params[0] = %d;" % f.uid
95 # Parameter pointers
96 castTemplate = "params[%d] = reinterpret_cast<uint32_t>(%s);"
97 for p in f.params:
98 ptr = p.name
99 if p.isPassedByValue():
100 ptr = "&" + ptr
101 code << castTemplate % (p.uid + 1, ptr)
102 # Return value pointer
103 code << castTemplate % (numParams - 1, "&result")
104
105 iovLength = 1
106 code << "NaClAbiNaClImcMsgIoVec iov[%d] = {" % iovLength
107 with Indent(code):
108 code << "{params, sizeof(params)}"
109 code << "};"
110
111 code << "NaClAbiNaClImcMsgHdr msgh = {iov, %d, NULL, 0};" % iovLength
112 code << "if (imc_sendmsg(NACL_MOJO_DESC, &msgh, 0) < 0) {"
113 with Indent(code):
114 code << "result = MOJO_RESULT_INVALID_ARGUMENT;"
115 code << "}"
116
117 code << "return result;"
118
119 code << "}"
120 code << ""
121
122 body = code.getValue()
123
124
125 text = template.substitute(
126 script_name=os.path.basename(__file__),
127 body=body)
128
129 print >>out, text
130
131 def paramPtr(param):
132 ptr = param.paramType
133 if param.isPassedByValue():
134 ptr += " volatile*"
135 return ptr
136
137 def generateMojoSyscall(functions, out):
138 template = loadTemplate("mojo_syscall.cc.template")
139
140 code = CodeWriter()
141 code.pushMargin()
142
143 for f in functions:
144 code << "case %d:" % f.uid
145
146 code.pushMargin()
147
148 code << "{"
149
150 with Indent(code):
151 numParams = len(f.params) + 2
152 code << "if (numParams != %d) {" % numParams
153 with Indent(code):
154 code << "return -1;"
155 code << "}"
156
157 def scalarNull(param):
158 code << "%s_ptr = NULL;" % (param.name)
159 if param.isInput:
160 if param.isScalar():
161 # TODO can we alway zero scalar values?
162 code << "%s = 0;" % (param.name)
163
164 def scalarFinalize(param, src):
165 if param.isOutput:
166 # For outputs, we need to retain the pointer for later.
167 code << "%s_ptr = reinterpret_cast<%s>(%s);" % (param.name, paramPtr(p aram), src)
Mark Seaborn 2014/07/21 16:31:39 Lines >80 chars (and elsewhere too)
Nick Bray (chromium) 2014/07/21 22:38:36 This file needs to be cleaned up before commit, as
168 if param.isInput:
169 code << "// In/Out"
170 code << "%s = *%s_ptr;" % (param.name, param.name)
171 else:
172 # For pure inputs, no need to retain the pointer
173 code << "%s = *reinterpret_cast<%s>(%s);" % (param.name, paramPtr(para m), src)
174
175 def convertParam(param):
176 if param.isScalar():
177 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], size of(%s));" % (param.uid + 1, param.name)
178 elif param.isArray:
179 if param.baseType == "void":
180 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], %s );" % (param.uid + 1, param.size)
181 else:
182 code << "uintptr_t temp = NaClUserToSysAddrArray(nap, params[%d], %s , sizeof(*%s));" % (param.uid + 1, param.size, param.name)
183 else:
184 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], size of(*%s));" % (param.uid + 1, param.name)
185
186 code << "if (temp == kNaClBadAddress) {"
187 with Indent(code):
188 code << "return -1;"
189 code << "}"
190 if param.isScalar():
191 scalarFinalize(param, 'temp')
192 else:
193 code << "%s = reinterpret_cast<%s>(%s);" % (param.name, param.paramTyp e, 'temp')
194
195 def convertPtr(param):
196 if param.isScalar():
197 if param.isOutput:
198 code << "%s %s_ptr;" % (paramPtr(param), param.name)
199 code << "%s %s;" % (param.baseType, param.name)
200 else:
201 code << "%s %s;" % (param.paramType, param.name)
202
203 code << "if (params[%d] == 0) {" % (param.uid + 1)
204 with Indent(code):
205 if param.isOptional:
206 if param.isScalar():
207 scalarNull(param)
208 else:
209 code << "%s = NULL;" % (param.name)
210 else:
211 code << "return -1;"
212 code << "} else {"
213 with Indent(code):
214 convertParam(param)
215 code << "}"
216
217 # Convert and validate pointers in two passes.
218 # Arrays cannot be validated util the size parameter has been converted.
219 code << "NaClCopyTakeLock(nap);"
220 for param in f.params:
221 if not param.isArray:
222 convertPtr(param)
223 for param in f.params:
224 if param.isArray:
225 convertPtr(param)
226 convertPtr(f.resultParam)
227 code << "NaClCopyDropLock(nap);"
228 code << ""
229
230 # Call
231 getParams = []
232 for param in f.params:
233 if param.isScalar() and not param.isPassedByValue():
234 if param.isOptional:
235 getParams.append("%s_ptr ? &%s : NULL" % (param.name, param.name))
236 else:
237 getParams.append("&%s" % (param.name))
238 else:
239 getParams.append(param.name)
240
241 code << "result = %s(%s);" % (f.name, ", ".join(getParams))
242 code << ""
243
244 def copyOut(param):
245 if param.isScalar():
246 if param.isOutput:
247 if param.isOptional:
248 code << "if (%s_ptr != NULL) {" % (param.name)
249 with Indent(code):
250 code << "*%s_ptr = %s;" % (param.name, param.name)
251 code << "}"
252 else:
253 code << "*%s_ptr = %s;" % (param.name, param.name)
254
255 # Write outputs
256 code << "NaClCopyTakeLock(nap);"
257 for param in f.params:
258 copyOut(param)
259 copyOut(f.resultParam)
260 code << "NaClCopyDropLock(nap);"
261 code << ""
262
263 code << "return 0;"
264 code << "}"
265
266 code.popMargin()
267
268 body = code.getValue()
269
270 text = template.substitute(
271 script_name=os.path.basename(__file__),
272 body=body)
273
274 print >>out, text
275
276 def main():
277 outdir = os.path.dirname(os.path.dirname(__file__))
278
279 mojo = interface.makeInterface()
280 generateLibMojo(mojo.functions, open(os.path.join(outdir, "libmojo.cc"), "w"))
281 generateMojoSyscall(mojo.functions, open(os.path.join(outdir, "mojo_syscall.cc "), "w"))
282
283 if __name__ == "__main__":
284 main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698