# Copyright 2020 The Emscripten Authors.  All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License.  Both these licenses can be
# found in the LICENSE file.

import os
import re

from tools.shared import unsuffixed, check_call
from tools.settings import settings
from tools.utils import path_from_root, exit_with_error
from tools import config


# map an emscripten-style signature letter to a wasm2c C type
def s_to_c(s):
  if s == 'v':
    return 'void'
  elif s == 'i':
    return 'u32'
  elif s == 'j':
    return 'u64'
  elif s == 'f':
    return 'f32'
  elif s == 'd':
    return 'f64'
  else:
    exit_with_error('invalid sig element:' + str(s))


# map a wasm2c C type to an emscripten-style signature letter
def c_to_s(c):
  if c == 'WASM_RT_I32':
    return 'i'
  elif c == 'WASM_RT_I64':
    return 'j'
  elif c == 'WASM_RT_F32':
    return 'f'
  elif c == 'WASM_RT_F64':
    return 'd'
  else:
    exit_with_error('invalid wasm2c type element:' + str(c))


def get_func_types(code):
  '''
    We look for this pattern:

    static void init_func_types(void) {
      func_types[0] = wasm_rt_register_func_type(3, 1, WASM_RT_I32, WASM_RT_I32, WASM_RT_I32, WASM_RT_I32);
      func_types[1] = wasm_rt_register_func_type(1, 1, WASM_RT_I32, WASM_RT_I32);
      func_types[2] = wasm_rt_register_func_type(0, 0);
    }

    We return a map of signatures names to their index.
  '''
  init_func_types = re.search(r'static void init_func_types\(void\) {([^}]*)}', code)
  if not init_func_types:
    return {}
  ret = {}
  for entry in re.findall(r'func_types\[(\d+)\] = wasm_rt_register_func_type\((\d+), (\d+),? ?([^)]+)?\);', init_func_types[0]):
    index, params, results, types = entry
    index = int(index)
    params = int(params)
    results = int(results)
    types = types.split(', ')
    sig = ''
    for i in range(params):
      sig += c_to_s(types[i])
    if results == 0:
      sig = 'v' + sig
    else:
      assert results == 1, 'no multivalue support'
      sig = c_to_s(types[-1]) + sig
    ret[sig] = index
  return ret


def do_wasm2c(infile):
  assert settings.STANDALONE_WASM
  WASM2C = config.NODE_JS + [path_from_root('node_modules', 'wasm2c', 'wasm2c.js')]
  WASM2C_DIR = path_from_root('node_modules', 'wasm2c')
  c_file = unsuffixed(infile) + '.wasm.c'
  h_file = unsuffixed(infile) + '.wasm.h'
  cmd = WASM2C + [infile, '-o', c_file]
  check_call(cmd)
  total = '''\
/*
* This file was generated by emcc+wasm2c. To compile it, use something like
*
*   $CC FILE.c -O2 -lm -DWASM_RT_MAX_CALL_STACK_DEPTH=8000
*/
'''
  SEP = '\n/* ==================================== */\n'

  def bundle_file(total, filename):
    with open(filename) as f:
      total += '// ' + filename + '\n' + f.read() + SEP
    return total

  # hermeticize the C file, by bundling in the wasm2c/ includes
  headers = [
    (WASM2C_DIR, 'wasm-rt.h'),
    (WASM2C_DIR, 'wasm-rt-impl.h'),
    ('', h_file)
  ]
  for header in headers:
    total = bundle_file(total, os.path.join(header[0], header[1]))
  # add the wasm2c output
  with open(c_file) as read_c:
    c = read_c.read()
  total += c + SEP
  # add the wasm2c runtime
  total = bundle_file(total, os.path.join(WASM2C_DIR, 'wasm-rt-impl.c'))
  # add the support code
  support_files = ['base']
  if settings.AUTODEBUG:
    support_files.append('autodebug')
  if settings.EXPECT_MAIN:
    # TODO: add an option for direct OS access. For now, do that when building
    #       an executable with main, as opposed to a library
    support_files.append('os')
    support_files.append('main')
  else:
    support_files.append('os_sandboxed')
    support_files.append('reactor')
    # for a reactor, also append wasmbox_* API definitions
    with open(h_file, 'a') as f:
      f.write('''
// wasmbox_* API
// TODO: optional prefixing
extern void wasmbox_init(void);
''')
  for support_file in support_files:
    total = bundle_file(total, path_from_root('tools', 'wasm2c', support_file + '.c'))
  # remove #includes of the headers we bundled
  for header in headers:
    total = total.replace('#include "%s"\n' % header[1], '/* include of %s */\n' % header[1])
  # generate the necessary invokes
  invokes = []
  for sig in re.findall(r"\/\* import\: 'env' 'invoke_(\w+)' \*\/", total):
    all_func_types = get_func_types(total)

    def name(i):
      return 'a' + str(i)

    wabt_sig = sig[0] + 'i' + sig[1:]
    typed_args = [s_to_c(sig[i]) + ' ' + name(i) for i in range(1, len(sig))]
    full_typed_args = ['u32 fptr'] + typed_args
    types = [s_to_c(sig[i]) for i in range(1, len(sig))]
    args = [name(i) for i in range(1, len(sig))]
    c_func_type = s_to_c(sig[0]) + ' (*)(' + (', '.join(types) if types else 'void') + ')'
    if sig not in all_func_types:
      exit_with_error('could not find signature ' + sig + ' in function types ' + str(all_func_types))
    type_index = all_func_types[sig]

    invokes.append(r'''
IMPORT_IMPL(%(return_type)s, Z_envZ_invoke_%(sig)sZ_%(wabt_sig)s, (%(full_typed_args)s), {
  VERBOSE_LOG("invoke\n"); // waka
  u32 sp = WASM_RT_ADD_PREFIX(Z_stackSaveZ_iv)();
  if (next_setjmp >= MAX_SETJMP_STACK) {
    abort_with_message("too many nested setjmps");
  }
  u32 id = next_setjmp++;
  int result = setjmp(setjmp_stack[id]);
  %(declare_return)s
  if (result == 0) {
    %(receive)sCALL_INDIRECT(w2c___indirect_function_table, %(c_func_type)s, %(type_index)s, fptr %(args)s);
    /* if we got here, no longjmp or exception happened, we returned normally */
  } else {
    /* A longjmp or an exception took us here. */
    WASM_RT_ADD_PREFIX(Z_stackRestoreZ_vi)(sp);
    WASM_RT_ADD_PREFIX(Z_setThrewZ_vii)(1, 0);
  }
  next_setjmp--;
  %(return)s
});
''' % {
      'return_type': s_to_c(sig[0]) if sig[0] != 'v' else 'void',
      'sig': sig,
      'wabt_sig': wabt_sig,
      'full_typed_args': ', '.join(full_typed_args),
      'type_index': type_index,
      'c_func_type': c_func_type,
      'args': (', ' + ', '.join(args)) if args else '',
      'declare_return': (s_to_c(sig[0]) + ' returned_value = 0;') if sig[0] != 'v' else '',
      'receive': 'returned_value = ' if sig[0] != 'v' else '',
      'return': 'return returned_value;' if sig[0] != 'v' else ''
    })

  total += '\n'.join(invokes)

  # adjust sandboxing
  TRAP_OOB = 'TRAP(OOB)'
  assert total.count(TRAP_OOB) == 2
  if settings.WASM2C_SANDBOXING == 'full':
    pass # keep it
  elif settings.WASM2C_SANDBOXING == 'none':
    total = total.replace(TRAP_OOB, '{}')
  elif settings.WASM2C_SANDBOXING == 'mask':
    assert not settings.ALLOW_MEMORY_GROWTH
    assert (settings.INITIAL_MEMORY & (settings.INITIAL_MEMORY - 1)) == 0, 'poewr of 2'
    total = total.replace(TRAP_OOB, '{}')
    MEM_ACCESS = '[addr]'
    assert total.count(MEM_ACCESS) == 3, '2 from wasm2c, 1 from runtime'
    total = total.replace(MEM_ACCESS, '[addr & %d]' % (settings.INITIAL_MEMORY - 1))
  else:
    exit_with_error('bad sandboxing')

  # adjust prefixing: emit simple output that works with multiple libraries,
  # each compiled into its own single .c file, by adding 'static' in some places
  # TODO: decide on the proper pattern for this in an upstream discussion in
  #       wasm2c; another option would be to prefix all these things.
  for rep in [
    'uint32_t wasm_rt_register_func_type(',
    'void wasm_rt_trap(',
    'void wasm_rt_allocate_memory(',
    'uint32_t wasm_rt_grow_memory(',
    'void wasm_rt_allocate_table(',
    'jmp_buf g_jmp_buf',
    'uint32_t g_func_type_count',
    'FuncType* g_func_types',
    'uint32_t wasm_rt_call_stack_depth',
    'uint32_t g_saved_call_stack_depth',
  ]:
    # remove 'extern' from declaration
    total = total.replace('extern ' + rep, rep)
    # add 'static' to implementation
    old = total
    total = total.replace(rep, 'static ' + rep)
    assert old != total, f'did not find "{rep}"'

  # write out the final file
  with open(c_file, 'w') as out:
    out.write(total)
