| Index: mojo/nacl/generator/generate_nacl_bindings.py
|
| diff --git a/mojo/nacl/generator/generate_nacl_bindings.py b/mojo/nacl/generator/generate_nacl_bindings.py
|
| index 2c8ae9d4d27cc589c4a1a8aebc1d3876887bfaa5..b3f7feb0e9a76f6c2d1103349bc1064083c72076 100755
|
| --- a/mojo/nacl/generator/generate_nacl_bindings.py
|
| +++ b/mojo/nacl/generator/generate_nacl_bindings.py
|
| @@ -157,18 +157,18 @@ class ParamImpl(object):
|
|
|
| # Declare whatever variables are needed to handle this particular parameter.
|
| def DeclareVars(self, code):
|
| - raise NotImplementedError()
|
| + raise NotImplementedError(type(self))
|
|
|
| # Convert the untrusted representation of the parameter into a trusted
|
| # representation, such as a scalar value or a trusted pointer into the
|
| # untrusted address space.
|
| def ConvertParam(self):
|
| - raise NotImplementedError()
|
| + raise NotImplementedError(type(self))
|
|
|
| # For this particular parameter, what expression should be passed when
|
| # invoking the trusted Mojo API function?
|
| def CallParam(self):
|
| - raise NotImplementedError()
|
| + raise NotImplementedError(type(self))
|
|
|
| # After invoking the trusted Mojo API function, transfer data back into
|
| # untrusted memory. Overriden for Out and InOut parameters.
|
| @@ -201,14 +201,34 @@ class ScalarOutputImpl(ParamImpl):
|
|
|
| def ConvertParam(self):
|
| p = self.param
|
| - return 'ConvertScalarOutput(nap, params[%d], &%s_ptr)' % (p.uid + 1, p.name)
|
| + return ('ConvertScalarOutput(nap, params[%d], %s, &%s_ptr)' %
|
| + (p.uid + 1, CBool(p.is_optional), p.name))
|
|
|
| def CallParam(self):
|
| - return '&%s_value' % self.param.name
|
| + name = self.param.name
|
| + expr = '&%s_value' % name
|
| + if self.param.is_optional:
|
| + expr = '%s_ptr ? %s : NULL' % (name, expr)
|
| + return expr
|
|
|
| def CopyOut(self, code):
|
| name = self.param.name
|
| - code << '*%s_ptr = %s_value;' % (name, name)
|
| + if self.param.is_struct:
|
| + # C++ errors when you try to copy a volatile struct pointer.
|
| + # (There are no default copy constructors for this case.)
|
| + # memcpy instead.
|
| + copy_stmt = ('memcpy_volatile_out(%s_ptr, &%s_value, sizeof(%s));' %
|
| + (name, name, self.param.base_type))
|
| + else:
|
| + copy_stmt = '*%s_ptr = %s_value;' % (name, name)
|
| +
|
| + if self.param.is_optional:
|
| + code << 'if (%s_ptr != NULL) {' % (name)
|
| + with code.Indent():
|
| + code << copy_stmt
|
| + code << '}'
|
| + else:
|
| + code << copy_stmt
|
|
|
|
|
| class ScalarInOutImpl(ParamImpl):
|
| @@ -261,34 +281,42 @@ class ArrayImpl(ParamImpl):
|
| return True
|
|
|
|
|
| -class StructInputImpl(ParamImpl):
|
| +class ExtensibleStructInputImpl(ParamImpl):
|
| def DeclareVars(self, code):
|
| code << '%s %s;' % (self.param.param_type, self.param.name)
|
|
|
| def ConvertParam(self):
|
| p = self.param
|
| - return ('ConvertStruct(nap, params[%d], %s, &%s)' %
|
| + return ('ConvertExtensibleStructInput(nap, params[%d], %s, &%s)' %
|
| (p.uid + 1, CBool(p.is_optional), p.name))
|
|
|
| def CallParam(self):
|
| return self.param.name
|
|
|
| -
|
| def ImplForParam(p):
|
| if p.IsScalar():
|
| if p.is_output:
|
| if p.is_input:
|
| return ScalarInOutImpl(p)
|
| else:
|
| - return ScalarOutputImpl(p)
|
| + if p.is_always_written:
|
| + return ScalarOutputImpl(p)
|
| + else:
|
| + # Mojo defines that some of its outputs will not be set in specific
|
| + # cases. To avoid the complexity of determining if the output was set
|
| + # by Mojo, copy the output's current value (possibly junk) and copy it
|
| + # back to untrusted memory afterwards.
|
| + return ScalarInOutImpl(p)
|
| else:
|
| return ScalarInputImpl(p)
|
| elif p.is_array:
|
| return ArrayImpl(p)
|
| elif p.is_struct:
|
| - return StructInputImpl(p)
|
| - else:
|
| - assert False, p
|
| + if p.is_input and not p.is_output and p.is_extensible:
|
| + return ExtensibleStructInputImpl(p)
|
| + if not p.is_input and p.is_output and not p.is_extensible:
|
| + return ScalarOutputImpl(p)
|
| + assert False, p.name
|
|
|
|
|
| def CBool(value):
|
|
|