• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4"""Codegen for GEN_JNI.java."""
5
6import common
7import java_types
8
9
10def _stub_for_missing_native(sb, native):
11  sb(f'public static {native.proxy_return_type.to_java()} {native.proxy_name}')
12  with sb.param_list() as plist:
13    plist.extend(p.to_java_declaration() for p in native.proxy_params)
14  with sb.block():
15    sb('throw new RuntimeException("Native method not present");\n')
16
17
18def _forwarding_method(sb, jni_mode, native, target_class_name):
19  sb(f'public static {native.proxy_return_type.to_java()} {native.proxy_name}')
20  sb.param_list([p.to_java_declaration() for p in native.proxy_params])
21  with sb.block():
22    with sb.statement():
23      if not native.proxy_return_type.is_void():
24        sb('return ')
25      if jni_mode.is_muxing:
26        sb(f'{target_class_name}.{native.muxed_name}')
27        with sb.param_list() as plist:
28          if native.muxed_switch_num != -1:
29            plist.append(str(native.muxed_switch_num))
30          plist.extend(p.name for p in native.muxed_params)
31      else:
32        sb(f'{target_class_name}.{native.hashed_name}')
33        sb.param_list([p.name for p in native.proxy_params])
34
35
36def _native_method(sb, jni_mode, native):
37  name = native.boundary_name(jni_mode)
38  if jni_mode.is_hashing:
39    sb(f'// Original name: {native.java_class.full_name_with_dots}#{native.name}\n'
40       )
41  elif not jni_mode.is_muxing:
42    sb(f'// Hashed name: Java_J_N_{native.hashed_name}\n')
43  with sb.statement():
44    sb(f'public static native {native.proxy_return_type.to_java()} {name}')
45    with sb.param_list() as plist:
46      if jni_mode.is_muxing:
47        if native.muxed_switch_num != -1:
48          plist.append('int _switchNum')
49        for i, p in enumerate(native.muxed_params):
50          plist.append(f'{p.java_type.to_java()} p{i}')
51      else:
52        plist.extend(p.to_java_declaration() for p in native.proxy_params)
53
54
55def generate_forwarding(jni_mode, script_name, full_gen_jni_class,
56                        short_gen_jni_class, present_proxy_natives,
57                        absent_proxy_natives):
58  """GEN_JNI.java that forwards calls to native methods on N.java."""
59  sb = common.StringBuilder()
60  sb(f"""\
61//
62// This file was generated by {script_name}
63//
64
65package {full_gen_jni_class.package_with_dots};
66
67public class {full_gen_jni_class.name}""")
68  with sb.block():
69    short_class_with_dots = short_gen_jni_class.full_name_with_dots
70    for native in present_proxy_natives:
71      _forwarding_method(sb, jni_mode, native, short_class_with_dots)
72
73    for native in absent_proxy_natives:
74      _stub_for_missing_native(sb, native)
75  return sb.to_string()
76
77
78def generate_impl(jni_mode,
79                  script_name,
80                  gen_jni_class,
81                  boundary_proxy_natives,
82                  absent_proxy_natives,
83                  *,
84                  whole_hash=None,
85                  priority_hash=None):
86  """GEN_JNI.java (or N.java) that has all "public static native" methods."""
87  sb = common.StringBuilder()
88  sb(f"""\
89//
90// This file was generated by {script_name}
91//
92
93package {gen_jni_class.package_with_dots};
94
95public class {gen_jni_class.name}""")
96  with sb.block():
97    if jni_mode.is_muxing:
98      sb(f"""\
99public static final long WHOLE_HASH = {whole_hash}L;
100public static final long PRIORITY_HASH = {priority_hash}L;
101
102""")
103
104    for native in boundary_proxy_natives:
105      _native_method(sb, jni_mode, native)
106    for native in absent_proxy_natives:
107      _stub_for_missing_native(sb, native)
108  return sb.to_string()
109