Implement MojoGetBufferInformation(), part 3.
This hooks up Core::GetBufferInformation() to all the thunks, etc.
R=smklein@chromium.org, vardhan@google.com
BUG=#501
Review URL: https://codereview.chromium.org/1778753002 .
diff --git a/mojo/nacl/sfi/nacl_bindings_generator/generate_nacl_bindings.py b/mojo/nacl/sfi/nacl_bindings_generator/generate_nacl_bindings.py
index de62359..0019826 100755
--- a/mojo/nacl/sfi/nacl_bindings_generator/generate_nacl_bindings.py
+++ b/mojo/nacl/sfi/nacl_bindings_generator/generate_nacl_bindings.py
@@ -277,6 +277,7 @@
else:
code << 'CopyOutPointer(nap, %s_value, %s_ptr);' % (name, name)
+
class ArrayImpl(ParamImpl):
def DeclareVars(self, code):
code << '%s %s;' % (self.param.param_type, self.param.name)
@@ -312,6 +313,24 @@
return self.param.name
+# We can handle extensible out structs just like we handle output arrays, except
+# that the (input buffer) size is always in bytes.
+class ExtensibleStructOutputImpl(ParamImpl):
+ def DeclareVars(self, code):
+ code << '%s %s;' % (self.param.param_type, self.param.name)
+
+ def ConvertParam(self):
+ p = self.param
+ return ('ConvertArray(nap, params[%d], %s, %s, %s, &%s)' %
+ (p.uid + 1, p.size + '_value', '1', CBool(p.is_optional), p.name))
+
+ def CallParam(self):
+ return self.param.name
+
+ def IsArray(self):
+ return True
+
+
def ImplForParam(p):
if p.IsScalar():
if p.is_output:
@@ -338,6 +357,8 @@
elif p.is_struct:
if p.is_input and not p.is_output and p.is_extensible:
return ExtensibleStructInputImpl(p)
+ if p.is_output and not p.is_input and p.is_extensible:
+ return ExtensibleStructOutputImpl(p)
if not p.is_input and p.is_output and not p.is_extensible:
return ScalarOutputImpl(p)
assert False, p.name
diff --git a/mojo/nacl/sfi/nacl_bindings_generator/interface.py b/mojo/nacl/sfi/nacl_bindings_generator/interface.py
index 0f6af62..1c97be1 100644
--- a/mojo/nacl/sfi/nacl_bindings_generator/interface.py
+++ b/mojo/nacl/sfi/nacl_bindings_generator/interface.py
@@ -9,33 +9,53 @@
def MakeInterface():
mojo = interface_dsl.Interface()
- f = mojo.Func('MojoCreateSharedBuffer', 'MojoResult')
+ # This function is not provided by the Mojo system APIs, but instead allows
+ # trusted code to provide a handle for use by untrusted code. See the
+ # implementation in mojo_syscall.cc.tmpl.
+ f = mojo.Func('_MojoGetInitialHandle', 'MojoResult')
+ f.Param('handle').Out('MojoHandle')
+
+ f = mojo.Func('MojoGetTimeTicksNow', 'MojoTimeTicks')
+
+ f = mojo.Func('MojoClose', 'MojoResult')
+ f.Param('handle').In('MojoHandle')
+
+ f = mojo.Func('MojoWait', 'MojoResult')
+ f.Param('handle').In('MojoHandle')
+ f.Param('signals').In('MojoHandleSignals')
+ f.Param('deadline').In('MojoDeadline')
+ f.Param('signals_state').OutFixedStruct('MojoHandleSignalsState').Optional()
+
+ f = mojo.Func('MojoWaitMany', 'MojoResult')
+ f.Param('handles').InArray('MojoHandle', 'num_handles')
+ f.Param('signals').InArray('MojoHandleSignals', 'num_handles')
+ f.Param('num_handles').In('uint32_t')
+ f.Param('deadline').In('MojoDeadline')
+ f.Param('result_index').Out('uint32_t').Optional()
+ p = f.Param('signals_states')
+ p.OutFixedStructArray('MojoHandleSignalsState', 'num_handles').Optional()
+
+ f = mojo.Func('MojoCreateMessagePipe', 'MojoResult')
p = f.Param('options')
- p.InExtensibleStruct('MojoCreateSharedBufferOptions').Optional()
- f.Param('num_bytes').In('uint64_t')
- f.Param('shared_buffer_handle').Out('MojoHandle')
+ p.InExtensibleStruct('MojoCreateMessagePipeOptions').Optional()
+ f.Param('message_pipe_handle0').Out('MojoHandle')
+ f.Param('message_pipe_handle1').Out('MojoHandle')
- f = mojo.Func('MojoDuplicateBufferHandle', 'MojoResult')
- f.Param('buffer_handle').In('MojoHandle')
- p = f.Param('options')
- p.InExtensibleStruct('MojoDuplicateBufferHandleOptions').Optional()
- f.Param('new_buffer_handle').Out('MojoHandle')
+ f = mojo.Func('MojoWriteMessage', 'MojoResult')
+ f.Param('message_pipe_handle').In('MojoHandle')
+ f.Param('bytes').InArray('void', 'num_bytes').Optional()
+ f.Param('num_bytes').In('uint32_t')
+ f.Param('handles').InArray('MojoHandle', 'num_handles').Optional()
+ f.Param('num_handles').In('uint32_t')
+ f.Param('flags').In('MojoWriteMessageFlags')
- f = mojo.Func('MojoMapBuffer', 'MojoResult')
- f.Param('buffer_handle').In('MojoHandle')
- f.Param('offset').In('uint64_t')
- f.Param('num_bytes').In('uint64_t')
- f.Param('buffer').Out('void*')
- f.Param('flags').In('MojoMapBufferFlags')
- # TODO(ncbray): support mmaping.
- # https://code.google.com/p/chromium/issues/detail?id=401761
- f.IsBrokenInNaCl()
-
- f = mojo.Func('MojoUnmapBuffer', 'MojoResult')
- f.Param('buffer').In('void*')
- # TODO(ncbray): support mmaping.
- # https://code.google.com/p/chromium/issues/detail?id=401761
- f.IsBrokenInNaCl()
+ f = mojo.Func('MojoReadMessage', 'MojoResult')
+ f.Param('message_pipe_handle').In('MojoHandle')
+ f.Param('bytes').OutArray('void', 'num_bytes').Optional()
+ f.Param('num_bytes').InOut('uint32_t').Optional()
+ f.Param('handles').OutArray('MojoHandle', 'num_handles').Optional()
+ f.Param('num_handles').InOut('uint32_t').Optional()
+ f.Param('flags').In('MojoReadMessageFlags')
f = mojo.Func('MojoCreateDataPipe', 'MojoResult')
p = f.Param('options')
@@ -81,53 +101,39 @@
f.Param('data_pipe_consumer_handle').In('MojoHandle')
f.Param('num_bytes_read').In('uint32_t')
- f = mojo.Func('MojoGetTimeTicksNow', 'MojoTimeTicks')
-
- f = mojo.Func('MojoClose', 'MojoResult')
- f.Param('handle').In('MojoHandle')
-
- f = mojo.Func('MojoWait', 'MojoResult')
- f.Param('handle').In('MojoHandle')
- f.Param('signals').In('MojoHandleSignals')
- f.Param('deadline').In('MojoDeadline')
- f.Param('signals_state').OutFixedStruct('MojoHandleSignalsState').Optional()
-
- f = mojo.Func('MojoWaitMany', 'MojoResult')
- f.Param('handles').InArray('MojoHandle', 'num_handles')
- f.Param('signals').InArray('MojoHandleSignals', 'num_handles')
- f.Param('num_handles').In('uint32_t')
- f.Param('deadline').In('MojoDeadline')
- f.Param('result_index').Out('uint32_t').Optional()
- p = f.Param('signals_states')
- p.OutFixedStructArray('MojoHandleSignalsState', 'num_handles').Optional()
-
- f = mojo.Func('MojoCreateMessagePipe', 'MojoResult')
+ f = mojo.Func('MojoCreateSharedBuffer', 'MojoResult')
p = f.Param('options')
- p.InExtensibleStruct('MojoCreateMessagePipeOptions').Optional()
- f.Param('message_pipe_handle0').Out('MojoHandle')
- f.Param('message_pipe_handle1').Out('MojoHandle')
+ p.InExtensibleStruct('MojoCreateSharedBufferOptions').Optional()
+ f.Param('num_bytes').In('uint64_t')
+ f.Param('shared_buffer_handle').Out('MojoHandle')
- f = mojo.Func('MojoWriteMessage', 'MojoResult')
- f.Param('message_pipe_handle').In('MojoHandle')
- f.Param('bytes').InArray('void', 'num_bytes').Optional()
- f.Param('num_bytes').In('uint32_t')
- f.Param('handles').InArray('MojoHandle', 'num_handles').Optional()
- f.Param('num_handles').In('uint32_t')
- f.Param('flags').In('MojoWriteMessageFlags')
+ f = mojo.Func('MojoDuplicateBufferHandle', 'MojoResult')
+ f.Param('buffer_handle').In('MojoHandle')
+ p = f.Param('options')
+ p.InExtensibleStruct('MojoDuplicateBufferHandleOptions').Optional()
+ f.Param('new_buffer_handle').Out('MojoHandle')
- f = mojo.Func('MojoReadMessage', 'MojoResult')
- f.Param('message_pipe_handle').In('MojoHandle')
- f.Param('bytes').OutArray('void', 'num_bytes').Optional()
- f.Param('num_bytes').InOut('uint32_t').Optional()
- f.Param('handles').OutArray('MojoHandle', 'num_handles').Optional()
- f.Param('num_handles').InOut('uint32_t').Optional()
- f.Param('flags').In('MojoReadMessageFlags')
+ f = mojo.Func('MojoGetBufferInformation', 'MojoResult')
+ f.Param('buffer_handle').In('MojoHandle')
+ p = f.Param('info')
+ p.OutExtensibleStruct('MojoBufferInformation', 'info_num_bytes')
+ f.Param('info_num_bytes').In('uint32_t')
- # This function is not provided by the Mojo system APIs, but instead allows
- # trusted code to provide a handle for use by untrusted code. See the
- # implementation in mojo_syscall.cc.tmpl.
- f = mojo.Func('_MojoGetInitialHandle', 'MojoResult')
- f.Param('handle').Out('MojoHandle')
+ f = mojo.Func('MojoMapBuffer', 'MojoResult')
+ f.Param('buffer_handle').In('MojoHandle')
+ f.Param('offset').In('uint64_t')
+ f.Param('num_bytes').In('uint64_t')
+ f.Param('buffer').Out('void*')
+ f.Param('flags').In('MojoMapBufferFlags')
+ # TODO(ncbray): support mmaping.
+ # https://code.google.com/p/chromium/issues/detail?id=401761
+ f.IsBrokenInNaCl()
+
+ f = mojo.Func('MojoUnmapBuffer', 'MojoResult')
+ f.Param('buffer').In('void*')
+ # TODO(ncbray): support mmaping.
+ # https://code.google.com/p/chromium/issues/detail?id=401761
+ f.IsBrokenInNaCl()
mojo.Finalize()
diff --git a/mojo/nacl/sfi/nacl_bindings_generator/interface_dsl.py b/mojo/nacl/sfi/nacl_bindings_generator/interface_dsl.py
index 88607ff..9b63197 100644
--- a/mojo/nacl/sfi/nacl_bindings_generator/interface_dsl.py
+++ b/mojo/nacl/sfi/nacl_bindings_generator/interface_dsl.py
@@ -119,6 +119,18 @@
self.is_output = True
return self
+ # Out extensible structs have an input size indicating the buffer size. On
+ # success, the size actually written is indicated in the struct.
+ def OutExtensibleStruct(self, ty, size):
+ self.base_type = ty
+ self.param_type = 'struct ' + ty + '*'
+ self.size = size
+ self.is_array = False
+ self.is_output = True
+ self.is_struct = True
+ self.is_extensible = True
+ return self
+
# The size of the struct is fixed by the API, it cannot be extended.
def OutFixedStruct(self, ty):
self.base_type = ty