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

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: Edits 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 if f.returnType == "MojoResult":
92 default = "MOJO_RESULT_INVALID_ARGUMENT"
93 elif f.returnType == "MojoTimeTicks":
94 default = "0"
95 else:
96 raise Exception("Unhandled return type: " + f.returnType)
97 code << "%s result = %s;" % (f.returnType, default);
98
99 # Message ID
100 code << "params[0] = %d;" % f.uid
101 # Parameter pointers
102 castTemplate = "params[%d] = reinterpret_cast<uint32_t>(%s);"
103 for p in f.params:
104 ptr = p.name
105 if p.isPassedByValue():
106 ptr = "&" + ptr
107 code << castTemplate % (p.uid + 1, ptr)
108 # Return value pointer
109 code << castTemplate % (numParams - 1, "&result")
110
111 code << "DoMojoCall(params, sizeof(params));";
112 code << "return result;"
113
114 code << "}"
115 code << ""
116
117 body = code.getValue()
118
119
120 text = template.substitute(
121 script_name=os.path.basename(__file__),
122 body=body)
123
124 print >>out, text
125
126 def paramPtr(param):
127 ptr = param.paramType
128 if param.isPassedByValue():
129 ptr += " volatile*"
130 return ptr
131
132 def generateMojoSyscall(functions, out):
133 template = loadTemplate("mojo_syscall.cc.template")
134
135 code = CodeWriter()
136 code.pushMargin()
137
138 for f in functions:
139 code << "case %d:" % f.uid
140
141 code.pushMargin()
142
143 code << "{"
144
145 with Indent(code):
146 numParams = len(f.params) + 2
147 code << "if (numParams != %d) {" % numParams
148 with Indent(code):
149 code << "return -1;"
150 code << "}"
151
152 def scalarNull(param):
153 code << "%s_ptr = NULL;" % (param.name)
154 if param.isInput:
155 if param.isScalar():
156 # TODO can we alway zero scalar values?
157 code << "%s = 0;" % (param.name)
158
159 def scalarFinalize(param, src):
160 if param.isOutput:
161 # For outputs, we need to retain the pointer for later.
162 code << "%s_ptr = reinterpret_cast<%s>(%s);" % (param.name, paramPtr(p aram), src)
163 if param.isInput:
164 code << "// In/Out"
165 code << "%s = *%s_ptr;" % (param.name, param.name)
166 else:
167 # For pure inputs, no need to retain the pointer
168 code << "%s = *reinterpret_cast<%s>(%s);" % (param.name, paramPtr(para m), src)
169
170 def convertParam(param):
171 if param.isScalar():
172 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], size of(%s));" % (param.uid + 1, param.name)
173 elif param.isArray:
174 if param.baseType == "void":
175 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], %s );" % (param.uid + 1, param.size)
176 else:
177 code << "uintptr_t temp = NaClUserToSysAddrArray(nap, params[%d], %s , sizeof(*%s));" % (param.uid + 1, param.size, param.name)
178 else:
179 code << "uintptr_t temp = NaClUserToSysAddrRange(nap, params[%d], size of(*%s));" % (param.uid + 1, param.name)
180
181 code << "if (temp == kNaClBadAddress) {"
182 with Indent(code):
183 code << "return -1;"
184 code << "}"
185 if param.isScalar():
186 scalarFinalize(param, 'temp')
187 else:
188 code << "%s = reinterpret_cast<%s>(%s);" % (param.name, param.paramTyp e, 'temp')
189
190 def convertPtr(param):
191 if param.isScalar():
192 if param.isOutput:
193 code << "%s %s_ptr;" % (paramPtr(param), param.name)
194 code << "%s %s;" % (param.baseType, param.name)
195 else:
196 code << "%s %s;" % (param.paramType, param.name)
197
198 code << "if (params[%d] == 0) {" % (param.uid + 1)
199 with Indent(code):
200 if param.isOptional:
201 if param.isScalar():
202 scalarNull(param)
203 else:
204 code << "%s = NULL;" % (param.name)
205 else:
206 code << "return -1;"
207 code << "} else {"
208 with Indent(code):
209 convertParam(param)
210 code << "}"
211
212 # Convert and validate pointers in two passes.
213 # Arrays cannot be validated util the size parameter has been converted.
214 code << "NaClCopyTakeLock(nap);"
215 for param in f.params:
216 if not param.isArray:
217 convertPtr(param)
218 for param in f.params:
219 if param.isArray:
220 convertPtr(param)
221 convertPtr(f.resultParam)
222 code << "NaClCopyDropLock(nap);"
223 code << ""
224
225 # Call
226 getParams = []
227 for param in f.params:
228 if param.isScalar() and not param.isPassedByValue():
229 if param.isOptional:
230 getParams.append("%s_ptr ? &%s : NULL" % (param.name, param.name))
231 else:
232 getParams.append("&%s" % (param.name))
233 else:
234 getParams.append(param.name)
235
236 code << "result = %s(%s);" % (f.name, ", ".join(getParams))
237 code << ""
238
239 def copyOut(param):
240 if param.isScalar():
241 if param.isOutput:
242 if param.isOptional:
243 code << "if (%s_ptr != NULL) {" % (param.name)
244 with Indent(code):
245 code << "*%s_ptr = %s;" % (param.name, param.name)
246 code << "}"
247 else:
248 code << "*%s_ptr = %s;" % (param.name, param.name)
249
250 # Write outputs
251 code << "NaClCopyTakeLock(nap);"
252 for param in f.params:
253 copyOut(param)
254 copyOut(f.resultParam)
255 code << "NaClCopyDropLock(nap);"
256 code << ""
257
258 code << "return 0;"
259 code << "}"
260
261 code.popMargin()
262
263 body = code.getValue()
264
265 text = template.substitute(
266 script_name=os.path.basename(__file__),
267 body=body)
268
269 print >>out, text
270
271 def main():
272 outdir = os.path.dirname(os.path.dirname(__file__))
273
274 mojo = interface.makeInterface()
275 generateLibMojo(mojo.functions, open(os.path.join(outdir, "libmojo.cc"), "w"))
276 generateMojoSyscall(mojo.functions, open(os.path.join(outdir, "mojo_syscall.cc "), "w"))
277
278 if __name__ == "__main__":
279 main()
OLDNEW
« mojo/monacl.gypi ('K') | « mojo/monacl/README ('k') | mojo/monacl/gen/interface.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698