diff options
author | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-26 23:38:35 +0000 |
---|---|---|
committer | mseaborn@chromium.org <mseaborn@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-26 23:38:35 +0000 |
commit | c3064ecd51f4351a649b5dbea2879b0497320875 (patch) | |
tree | 187c88e4779eec5827938979ebb56ad88f94cb98 /ppapi/generators | |
parent | a7bed07581acc3812eda369aa86db1484b63f686 (diff) | |
download | chromium_src-c3064ecd51f4351a649b5dbea2879b0497320875.zip chromium_src-c3064ecd51f4351a649b5dbea2879b0497320875.tar.gz chromium_src-c3064ecd51f4351a649b5dbea2879b0497320875.tar.bz2 |
PNaCl PPAPI shims: Update for new PNaCl ABI for by-value struct passing
The PNaCl ABI is changing so that by-value struct arguments (and
return values) are expanded out to being passed by pointer, on all
architectures.
This means that __attribute__((pnaclcall)) no longer reflects PNaCl
user code's calling conventions, so we have to change the PNaCl PPAPI
shims. The new shims can be pure C without any special attributes.
Remove now-unused ptr_prefix argument.
This updates nacl_revision to pull in the following NaCl changes:
r11238: (kschimpf) Update pnacl_llvm_rev to 5712db994c8a4abb8c2512fb2900650f8335af66.
r11239: (mseaborn) Update PNaCl toolchain revision in TOOL_REVISIONS to get ExpandByVal
BUG=https://code.google.com/p/nativeclient/issues/detail?id=3400
TEST=cd ppapi/generators && ./generator.py + compile shims
+ "ppapi/generators/idl_gen_pnacl.py --test"
Review URL: https://codereview.chromium.org/14134011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196881 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/generators')
-rwxr-xr-x | ppapi/generators/idl_c_proto.py | 15 | ||||
-rwxr-xr-x | ppapi/generators/idl_gen_pnacl.py | 107 | ||||
-rw-r--r-- | ppapi/generators/idl_gen_wrapper.py | 19 | ||||
-rw-r--r-- | ppapi/generators/test_gen_pnacl/test_interfaces.idl | 51 |
4 files changed, 111 insertions, 81 deletions
diff --git a/ppapi/generators/idl_c_proto.py b/ppapi/generators/idl_c_proto.py index 79656308..fff3e65 100755 --- a/ppapi/generators/idl_c_proto.py +++ b/ppapi/generators/idl_c_proto.py @@ -398,7 +398,7 @@ class CGen(object): def Compose(self, rtype, name, arrayspec, callspec, prefix, func_as_ptr, - ptr_prefix, include_name, unsized_as_ptr): + include_name, unsized_as_ptr): self.LogEnter('Compose: %s %s' % (rtype, name)) arrayspec = ''.join(arrayspec) @@ -417,10 +417,10 @@ class CGen(object): params = [] for ptype, pname, parray, pspec in callspec: params.append(self.Compose(ptype, pname, parray, pspec, '', True, - ptr_prefix='', include_name=True, + include_name=True, unsized_as_ptr=unsized_as_ptr)) if func_as_ptr: - name = '(%s*%s)' % (ptr_prefix, name) + name = '(*%s)' % name if not params: params = ['void'] out = '%s %s(%s)' % (rtype, name, ', '.join(params)) @@ -433,14 +433,13 @@ class CGen(object): # Returns the 'C' style signature of the object # prefix - A prefix for the object's name # func_as_ptr - Formats a function as a function pointer - # ptr_prefix - A prefix that goes before the "*" for a function pointer # include_name - If true, include member name in the signature. - # If false, leave it out. In any case, prefix and ptr_prefix - # are always included. + # If false, leave it out. In any case, prefix is always + # included. # include_version - if True, include version in the member name # def GetSignature(self, node, release, mode, prefix='', func_as_ptr=True, - ptr_prefix='', include_name=True, include_version=False): + include_name=True, include_version=False): self.LogEnter('GetSignature %s %s as func=%s' % (node, mode, func_as_ptr)) rtype, name, arrayspec, callspec = self.GetComponents(node, release, mode) @@ -451,7 +450,7 @@ class CGen(object): unsized_as_ptr = not callspec out = self.Compose(rtype, name, arrayspec, callspec, prefix, - func_as_ptr, ptr_prefix, include_name, unsized_as_ptr) + func_as_ptr, include_name, unsized_as_ptr) self.LogExit('Exit GetSignature: %s' % out) return out diff --git a/ppapi/generators/idl_gen_pnacl.py b/ppapi/generators/idl_gen_pnacl.py index 35fdafd..1d7dc6e1 100755 --- a/ppapi/generators/idl_gen_pnacl.py +++ b/ppapi/generators/idl_gen_pnacl.py @@ -42,7 +42,6 @@ class PnaclGen(WrapperGen): 'Generate the PNaCl shim.') self.cgen = CGen() self._skip_opt = False - self._pnacl_attribute = '__attribute__((pnaclcall))' ############################################################ @@ -51,13 +50,6 @@ class PnaclGen(WrapperGen): We do not generate the header files. """ return 'ppapi/generators/pnacl_shim.h' - def GetGuardStart(self): - return ('\n/* The PNaCl PPAPI shims are only needed on x86-64 and arm. */\n' - '#if defined(__x86_64__) || defined(__arm__)\n\n') - - def GetGuardEnd(self): - return '\n#endif\n' - def InterfaceVersionNeedsWrapping(self, iface, version): """Return true if the interface+version has ANY methods that @@ -108,20 +100,62 @@ class PnaclGen(WrapperGen): ############################################################ + def ConvertByValueReturnType(self, ret, args_spec): + if self.TypeNeedsWrapping(ret, array_dims=[]): + args_spec = [(ret, '_struct_result', [], None)] + args_spec + ret2 = 'void' + wrap_return = True + else: + ret2 = ret + wrap_return = False + return wrap_return, ret2, args_spec + + + def ConvertByValueArguments(self, args_spec): + args = [] + for type_str, name, array_dims, more_args in args_spec: + if self.TypeNeedsWrapping(type_str, array_dims): + type_str += '*' + args.append((type_str, name, array_dims, more_args)) + return args + + + def FormatArgs(self, c_operator, args_spec): + args = [] + for type_str, name, array_dims, more_args in args_spec: + if self.TypeNeedsWrapping(type_str, array_dims): + args.append(c_operator + name) + else: + args.append(name) + return ', '.join(args) + + def GenerateWrapperForPPBMethod(self, iface, member): result = [] func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) - sig = self.cgen.GetSignature(member, iface.release, 'store', - func_prefix, False) - result.append('static %s\n%s {\n' % (self._pnacl_attribute, sig)) - result.append(' const struct %s *iface = %s.real_iface;\n' % - (iface.struct_name, self.GetWrapperInfoName(iface))) ret, name, array, cspec = self.cgen.GetComponents(member, iface.release, 'store') - ret_str, args_str = self.GetReturnArgs(ret, cspec) - result.append(' %siface->%s(%s);\n}\n\n' % (ret_str, - member.GetName(), args_str)) + wrap_return, ret2, cspec2 = self.ConvertByValueReturnType(ret, cspec) + cspec2 = self.ConvertByValueArguments(cspec2) + sig = self.cgen.Compose(ret2, name, array, cspec2, + prefix=func_prefix, + func_as_ptr=False, + include_name=True, + unsized_as_ptr=False) + result.append('static %s {\n' % sig) + result.append(' const struct %s *iface = %s.real_iface;\n' % + (iface.struct_name, self.GetWrapperInfoName(iface))) + + return_prefix = '' + if wrap_return: + return_prefix = '*_struct_result = ' + elif ret != 'void': + return_prefix = 'return ' + + result.append(' %siface->%s(%s);\n}\n\n' % (return_prefix, + member.GetName(), + self.FormatArgs('*', cspec))) return result @@ -133,24 +167,35 @@ class PnaclGen(WrapperGen): result.append('static %s {\n' % sig) result.append(' const struct %s *iface = %s.real_iface;\n' % (iface.struct_name, self.GetWrapperInfoName(iface))) - temp_fp = self.cgen.GetSignature(member, iface.release, 'return', - 'temp_fp', - func_as_ptr=True, - ptr_prefix=self._pnacl_attribute + ' ', - include_name=False) - cast = self.cgen.GetSignature(member, iface.release, 'return', - prefix='', - func_as_ptr=True, - ptr_prefix=self._pnacl_attribute + ' ', - include_name=False) - result.append(' %s = ((%s)iface->%s);\n' % (temp_fp, - cast, - member.GetName())) ret, name, array, cspec = self.cgen.GetComponents(member, iface.release, 'store') - ret_str, args_str = self.GetReturnArgs(ret, cspec) - result.append(' %stemp_fp(%s);\n}\n\n' % (ret_str, args_str)) + wrap_return, ret2, cspec = self.ConvertByValueReturnType(ret, cspec) + cspec2 = self.ConvertByValueArguments(cspec) + temp_fp = self.cgen.Compose(ret2, name, array, cspec2, + prefix='temp_fp', + func_as_ptr=True, + include_name=False, + unsized_as_ptr=False) + cast = self.cgen.Compose(ret2, name, array, cspec2, + prefix='', + func_as_ptr=True, + include_name=False, + unsized_as_ptr=False) + result.append(' %s =\n ((%s)iface->%s);\n' % (temp_fp, + cast, + member.GetName())) + return_prefix = '' + if wrap_return: + result.append(' %s _struct_result;\n' % ret) + elif ret != 'void': + return_prefix = 'return ' + + result.append(' %stemp_fp(%s);\n' % (return_prefix, + self.FormatArgs('&', cspec))) + if wrap_return: + result.append(' return _struct_result;\n') + result.append('}\n\n') return result diff --git a/ppapi/generators/idl_gen_wrapper.py b/ppapi/generators/idl_gen_wrapper.py index 3e483ac..b828562 100644 --- a/ppapi/generators/idl_gen_wrapper.py +++ b/ppapi/generators/idl_gen_wrapper.py @@ -267,21 +267,6 @@ const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) { return '%s_%s_%s_' % (self.wrapper_prefix, release, iface.GetName()) - def GetReturnArgs(self, ret_type, args_spec): - if ret_type != 'void': - ret = 'return ' - else: - ret = '' - if args_spec: - args = [] - for arg in args_spec: - args.append(arg[1]) - args = ', '.join(args) - else: - args = '' - return (ret, args) - - def GenerateWrapperForPPBMethod(self, iface, member): result = [] func_prefix = self.WrapperMethodPrefix(iface.node, iface.release) @@ -358,7 +343,6 @@ const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) { member, iface.release, 'return', prefix='', func_as_ptr=True, - ptr_prefix='', include_name=False) else: cast = '' @@ -440,8 +424,6 @@ const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) { # Generate the includes. self.GenerateIncludes(iface_releases, out) - out.Write(self.GetGuardStart()) - # Write out static helper functions (mystrcmp). self.GenerateHelperFunctions(out) @@ -462,6 +444,5 @@ const void *__%(wrapper_prefix)s_PPPGetInterface(const char *name) { # Write out the IDL-invariant functions. self.GenerateFixedFunctions(out) - out.Write(self.GetGuardEnd()) out.Close() return 0 diff --git a/ppapi/generators/test_gen_pnacl/test_interfaces.idl b/ppapi/generators/test_gen_pnacl/test_interfaces.idl index 78c21eb..f487a76 100644 --- a/ppapi/generators/test_gen_pnacl/test_interfaces.idl +++ b/ppapi/generators/test_gen_pnacl/test_interfaces.idl @@ -37,11 +37,11 @@ struct some_struct2 { }; /* - * static __attribute__((pnaclcall)) int32_t - * Pnacl_M15_PPB_Iface_struct_wrap_foo1(int32_t a, struct some_struct b) { + * static int32_t + * Pnacl_M15_PPB_Iface_struct_wrap_foo1(int32_t a, struct some_struct* b) { * const struct PPB_Iface_struct_wrap_2_0 *iface = * Pnacl_WrapperInfo_PPB_Iface_struct_wrap_2_0.real_iface; - * return iface->foo1(a, b); + * return iface->foo1(a, *b); * } */ [version=2.0] @@ -50,11 +50,11 @@ interface PPB_Iface_struct_wrap { }; /* - * static __attribute__((pnaclcall)) int32_t - * Pnacl_M15_PPB_Iface_union_wrap_foo1(int32_t a, union some_union b) { + * static int32_t + * Pnacl_M15_PPB_Iface_union_wrap_foo1(int32_t a, union some_union* b) { * const struct PPB_Iface_union_wrap_2_0 *iface = * Pnacl_WrapperInfo_PPB_Iface_union_wrap_2_0.real_iface; - * return iface->foo1(a, b); + * return iface->foo1(a, *b); * } */ [version=2.0] @@ -70,18 +70,19 @@ interface PPB_Iface_nowrap { /* - * static __attribute__((pnaclcall)) - * int32_t Pnacl_M13_PPB_SomeWrap_foo1(struct some_struct a) { + * static + * int32_t Pnacl_M13_PPB_SomeWrap_foo1(struct some_struct* a) { * const struct PPB_SomeWrap_0_0 *iface = * Pnacl_WrapperInfo_PPB_SomeWrap_0_0.real_iface; - * return iface->foo1(a); + * return iface->foo1(*a); * } * - * static __attribute__((pnaclcall)) - * struct some_struct Pnacl_M13_PPB_SomeWrap_foo2(int32_t a) { + * static + * void Pnacl_M13_PPB_SomeWrap_foo2(struct some_struct* _struct_result, + * int32_t a) { * const struct PPB_SomeWrap_0_0 *iface = * Pnacl_WrapperInfo_PPB_SomeWrap_0_0.real_iface; - * return iface->foo2(a); + * *_struct_result = iface->foo2(a); * } */ [version=0.0] @@ -105,32 +106,36 @@ interface PPB_SomeWrap { * static int32_t Pnacl_M13_PPP_SomeWrap_foo1(struct some_struct a) { * const struct PPP_SomeWrap_0_0 *iface = * Pnacl_WrapperInfo_PPP_SomeWrap_0_0.real_iface; - * int32_t (__attribute__((pnaclcall)) *temp_fp)(struct some_struct a) = - * ((int32_t (__attribute__((pnaclcall)) *)(struct some_struct a))iface->foo1); - * return temp_fp(a); + * int32_t (*temp_fp)(struct some_struct* a) = + * ((int32_t (*)(struct some_struct* a))iface->foo1); + * return temp_fp(&a); * } * * static struct some_struct Pnacl_M13_PPP_SomeWrap_foo2(int32_t a) { * const struct PPP_SomeWrap_0_0 *iface = * Pnacl_WrapperInfo_PPP_SomeWrap_0_0.real_iface; - * struct some_struct (__attribute__((pnaclcall)) *temp_fp)(int32_t a) = - * ((struct some_struct (__attribute__((pnaclcall)) *)(int32_t a))iface->foo2); - * return temp_fp(a); + * void (*temp_fp)(struct some_struct* _struct_result, int32_t a) = + * ((void (*)(struct some_struct* _struct_result, int32_t a))iface->foo2); + * struct some_struct _struct_result; + * temp_fp(&_struct_result, a); + * return _struct_result; * } * * static struct some_struct Pnacl_M14_PPP_SomeWrap_foo2(int32_t a) { * const struct PPP_SomeWrap_1_0 *iface = * Pnacl_WrapperInfo_PPP_SomeWrap_1_0.real_iface; - * struct some_struct (__attribute__((pnaclcall)) *temp_fp)(int32_t a) = - * ((struct some_struct (__attribute__((pnaclcall)) *)(int32_t a))iface->foo2); - * return temp_fp(a); + * void (*temp_fp)(struct some_struct* _struct_result, int32_t a) = + * ((void (*)(struct some_struct* _struct_result, int32_t a))iface->foo2); + * struct some_struct _struct_result; + * temp_fp(&_struct_result, a); + * return _struct_result; * } * * static int32_t Pnacl_M14_PPP_SomeWrap_foo1(const struct some_struct a[]) { * const struct PPP_SomeWrap_1_0 *iface = * Pnacl_WrapperInfo_PPP_SomeWrap_1_0.real_iface; - * int32_t (__attribute__((pnaclcall)) *temp_fp)(const struct some_struct a[]) = - * ((int32_t (__attribute__((pnaclcall)) *)(const struct some_struct a[]))iface->foo1); + * int32_t (*temp_fp)(const struct some_struct a[]) = + * ((int32_t (*)(const struct some_struct a[]))iface->foo1); * return temp_fp(a); * } */ |