native_impl.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright (C) 2024 Midokura Japan KK. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #define __STDC_WANT_LIB_EXT1__ 1
  6. #include <inttypes.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include "wasm_export.h"
  10. #include "bh_platform.h"
  11. /*
  12. * this "nest" var has two purposes:
  13. * - prevent tail-call optimization
  14. * - detect possible resource leak
  15. */
  16. unsigned int nest = 0;
  17. ptrdiff_t prev_diff = 0;
  18. uint32_t
  19. call_indirect(wasm_exec_env_t exec_env, uint32_t funcidx, uint32_t x)
  20. {
  21. uint32_t argv[1] = {
  22. x,
  23. };
  24. uint32_t argc = 1;
  25. if (!wasm_runtime_call_indirect(exec_env, funcidx, argc, argv)) {
  26. /* failed */
  27. return 0;
  28. }
  29. return argv[0];
  30. }
  31. uint32_t
  32. host_consume_stack_and_call_indirect(wasm_exec_env_t exec_env, uint32_t funcidx,
  33. uint32_t x, uint32_t stack)
  34. {
  35. void *boundary = os_thread_get_stack_boundary();
  36. void *fp = __builtin_frame_address(0);
  37. ptrdiff_t diff = fp - boundary;
  38. /*
  39. * because this function performs recursive calls depending on
  40. * the user input, we don't have an apriori knowledge how much stack
  41. * we need. perform the overflow check on each iteration.
  42. */
  43. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  44. return 0;
  45. }
  46. if (diff > stack) {
  47. prev_diff = diff;
  48. nest++;
  49. uint32_t ret =
  50. host_consume_stack_and_call_indirect(exec_env, funcidx, x, stack);
  51. nest--;
  52. return ret;
  53. }
  54. return call_indirect(exec_env, funcidx, x);
  55. }
  56. __attribute__((noinline)) static uint32_t
  57. consume_stack1(wasm_exec_env_t exec_env, void *base, uint32_t stack)
  58. #if defined(__clang__)
  59. __attribute__((disable_tail_calls))
  60. #endif
  61. {
  62. void *fp = __builtin_frame_address(0);
  63. ptrdiff_t diff = (unsigned char *)base - (unsigned char *)fp;
  64. assert(diff > 0);
  65. if (diff > stack) {
  66. return diff;
  67. }
  68. return consume_stack1(exec_env, base, stack);
  69. }
  70. uint32_t
  71. host_consume_stack(wasm_exec_env_t exec_env, uint32_t stack)
  72. {
  73. /*
  74. * this function consumes a bit more than "stack" bytes.
  75. */
  76. if (!wasm_runtime_detect_native_stack_overflow_size(exec_env, 64 + stack)) {
  77. return 0;
  78. }
  79. void *base = __builtin_frame_address(0);
  80. return consume_stack1(exec_env, base, stack);
  81. }