frida 16.2.0 → 16.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/BSDmakefile +6 -0
  2. package/Makefile +16 -0
  3. package/README.md +14 -11
  4. package/configure +18 -0
  5. package/configure.bat +22 -0
  6. package/dist/native.js +0 -8
  7. package/lib/application.ts +98 -0
  8. package/lib/authentication.ts +3 -0
  9. package/lib/build.py +50 -0
  10. package/lib/bus.ts +30 -0
  11. package/lib/cancellable.ts +33 -0
  12. package/lib/child.ts +15 -0
  13. package/lib/crash.ts +11 -0
  14. package/lib/device.ts +329 -0
  15. package/lib/device_manager.ts +69 -0
  16. package/lib/endpoint_parameters.ts +56 -0
  17. package/lib/icon.ts +15 -0
  18. package/lib/index.ts +311 -0
  19. package/lib/iostream.ts +78 -0
  20. package/lib/meson.build +53 -0
  21. package/lib/native.ts +9 -0
  22. package/lib/portal_membership.ts +10 -0
  23. package/lib/portal_service.ts +105 -0
  24. package/lib/process.ts +57 -0
  25. package/lib/relay.ts +44 -0
  26. package/lib/script.ts +352 -0
  27. package/lib/session.ts +113 -0
  28. package/lib/signals.ts +45 -0
  29. package/lib/socket_address.ts +35 -0
  30. package/lib/spawn.ts +4 -0
  31. package/lib/system_parameters.ts +78 -0
  32. package/make.bat +23 -0
  33. package/meson.build +160 -0
  34. package/meson.options +11 -0
  35. package/package.json +27 -6
  36. package/releng/deps.py +1133 -0
  37. package/releng/deps.toml +391 -0
  38. package/releng/devkit-assets/frida-core-example-unix.c +188 -0
  39. package/releng/devkit-assets/frida-core-example-windows.c +197 -0
  40. package/releng/devkit-assets/frida-core-example.sln +28 -0
  41. package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
  42. package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
  43. package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
  44. package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
  45. package/releng/devkit-assets/frida-gum-example.sln +28 -0
  46. package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
  47. package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
  48. package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
  49. package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
  50. package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
  51. package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
  52. package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
  53. package/releng/devkit.py +535 -0
  54. package/releng/env.py +420 -0
  55. package/releng/env_android.py +150 -0
  56. package/releng/env_apple.py +176 -0
  57. package/releng/env_generic.py +373 -0
  58. package/releng/frida_version.py +69 -0
  59. package/releng/machine_file.py +44 -0
  60. package/releng/machine_spec.py +290 -0
  61. package/releng/meson/meson.py +27 -0
  62. package/releng/meson/mesonbuild/__init__.py +0 -0
  63. package/releng/meson/mesonbuild/_pathlib.py +63 -0
  64. package/releng/meson/mesonbuild/_typing.py +69 -0
  65. package/releng/meson/mesonbuild/arglist.py +321 -0
  66. package/releng/meson/mesonbuild/ast/__init__.py +23 -0
  67. package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
  68. package/releng/meson/mesonbuild/ast/introspection.py +374 -0
  69. package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
  70. package/releng/meson/mesonbuild/ast/printer.py +620 -0
  71. package/releng/meson/mesonbuild/ast/visitor.py +161 -0
  72. package/releng/meson/mesonbuild/backend/__init__.py +0 -0
  73. package/releng/meson/mesonbuild/backend/backends.py +2047 -0
  74. package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
  75. package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
  76. package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
  77. package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
  78. package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
  79. package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
  80. package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
  81. package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
  82. package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
  83. package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
  84. package/releng/meson/mesonbuild/build.py +3249 -0
  85. package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
  86. package/releng/meson/mesonbuild/cargo/builder.py +238 -0
  87. package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
  88. package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
  89. package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
  90. package/releng/meson/mesonbuild/cargo/version.py +95 -0
  91. package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
  92. package/releng/meson/mesonbuild/cmake/common.py +331 -0
  93. package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
  94. package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
  95. package/releng/meson/mesonbuild/cmake/executor.py +241 -0
  96. package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
  97. package/releng/meson/mesonbuild/cmake/generator.py +186 -0
  98. package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
  99. package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
  100. package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
  101. package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
  102. package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
  103. package/releng/meson/mesonbuild/compilers/asm.py +307 -0
  104. package/releng/meson/mesonbuild/compilers/c.py +788 -0
  105. package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
  106. package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
  107. package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
  108. package/releng/meson/mesonbuild/compilers/cs.py +136 -0
  109. package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
  110. package/releng/meson/mesonbuild/compilers/cython.py +91 -0
  111. package/releng/meson/mesonbuild/compilers/d.py +861 -0
  112. package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
  113. package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
  114. package/releng/meson/mesonbuild/compilers/java.py +113 -0
  115. package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
  116. package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
  117. package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
  118. package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
  119. package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
  120. package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
  121. package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
  122. package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
  123. package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
  124. package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
  125. package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
  126. package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
  127. package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
  128. package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
  129. package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
  130. package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
  131. package/releng/meson/mesonbuild/compilers/objc.py +120 -0
  132. package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
  133. package/releng/meson/mesonbuild/compilers/rust.py +230 -0
  134. package/releng/meson/mesonbuild/compilers/swift.py +131 -0
  135. package/releng/meson/mesonbuild/compilers/vala.py +121 -0
  136. package/releng/meson/mesonbuild/coredata.py +1532 -0
  137. package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
  138. package/releng/meson/mesonbuild/dependencies/base.py +663 -0
  139. package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
  140. package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
  141. package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
  142. package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
  143. package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
  144. package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
  145. package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
  146. package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
  147. package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
  148. package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
  149. package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
  150. package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
  151. package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
  152. package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
  153. package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
  154. package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
  155. package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
  156. package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
  157. package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
  158. package/releng/meson/mesonbuild/dependencies/python.py +431 -0
  159. package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
  160. package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
  161. package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
  162. package/releng/meson/mesonbuild/depfile.py +82 -0
  163. package/releng/meson/mesonbuild/envconfig.py +480 -0
  164. package/releng/meson/mesonbuild/environment.py +987 -0
  165. package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
  166. package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
  167. package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
  168. package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
  169. package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
  170. package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
  171. package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
  172. package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
  173. package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
  174. package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
  175. package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
  176. package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
  177. package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
  178. package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
  179. package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
  180. package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
  181. package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
  182. package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
  183. package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
  184. package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
  185. package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
  186. package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
  187. package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
  188. package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
  189. package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
  190. package/releng/meson/mesonbuild/linkers/base.py +39 -0
  191. package/releng/meson/mesonbuild/linkers/detect.py +229 -0
  192. package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
  193. package/releng/meson/mesonbuild/mcompile.py +380 -0
  194. package/releng/meson/mesonbuild/mconf.py +368 -0
  195. package/releng/meson/mesonbuild/mdevenv.py +234 -0
  196. package/releng/meson/mesonbuild/mdist.py +376 -0
  197. package/releng/meson/mesonbuild/mesondata.py +38 -0
  198. package/releng/meson/mesonbuild/mesonlib.py +23 -0
  199. package/releng/meson/mesonbuild/mesonmain.py +289 -0
  200. package/releng/meson/mesonbuild/minit.py +204 -0
  201. package/releng/meson/mesonbuild/minstall.py +864 -0
  202. package/releng/meson/mesonbuild/mintro.py +667 -0
  203. package/releng/meson/mesonbuild/mlog.py +542 -0
  204. package/releng/meson/mesonbuild/modules/__init__.py +270 -0
  205. package/releng/meson/mesonbuild/modules/cmake.py +442 -0
  206. package/releng/meson/mesonbuild/modules/cuda.py +377 -0
  207. package/releng/meson/mesonbuild/modules/dlang.py +117 -0
  208. package/releng/meson/mesonbuild/modules/external_project.py +306 -0
  209. package/releng/meson/mesonbuild/modules/fs.py +323 -0
  210. package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
  211. package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
  212. package/releng/meson/mesonbuild/modules/i18n.py +405 -0
  213. package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
  214. package/releng/meson/mesonbuild/modules/java.py +112 -0
  215. package/releng/meson/mesonbuild/modules/keyval.py +65 -0
  216. package/releng/meson/mesonbuild/modules/modtest.py +33 -0
  217. package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
  218. package/releng/meson/mesonbuild/modules/python.py +556 -0
  219. package/releng/meson/mesonbuild/modules/python3.py +85 -0
  220. package/releng/meson/mesonbuild/modules/qt.py +621 -0
  221. package/releng/meson/mesonbuild/modules/qt4.py +23 -0
  222. package/releng/meson/mesonbuild/modules/qt5.py +23 -0
  223. package/releng/meson/mesonbuild/modules/qt6.py +22 -0
  224. package/releng/meson/mesonbuild/modules/rust.py +355 -0
  225. package/releng/meson/mesonbuild/modules/simd.py +114 -0
  226. package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
  227. package/releng/meson/mesonbuild/modules/wayland.py +151 -0
  228. package/releng/meson/mesonbuild/modules/windows.py +207 -0
  229. package/releng/meson/mesonbuild/mparser.py +1114 -0
  230. package/releng/meson/mesonbuild/msetup.py +365 -0
  231. package/releng/meson/mesonbuild/msubprojects.py +764 -0
  232. package/releng/meson/mesonbuild/mtest.py +2201 -0
  233. package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
  234. package/releng/meson/mesonbuild/optinterpreter.py +276 -0
  235. package/releng/meson/mesonbuild/programs.py +367 -0
  236. package/releng/meson/mesonbuild/rewriter.py +1075 -0
  237. package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
  238. package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
  239. package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
  240. package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
  241. package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
  242. package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
  243. package/releng/meson/mesonbuild/scripts/copy.py +19 -0
  244. package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
  245. package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
  246. package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
  247. package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
  248. package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
  249. package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
  250. package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
  251. package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
  252. package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
  253. package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
  254. package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
  255. package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
  256. package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
  257. package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
  258. package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
  259. package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
  260. package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
  261. package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
  262. package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
  263. package/releng/meson/mesonbuild/scripts/tags.py +44 -0
  264. package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
  265. package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
  266. package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
  267. package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
  268. package/releng/meson/mesonbuild/templates/__init__.py +0 -0
  269. package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
  270. package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
  271. package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
  272. package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
  273. package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
  274. package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
  275. package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
  276. package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
  277. package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
  278. package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
  279. package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
  280. package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
  281. package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
  282. package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
  283. package/releng/meson/mesonbuild/utils/__init__.py +0 -0
  284. package/releng/meson/mesonbuild/utils/core.py +166 -0
  285. package/releng/meson/mesonbuild/utils/platform.py +27 -0
  286. package/releng/meson/mesonbuild/utils/posix.py +32 -0
  287. package/releng/meson/mesonbuild/utils/universal.py +2445 -0
  288. package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
  289. package/releng/meson/mesonbuild/utils/win32.py +29 -0
  290. package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
  291. package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
  292. package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
  293. package/releng/meson-scripts/BSDmakefile +6 -0
  294. package/releng/meson-scripts/Makefile +16 -0
  295. package/releng/meson-scripts/configure +18 -0
  296. package/releng/meson-scripts/configure.bat +22 -0
  297. package/releng/meson-scripts/make.bat +23 -0
  298. package/releng/meson_configure.py +506 -0
  299. package/releng/meson_make.py +131 -0
  300. package/releng/mkdevkit.py +107 -0
  301. package/releng/mkfatmacho.py +54 -0
  302. package/releng/post-process-oabi.py +97 -0
  303. package/releng/progress.py +14 -0
  304. package/releng/sync-from-upstream.py +185 -0
  305. package/releng/tomlkit/tomlkit/__init__.py +59 -0
  306. package/releng/tomlkit/tomlkit/_compat.py +22 -0
  307. package/releng/tomlkit/tomlkit/_types.py +83 -0
  308. package/releng/tomlkit/tomlkit/_utils.py +158 -0
  309. package/releng/tomlkit/tomlkit/api.py +308 -0
  310. package/releng/tomlkit/tomlkit/container.py +875 -0
  311. package/releng/tomlkit/tomlkit/exceptions.py +227 -0
  312. package/releng/tomlkit/tomlkit/items.py +1967 -0
  313. package/releng/tomlkit/tomlkit/parser.py +1141 -0
  314. package/releng/tomlkit/tomlkit/py.typed +0 -0
  315. package/releng/tomlkit/tomlkit/source.py +180 -0
  316. package/releng/tomlkit/tomlkit/toml_char.py +52 -0
  317. package/releng/tomlkit/tomlkit/toml_document.py +7 -0
  318. package/releng/tomlkit/tomlkit/toml_file.py +58 -0
  319. package/releng/winenv.py +140 -0
  320. package/scripts/adjust-version.py +19 -0
  321. package/scripts/detect-version.py +40 -0
  322. package/scripts/fetch-abi-bits.py +343 -0
  323. package/scripts/install.js +23 -0
  324. package/scripts/package.py +15 -0
  325. package/src/addon.cc +76 -0
  326. package/src/application.cc +148 -0
  327. package/src/application.h +31 -0
  328. package/src/authentication.cc +174 -0
  329. package/src/authentication.h +24 -0
  330. package/src/bus.cc +167 -0
  331. package/src/bus.h +33 -0
  332. package/src/cancellable.cc +117 -0
  333. package/src/cancellable.h +31 -0
  334. package/src/child.cc +150 -0
  335. package/src/child.h +32 -0
  336. package/src/crash.cc +122 -0
  337. package/src/crash.h +30 -0
  338. package/src/device.cc +1302 -0
  339. package/src/device.h +55 -0
  340. package/src/device_manager.cc +362 -0
  341. package/src/device_manager.h +35 -0
  342. package/src/endpoint_parameters.cc +171 -0
  343. package/src/endpoint_parameters.h +28 -0
  344. package/src/glib_context.cc +62 -0
  345. package/src/glib_context.h +29 -0
  346. package/src/glib_object.cc +25 -0
  347. package/src/glib_object.h +37 -0
  348. package/src/iostream.cc +247 -0
  349. package/src/iostream.h +30 -0
  350. package/src/meson.build +26 -0
  351. package/src/operation.h +94 -0
  352. package/src/portal_membership.cc +100 -0
  353. package/src/portal_membership.h +26 -0
  354. package/src/portal_service.cc +401 -0
  355. package/src/portal_service.h +40 -0
  356. package/src/process.cc +135 -0
  357. package/src/process.h +30 -0
  358. package/src/relay.cc +139 -0
  359. package/src/relay.h +31 -0
  360. package/src/runtime.cc +443 -0
  361. package/src/runtime.h +64 -0
  362. package/src/script.cc +301 -0
  363. package/src/script.h +36 -0
  364. package/src/session.cc +860 -0
  365. package/src/session.h +42 -0
  366. package/src/signals.cc +334 -0
  367. package/src/signals.h +47 -0
  368. package/src/spawn.cc +95 -0
  369. package/src/spawn.h +27 -0
  370. package/src/usage_monitor.h +117 -0
  371. package/src/uv_context.cc +118 -0
  372. package/src/uv_context.h +40 -0
  373. package/src/win_delay_load_hook.cc +63 -0
  374. package/subprojects/frida-core.wrap +8 -0
  375. package/subprojects/nan.wrap +9 -0
  376. package/subprojects/packagefiles/nan.patch +13 -0
  377. package/test/data/index.ts +13 -0
  378. package/test/data/unixvictim-linux-x86 +0 -0
  379. package/test/data/unixvictim-linux-x86_64 +0 -0
  380. package/test/data/unixvictim-macos +0 -0
  381. package/test/device.ts +27 -0
  382. package/test/device_manager.ts +16 -0
  383. package/test/labrat.ts +32 -0
  384. package/test/script.ts +176 -0
  385. package/test/session.ts +73 -0
  386. package/tsconfig.json +18 -0
@@ -0,0 +1,665 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2016-2017 The Meson development team
3
+
4
+ # This class contains the basic functionality needed to run any interpreter
5
+ # or an interpreter-based tool.
6
+ from __future__ import annotations
7
+
8
+ from .. import environment, mparser, mesonlib
9
+
10
+ from .baseobjects import (
11
+ InterpreterObject,
12
+ MesonInterpreterObject,
13
+ MutableInterpreterObject,
14
+ ObjectHolder,
15
+ IterableObject,
16
+ ContextManagerObject,
17
+
18
+ HoldableTypes,
19
+ )
20
+
21
+ from .exceptions import (
22
+ BreakRequest,
23
+ ContinueRequest,
24
+ InterpreterException,
25
+ InvalidArguments,
26
+ InvalidCode,
27
+ SubdirDoneRequest,
28
+ )
29
+
30
+ from .decorators import FeatureNew
31
+ from .disabler import Disabler, is_disabled
32
+ from .helpers import default_resolve_key, flatten, resolve_second_level_holders, stringifyUserArguments
33
+ from .operator import MesonOperator
34
+ from ._unholder import _unholder
35
+
36
+ import os, copy, re, pathlib
37
+ import typing as T
38
+ import textwrap
39
+
40
+ if T.TYPE_CHECKING:
41
+ from .baseobjects import InterpreterObjectTypeVar, SubProject, TYPE_kwargs, TYPE_var
42
+ from ..interpreter import Interpreter
43
+
44
+ HolderMapType = T.Dict[
45
+ T.Union[
46
+ T.Type[mesonlib.HoldableObject],
47
+ T.Type[int],
48
+ T.Type[bool],
49
+ T.Type[str],
50
+ T.Type[list],
51
+ T.Type[dict],
52
+ ],
53
+ # For some reason, this has to be a callable and can't just be ObjectHolder[InterpreterObjectTypeVar]
54
+ T.Callable[[InterpreterObjectTypeVar, 'Interpreter'], ObjectHolder[InterpreterObjectTypeVar]]
55
+ ]
56
+
57
+ FunctionType = T.Dict[
58
+ str,
59
+ T.Callable[[mparser.BaseNode, T.List[TYPE_var], T.Dict[str, TYPE_var]], TYPE_var]
60
+ ]
61
+
62
+
63
+ class InvalidCodeOnVoid(InvalidCode):
64
+
65
+ def __init__(self, op_type: str) -> None:
66
+ super().__init__(f'Cannot perform {op_type!r} operation on void statement.')
67
+
68
+
69
+ class InterpreterBase:
70
+ def __init__(self, source_root: str, subdir: str, subproject: 'SubProject'):
71
+ self.source_root = source_root
72
+ self.funcs: FunctionType = {}
73
+ self.builtin: T.Dict[str, InterpreterObject] = {}
74
+ # Holder maps store a mapping from an HoldableObject to a class ObjectHolder
75
+ self.holder_map: HolderMapType = {}
76
+ self.bound_holder_map: HolderMapType = {}
77
+ self.subdir = subdir
78
+ self.root_subdir = subdir
79
+ self.subproject = subproject
80
+ self.variables: T.Dict[str, InterpreterObject] = {}
81
+ self.argument_depth = 0
82
+ self.current_lineno = -1
83
+ # Current node set during a function call. This can be used as location
84
+ # when printing a warning message during a method call.
85
+ self.current_node: mparser.BaseNode = None
86
+ # This is set to `version_string` when this statement is evaluated:
87
+ # meson.version().compare_version(version_string)
88
+ # If it was part of a if-clause, it is used to temporally override the
89
+ # current meson version target within that if-block.
90
+ self.tmp_meson_version: T.Optional[str] = None
91
+
92
+ def handle_meson_version_from_ast(self, strict: bool = True) -> None:
93
+ # do nothing in an AST interpreter
94
+ return
95
+
96
+ def load_root_meson_file(self) -> None:
97
+ mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename)
98
+ if not os.path.isfile(mesonfile):
99
+ raise InvalidArguments(f'Missing Meson file in {mesonfile}')
100
+ with open(mesonfile, encoding='utf-8') as mf:
101
+ code = mf.read()
102
+ if code.isspace():
103
+ raise InvalidCode('Builder file is empty.')
104
+ assert isinstance(code, str)
105
+ try:
106
+ self.ast = mparser.Parser(code, mesonfile).parse()
107
+ self.handle_meson_version_from_ast()
108
+ except mparser.ParseException as me:
109
+ me.file = mesonfile
110
+ if me.ast:
111
+ # try to detect parser errors from new syntax added by future
112
+ # meson versions, and just tell the user to update meson
113
+ self.ast = me.ast
114
+ self.handle_meson_version_from_ast()
115
+ raise me
116
+
117
+ def parse_project(self) -> None:
118
+ """
119
+ Parses project() and initializes languages, compilers etc. Do this
120
+ early because we need this before we parse the rest of the AST.
121
+ """
122
+ self.evaluate_codeblock(self.ast, end=1)
123
+
124
+ def sanity_check_ast(self) -> None:
125
+ def _is_project(ast: mparser.CodeBlockNode) -> object:
126
+ if not isinstance(ast, mparser.CodeBlockNode):
127
+ raise InvalidCode('AST is of invalid type. Possibly a bug in the parser.')
128
+ if not ast.lines:
129
+ raise InvalidCode('No statements in code.')
130
+ first = ast.lines[0]
131
+ return isinstance(first, mparser.FunctionNode) and first.func_name.value == 'project'
132
+
133
+ if not _is_project(self.ast):
134
+ p = pathlib.Path(self.source_root).resolve()
135
+ found = p
136
+ for parent in p.parents:
137
+ if (parent / 'meson.build').is_file():
138
+ with open(parent / 'meson.build', encoding='utf-8') as f:
139
+ code = f.read()
140
+
141
+ try:
142
+ ast = mparser.Parser(code, 'empty').parse()
143
+ except mparser.ParseException:
144
+ continue
145
+
146
+ if _is_project(ast):
147
+ found = parent
148
+ break
149
+ else:
150
+ break
151
+
152
+ error = 'first statement must be a call to project()'
153
+ if found != p:
154
+ raise InvalidCode(f'Not the project root: {error}\n\nDid you mean to run meson from the directory: "{found}"?')
155
+ else:
156
+ raise InvalidCode(f'Invalid source tree: {error}')
157
+
158
+ def run(self) -> None:
159
+ # Evaluate everything after the first line, which is project() because
160
+ # we already parsed that in self.parse_project()
161
+ try:
162
+ self.evaluate_codeblock(self.ast, start=1)
163
+ except SubdirDoneRequest:
164
+ pass
165
+
166
+ def evaluate_codeblock(self, node: mparser.CodeBlockNode, start: int = 0, end: T.Optional[int] = None) -> None:
167
+ if node is None:
168
+ return
169
+ if not isinstance(node, mparser.CodeBlockNode):
170
+ e = InvalidCode('Tried to execute a non-codeblock. Possibly a bug in the parser.')
171
+ e.lineno = node.lineno
172
+ e.colno = node.colno
173
+ raise e
174
+ statements = node.lines[start:end]
175
+ i = 0
176
+ while i < len(statements):
177
+ cur = statements[i]
178
+ try:
179
+ self.current_lineno = cur.lineno
180
+ self.evaluate_statement(cur)
181
+ except Exception as e:
182
+ if getattr(e, 'lineno', None) is None:
183
+ # We are doing the equivalent to setattr here and mypy does not like it
184
+ # NOTE: self.current_node is continually updated during processing
185
+ e.lineno = self.current_node.lineno # type: ignore
186
+ e.colno = self.current_node.colno # type: ignore
187
+ e.file = os.path.join(self.source_root, self.subdir, environment.build_filename) # type: ignore
188
+ raise e
189
+ i += 1 # In THE FUTURE jump over blocks and stuff.
190
+
191
+ def evaluate_statement(self, cur: mparser.BaseNode) -> T.Optional[InterpreterObject]:
192
+ self.current_node = cur
193
+ if isinstance(cur, mparser.FunctionNode):
194
+ return self.function_call(cur)
195
+ elif isinstance(cur, mparser.PlusAssignmentNode):
196
+ self.evaluate_plusassign(cur)
197
+ elif isinstance(cur, mparser.AssignmentNode):
198
+ self.assignment(cur)
199
+ elif isinstance(cur, mparser.MethodNode):
200
+ return self.method_call(cur)
201
+ elif isinstance(cur, mparser.BaseStringNode):
202
+ if isinstance(cur, mparser.MultilineFormatStringNode):
203
+ return self.evaluate_multiline_fstring(cur)
204
+ elif isinstance(cur, mparser.FormatStringNode):
205
+ return self.evaluate_fstring(cur)
206
+ else:
207
+ return self._holderify(cur.value)
208
+ elif isinstance(cur, mparser.BooleanNode):
209
+ return self._holderify(cur.value)
210
+ elif isinstance(cur, mparser.IfClauseNode):
211
+ return self.evaluate_if(cur)
212
+ elif isinstance(cur, mparser.IdNode):
213
+ return self.get_variable(cur.value)
214
+ elif isinstance(cur, mparser.ComparisonNode):
215
+ return self.evaluate_comparison(cur)
216
+ elif isinstance(cur, mparser.ArrayNode):
217
+ return self.evaluate_arraystatement(cur)
218
+ elif isinstance(cur, mparser.DictNode):
219
+ return self.evaluate_dictstatement(cur)
220
+ elif isinstance(cur, mparser.NumberNode):
221
+ return self._holderify(cur.value)
222
+ elif isinstance(cur, mparser.AndNode):
223
+ return self.evaluate_andstatement(cur)
224
+ elif isinstance(cur, mparser.OrNode):
225
+ return self.evaluate_orstatement(cur)
226
+ elif isinstance(cur, mparser.NotNode):
227
+ return self.evaluate_notstatement(cur)
228
+ elif isinstance(cur, mparser.UMinusNode):
229
+ return self.evaluate_uminusstatement(cur)
230
+ elif isinstance(cur, mparser.ArithmeticNode):
231
+ return self.evaluate_arithmeticstatement(cur)
232
+ elif isinstance(cur, mparser.ForeachClauseNode):
233
+ self.evaluate_foreach(cur)
234
+ elif isinstance(cur, mparser.IndexNode):
235
+ return self.evaluate_indexing(cur)
236
+ elif isinstance(cur, mparser.TernaryNode):
237
+ return self.evaluate_ternary(cur)
238
+ elif isinstance(cur, mparser.ContinueNode):
239
+ raise ContinueRequest()
240
+ elif isinstance(cur, mparser.BreakNode):
241
+ raise BreakRequest()
242
+ elif isinstance(cur, mparser.ParenthesizedNode):
243
+ return self.evaluate_statement(cur.inner)
244
+ elif isinstance(cur, mparser.TestCaseClauseNode):
245
+ return self.evaluate_testcase(cur)
246
+ else:
247
+ raise InvalidCode("Unknown statement.")
248
+ return None
249
+
250
+ def evaluate_arraystatement(self, cur: mparser.ArrayNode) -> InterpreterObject:
251
+ (arguments, kwargs) = self.reduce_arguments(cur.args)
252
+ if len(kwargs) > 0:
253
+ raise InvalidCode('Keyword arguments are invalid in array construction.')
254
+ return self._holderify([_unholder(x) for x in arguments])
255
+
256
+ @FeatureNew('dict', '0.47.0')
257
+ def evaluate_dictstatement(self, cur: mparser.DictNode) -> InterpreterObject:
258
+ def resolve_key(key: mparser.BaseNode) -> str:
259
+ if not isinstance(key, mparser.BaseStringNode):
260
+ FeatureNew.single_use('Dictionary entry using non literal key', '0.53.0', self.subproject)
261
+ key_holder = self.evaluate_statement(key)
262
+ if key_holder is None:
263
+ raise InvalidArguments('Key cannot be void.')
264
+ str_key = _unholder(key_holder)
265
+ if not isinstance(str_key, str):
266
+ raise InvalidArguments('Key must be a string')
267
+ return str_key
268
+ arguments, kwargs = self.reduce_arguments(cur.args, key_resolver=resolve_key, duplicate_key_error='Duplicate dictionary key: {}')
269
+ assert not arguments
270
+ return self._holderify({k: _unholder(v) for k, v in kwargs.items()})
271
+
272
+ def evaluate_notstatement(self, cur: mparser.NotNode) -> InterpreterObject:
273
+ v = self.evaluate_statement(cur.value)
274
+ if v is None:
275
+ raise InvalidCodeOnVoid('not')
276
+ if isinstance(v, Disabler):
277
+ return v
278
+ return self._holderify(v.operator_call(MesonOperator.NOT, None))
279
+
280
+ def evaluate_if(self, node: mparser.IfClauseNode) -> T.Optional[Disabler]:
281
+ assert isinstance(node, mparser.IfClauseNode)
282
+ for i in node.ifs:
283
+ # Reset self.tmp_meson_version to know if it gets set during this
284
+ # statement evaluation.
285
+ self.tmp_meson_version = None
286
+ result = self.evaluate_statement(i.condition)
287
+ if result is None:
288
+ raise InvalidCodeOnVoid('if')
289
+ if isinstance(result, Disabler):
290
+ return result
291
+ if not isinstance(result, InterpreterObject):
292
+ raise mesonlib.MesonBugException(f'Argument to if ({result}) is not an InterpreterObject but {type(result).__name__}.')
293
+ res = result.operator_call(MesonOperator.BOOL, None)
294
+ if not isinstance(res, bool):
295
+ raise InvalidCode(f'If clause {result!r} does not evaluate to true or false.')
296
+ if res:
297
+ prev_meson_version = mesonlib.project_meson_versions[self.subproject]
298
+ if self.tmp_meson_version:
299
+ mesonlib.project_meson_versions[self.subproject] = self.tmp_meson_version
300
+ try:
301
+ self.evaluate_codeblock(i.block)
302
+ finally:
303
+ mesonlib.project_meson_versions[self.subproject] = prev_meson_version
304
+ return None
305
+ if not isinstance(node.elseblock, mparser.EmptyNode):
306
+ self.evaluate_codeblock(node.elseblock.block)
307
+ return None
308
+
309
+ def evaluate_testcase(self, node: mparser.TestCaseClauseNode) -> T.Optional[Disabler]:
310
+ result = self.evaluate_statement(node.condition)
311
+ if isinstance(result, Disabler):
312
+ return result
313
+ if not isinstance(result, ContextManagerObject):
314
+ raise InvalidCode(f'testcase clause {result!r} does not evaluate to a context manager.')
315
+ with result:
316
+ self.evaluate_codeblock(node.block)
317
+ return None
318
+
319
+ def evaluate_comparison(self, node: mparser.ComparisonNode) -> InterpreterObject:
320
+ val1 = self.evaluate_statement(node.left)
321
+ if val1 is None:
322
+ raise mesonlib.MesonException('Cannot compare a void statement on the left-hand side')
323
+ if isinstance(val1, Disabler):
324
+ return val1
325
+ val2 = self.evaluate_statement(node.right)
326
+ if val2 is None:
327
+ raise mesonlib.MesonException('Cannot compare a void statement on the right-hand side')
328
+ if isinstance(val2, Disabler):
329
+ return val2
330
+
331
+ # New code based on InterpreterObjects
332
+ operator = {
333
+ 'in': MesonOperator.IN,
334
+ 'notin': MesonOperator.NOT_IN,
335
+ '==': MesonOperator.EQUALS,
336
+ '!=': MesonOperator.NOT_EQUALS,
337
+ '>': MesonOperator.GREATER,
338
+ '<': MesonOperator.LESS,
339
+ '>=': MesonOperator.GREATER_EQUALS,
340
+ '<=': MesonOperator.LESS_EQUALS,
341
+ }[node.ctype]
342
+
343
+ # Check if the arguments should be reversed for simplicity (this essentially converts `in` to `contains`)
344
+ if operator in (MesonOperator.IN, MesonOperator.NOT_IN):
345
+ val1, val2 = val2, val1
346
+
347
+ val1.current_node = node
348
+ return self._holderify(val1.operator_call(operator, _unholder(val2)))
349
+
350
+ def evaluate_andstatement(self, cur: mparser.AndNode) -> InterpreterObject:
351
+ l = self.evaluate_statement(cur.left)
352
+ if l is None:
353
+ raise mesonlib.MesonException('Cannot compare a void statement on the left-hand side')
354
+ if isinstance(l, Disabler):
355
+ return l
356
+ l_bool = l.operator_call(MesonOperator.BOOL, None)
357
+ if not l_bool:
358
+ return self._holderify(l_bool)
359
+ r = self.evaluate_statement(cur.right)
360
+ if r is None:
361
+ raise mesonlib.MesonException('Cannot compare a void statement on the right-hand side')
362
+ if isinstance(r, Disabler):
363
+ return r
364
+ return self._holderify(r.operator_call(MesonOperator.BOOL, None))
365
+
366
+ def evaluate_orstatement(self, cur: mparser.OrNode) -> InterpreterObject:
367
+ l = self.evaluate_statement(cur.left)
368
+ if l is None:
369
+ raise mesonlib.MesonException('Cannot compare a void statement on the left-hand side')
370
+ if isinstance(l, Disabler):
371
+ return l
372
+ l_bool = l.operator_call(MesonOperator.BOOL, None)
373
+ if l_bool:
374
+ return self._holderify(l_bool)
375
+ r = self.evaluate_statement(cur.right)
376
+ if r is None:
377
+ raise mesonlib.MesonException('Cannot compare a void statement on the right-hand side')
378
+ if isinstance(r, Disabler):
379
+ return r
380
+ return self._holderify(r.operator_call(MesonOperator.BOOL, None))
381
+
382
+ def evaluate_uminusstatement(self, cur: mparser.UMinusNode) -> InterpreterObject:
383
+ v = self.evaluate_statement(cur.value)
384
+ if v is None:
385
+ raise InvalidCodeOnVoid('unary minus')
386
+ if isinstance(v, Disabler):
387
+ return v
388
+ v.current_node = cur
389
+ return self._holderify(v.operator_call(MesonOperator.UMINUS, None))
390
+
391
+ def evaluate_arithmeticstatement(self, cur: mparser.ArithmeticNode) -> InterpreterObject:
392
+ l = self.evaluate_statement(cur.left)
393
+ if isinstance(l, Disabler):
394
+ return l
395
+ r = self.evaluate_statement(cur.right)
396
+ if isinstance(r, Disabler):
397
+ return r
398
+ if l is None or r is None:
399
+ raise InvalidCodeOnVoid(cur.operation)
400
+
401
+ mapping: T.Dict[str, MesonOperator] = {
402
+ 'add': MesonOperator.PLUS,
403
+ 'sub': MesonOperator.MINUS,
404
+ 'mul': MesonOperator.TIMES,
405
+ 'div': MesonOperator.DIV,
406
+ 'mod': MesonOperator.MOD,
407
+ }
408
+ l.current_node = cur
409
+ res = l.operator_call(mapping[cur.operation], _unholder(r))
410
+ return self._holderify(res)
411
+
412
+ def evaluate_ternary(self, node: mparser.TernaryNode) -> T.Optional[InterpreterObject]:
413
+ assert isinstance(node, mparser.TernaryNode)
414
+ result = self.evaluate_statement(node.condition)
415
+ if result is None:
416
+ raise mesonlib.MesonException('Cannot use a void statement as condition for ternary operator.')
417
+ if isinstance(result, Disabler):
418
+ return result
419
+ result.current_node = node
420
+ result_bool = result.operator_call(MesonOperator.BOOL, None)
421
+ if result_bool:
422
+ return self.evaluate_statement(node.trueblock)
423
+ else:
424
+ return self.evaluate_statement(node.falseblock)
425
+
426
+ @FeatureNew('multiline format strings', '0.63.0')
427
+ def evaluate_multiline_fstring(self, node: mparser.MultilineFormatStringNode) -> InterpreterObject:
428
+ return self.evaluate_fstring(node)
429
+
430
+ @FeatureNew('format strings', '0.58.0')
431
+ def evaluate_fstring(self, node: T.Union[mparser.FormatStringNode, mparser.MultilineFormatStringNode]) -> InterpreterObject:
432
+ def replace(match: T.Match[str]) -> str:
433
+ var = str(match.group(1))
434
+ try:
435
+ val = _unholder(self.variables[var])
436
+ if isinstance(val, (list, dict)):
437
+ FeatureNew.single_use('List or dictionary in f-string', '1.3.0', self.subproject, location=self.current_node)
438
+ try:
439
+ return stringifyUserArguments(val, self.subproject)
440
+ except InvalidArguments as e:
441
+ raise InvalidArguments(f'f-string: {str(e)}')
442
+ except KeyError:
443
+ raise InvalidCode(f'Identifier "{var}" does not name a variable.')
444
+
445
+ res = re.sub(r'@([_a-zA-Z][_0-9a-zA-Z]*)@', replace, node.value)
446
+ return self._holderify(res)
447
+
448
+ def evaluate_foreach(self, node: mparser.ForeachClauseNode) -> None:
449
+ assert isinstance(node, mparser.ForeachClauseNode)
450
+ items = self.evaluate_statement(node.items)
451
+ if not isinstance(items, IterableObject):
452
+ raise InvalidArguments('Items of foreach loop do not support iterating')
453
+
454
+ tsize = items.iter_tuple_size()
455
+ if len(node.varnames) != (tsize or 1):
456
+ raise InvalidArguments(f'Foreach expects exactly {tsize or 1} variables for iterating over objects of type {items.display_name()}')
457
+
458
+ for i in items.iter_self():
459
+ if tsize is None:
460
+ if isinstance(i, tuple):
461
+ raise mesonlib.MesonBugException(f'Iteration of {items} returned a tuple even though iter_tuple_size() is None')
462
+ self.set_variable(node.varnames[0].value, self._holderify(i))
463
+ else:
464
+ if not isinstance(i, tuple):
465
+ raise mesonlib.MesonBugException(f'Iteration of {items} did not return a tuple even though iter_tuple_size() is {tsize}')
466
+ if len(i) != tsize:
467
+ raise mesonlib.MesonBugException(f'Iteration of {items} did not return a tuple even though iter_tuple_size() is {tsize}')
468
+ for j in range(tsize):
469
+ self.set_variable(node.varnames[j].value, self._holderify(i[j]))
470
+ try:
471
+ self.evaluate_codeblock(node.block)
472
+ except ContinueRequest:
473
+ continue
474
+ except BreakRequest:
475
+ break
476
+
477
+ def evaluate_plusassign(self, node: mparser.PlusAssignmentNode) -> None:
478
+ assert isinstance(node, mparser.PlusAssignmentNode)
479
+ varname = node.var_name.value
480
+ addition = self.evaluate_statement(node.value)
481
+ if addition is None:
482
+ raise InvalidCodeOnVoid('plus assign')
483
+
484
+ # Remember that all variables are immutable. We must always create a
485
+ # full new variable and then assign it.
486
+ old_variable = self.get_variable(varname)
487
+ old_variable.current_node = node
488
+ new_value = self._holderify(old_variable.operator_call(MesonOperator.PLUS, _unholder(addition)))
489
+ self.set_variable(varname, new_value)
490
+
491
+ def evaluate_indexing(self, node: mparser.IndexNode) -> InterpreterObject:
492
+ assert isinstance(node, mparser.IndexNode)
493
+ iobject = self.evaluate_statement(node.iobject)
494
+ if iobject is None:
495
+ raise InterpreterException('Tried to evaluate indexing on void.')
496
+ if isinstance(iobject, Disabler):
497
+ return iobject
498
+ index_holder = self.evaluate_statement(node.index)
499
+ if index_holder is None:
500
+ raise InvalidArguments('Cannot use void statement as index.')
501
+ index = _unholder(index_holder)
502
+
503
+ iobject.current_node = node
504
+ return self._holderify(iobject.operator_call(MesonOperator.INDEX, index))
505
+
506
+ def function_call(self, node: mparser.FunctionNode) -> T.Optional[InterpreterObject]:
507
+ func_name = node.func_name.value
508
+ (h_posargs, h_kwargs) = self.reduce_arguments(node.args)
509
+ (posargs, kwargs) = self._unholder_args(h_posargs, h_kwargs)
510
+ if is_disabled(posargs, kwargs) and func_name not in {'get_variable', 'set_variable', 'unset_variable', 'is_disabler'}:
511
+ return Disabler()
512
+ if func_name in self.funcs:
513
+ func = self.funcs[func_name]
514
+ func_args = posargs
515
+ if not getattr(func, 'no-args-flattening', False):
516
+ func_args = flatten(posargs)
517
+ if not getattr(func, 'no-second-level-holder-flattening', False):
518
+ func_args, kwargs = resolve_second_level_holders(func_args, kwargs)
519
+ self.current_node = node
520
+ res = func(node, func_args, kwargs)
521
+ return self._holderify(res) if res is not None else None
522
+ else:
523
+ self.unknown_function_called(func_name)
524
+ return None
525
+
526
+ def method_call(self, node: mparser.MethodNode) -> T.Optional[InterpreterObject]:
527
+ invocable = node.source_object
528
+ obj: T.Optional[InterpreterObject]
529
+ if isinstance(invocable, mparser.IdNode):
530
+ object_display_name = f'variable "{invocable.value}"'
531
+ obj = self.get_variable(invocable.value)
532
+ else:
533
+ object_display_name = invocable.__class__.__name__
534
+ obj = self.evaluate_statement(invocable)
535
+ method_name = node.name.value
536
+ (h_args, h_kwargs) = self.reduce_arguments(node.args)
537
+ (args, kwargs) = self._unholder_args(h_args, h_kwargs)
538
+ if is_disabled(args, kwargs):
539
+ return Disabler()
540
+ if not isinstance(obj, InterpreterObject):
541
+ raise InvalidArguments(f'{object_display_name} is not callable.')
542
+ # TODO: InterpreterBase **really** shouldn't be in charge of checking this
543
+ if method_name == 'extract_objects':
544
+ if isinstance(obj, ObjectHolder):
545
+ self.validate_extraction(obj.held_object)
546
+ elif not isinstance(obj, Disabler):
547
+ raise InvalidArguments(f'Invalid operation "extract_objects" on {object_display_name} of type {type(obj).__name__}')
548
+ obj.current_node = self.current_node = node
549
+ res = obj.method_call(method_name, args, kwargs)
550
+ return self._holderify(res) if res is not None else None
551
+
552
+ def _holderify(self, res: T.Union[TYPE_var, InterpreterObject]) -> InterpreterObject:
553
+ if isinstance(res, HoldableTypes):
554
+ # Always check for an exact match first.
555
+ cls = self.holder_map.get(type(res), None)
556
+ if cls is not None:
557
+ # Casts to Interpreter are required here since an assertion would
558
+ # not work for the `ast` module.
559
+ return cls(res, T.cast('Interpreter', self))
560
+ # Try the boundary types next.
561
+ for typ, cls in self.bound_holder_map.items():
562
+ if isinstance(res, typ):
563
+ return cls(res, T.cast('Interpreter', self))
564
+ raise mesonlib.MesonBugException(f'Object {res} of type {type(res).__name__} is neither in self.holder_map nor self.bound_holder_map.')
565
+ elif isinstance(res, ObjectHolder):
566
+ raise mesonlib.MesonBugException(f'Returned object {res} of type {type(res).__name__} is an object holder.')
567
+ elif isinstance(res, MesonInterpreterObject):
568
+ return res
569
+ raise mesonlib.MesonBugException(f'Unknown returned object {res} of type {type(res).__name__} in the parameters.')
570
+
571
+ def _unholder_args(self,
572
+ args: T.List[InterpreterObject],
573
+ kwargs: T.Dict[str, InterpreterObject]) -> T.Tuple[T.List[TYPE_var], TYPE_kwargs]:
574
+ return [_unholder(x) for x in args], {k: _unholder(v) for k, v in kwargs.items()}
575
+
576
+ def unknown_function_called(self, func_name: str) -> None:
577
+ raise InvalidCode(f'Unknown function "{func_name}".')
578
+
579
+ def reduce_arguments(
580
+ self,
581
+ args: mparser.ArgumentNode,
582
+ key_resolver: T.Callable[[mparser.BaseNode], str] = default_resolve_key,
583
+ duplicate_key_error: T.Optional[str] = None,
584
+ ) -> T.Tuple[
585
+ T.List[InterpreterObject],
586
+ T.Dict[str, InterpreterObject]
587
+ ]:
588
+ assert isinstance(args, mparser.ArgumentNode)
589
+ if args.incorrect_order():
590
+ raise InvalidArguments('All keyword arguments must be after positional arguments.')
591
+ self.argument_depth += 1
592
+ reduced_pos = [self.evaluate_statement(arg) for arg in args.arguments]
593
+ if any(x is None for x in reduced_pos):
594
+ raise InvalidArguments('At least one value in the arguments is void.')
595
+ reduced_kw: T.Dict[str, InterpreterObject] = {}
596
+ for key, val in args.kwargs.items():
597
+ reduced_key = key_resolver(key)
598
+ assert isinstance(val, mparser.BaseNode)
599
+ reduced_val = self.evaluate_statement(val)
600
+ if reduced_val is None:
601
+ raise InvalidArguments(f'Value of key {reduced_key} is void.')
602
+ self.current_node = key
603
+ if duplicate_key_error and reduced_key in reduced_kw:
604
+ raise InvalidArguments(duplicate_key_error.format(reduced_key))
605
+ reduced_kw[reduced_key] = reduced_val
606
+ self.argument_depth -= 1
607
+ final_kw = self.expand_default_kwargs(reduced_kw)
608
+ return reduced_pos, final_kw
609
+
610
+ def expand_default_kwargs(self, kwargs: T.Dict[str, T.Optional[InterpreterObject]]) -> T.Dict[str, T.Optional[InterpreterObject]]:
611
+ if 'kwargs' not in kwargs:
612
+ return kwargs
613
+ to_expand = _unholder(kwargs.pop('kwargs'))
614
+ if not isinstance(to_expand, dict):
615
+ raise InterpreterException('Value of "kwargs" must be dictionary.')
616
+ if 'kwargs' in to_expand:
617
+ raise InterpreterException('Kwargs argument must not contain a "kwargs" entry. Points for thinking meta, though. :P')
618
+ for k, v in to_expand.items():
619
+ if k in kwargs:
620
+ raise InterpreterException(f'Entry "{k}" defined both as a keyword argument and in a "kwarg" entry.')
621
+ kwargs[k] = self._holderify(v)
622
+ return kwargs
623
+
624
+ def assignment(self, node: mparser.AssignmentNode) -> None:
625
+ assert isinstance(node, mparser.AssignmentNode)
626
+ if self.argument_depth != 0:
627
+ raise InvalidArguments(textwrap.dedent('''\
628
+ Tried to assign values inside an argument list.
629
+ To specify a keyword argument, use : instead of =.
630
+ '''))
631
+ var_name = node.var_name.value
632
+ if not isinstance(var_name, str):
633
+ raise InvalidArguments('Tried to assign value to a non-variable.')
634
+ value = self.evaluate_statement(node.value)
635
+ # For mutable objects we need to make a copy on assignment
636
+ if isinstance(value, MutableInterpreterObject):
637
+ value = copy.deepcopy(value)
638
+ self.set_variable(var_name, value)
639
+
640
+ def set_variable(self, varname: str, variable: T.Union[TYPE_var, InterpreterObject], *, holderify: bool = False) -> None:
641
+ if variable is None:
642
+ raise InvalidCode('Can not assign void to variable.')
643
+ if holderify:
644
+ variable = self._holderify(variable)
645
+ else:
646
+ # Ensure that we are always storing ObjectHolders
647
+ if not isinstance(variable, InterpreterObject):
648
+ raise mesonlib.MesonBugException(f'set_variable in InterpreterBase called with a non InterpreterObject {variable} of type {type(variable).__name__}')
649
+ if not isinstance(varname, str):
650
+ raise InvalidCode('First argument to set_variable must be a string.')
651
+ if re.match('[_a-zA-Z][_0-9a-zA-Z]*$', varname) is None:
652
+ raise InvalidCode('Invalid variable name: ' + varname)
653
+ if varname in self.builtin:
654
+ raise InvalidCode(f'Tried to overwrite internal variable "{varname}"')
655
+ self.variables[varname] = variable
656
+
657
+ def get_variable(self, varname: str) -> InterpreterObject:
658
+ if varname in self.builtin:
659
+ return self.builtin[varname]
660
+ if varname in self.variables:
661
+ return self.variables[varname]
662
+ raise InvalidCode(f'Unknown variable "{varname}".')
663
+
664
+ def validate_extraction(self, buildtarget: mesonlib.HoldableObject) -> None:
665
+ raise InterpreterException('validate_extraction is not implemented in this context (please file a bug)')