/*
 * Copyright 2018 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef wasm_abi_abi_h
#define wasm_abi_abi_h

#include "asmjs/shared-constants.h"
#include "wasm-builder.h"
#include "wasm.h"

namespace wasm {

namespace ABI {

namespace wasm2js {

extern IString SCRATCH_LOAD_I32;
extern IString SCRATCH_STORE_I32;
extern IString SCRATCH_LOAD_F32;
extern IString SCRATCH_STORE_F32;
extern IString SCRATCH_LOAD_F64;
extern IString SCRATCH_STORE_F64;
extern IString MEMORY_INIT;
extern IString MEMORY_FILL;
extern IString MEMORY_COPY;
extern IString TABLE_GROW;
extern IString TABLE_FILL;
extern IString TABLE_COPY;
extern IString DATA_DROP;
extern IString ATOMIC_WAIT_I32;
extern IString ATOMIC_RMW_I64;
extern IString GET_STASHED_BITS;
extern IString TRAP;

// The wasm2js helpers let us do things that can't be done without special help,
// like read and write to scratch memory for purposes of implementing things
// like reinterpret, etc.
// The optional "specific" parameter is a specific function we want. If not
// provided, we create them all.
inline void ensureHelpers(Module* wasm, IString specific = IString()) {
  auto ensureImport = [&](Name name, Type params, Type results) {
    if (wasm->getFunctionOrNull(name)) {
      return;
    }
    if (specific.is() && name != specific) {
      return;
    }
    auto func = Builder::makeFunction(
      name, Type(Signature(params, results), NonNullable, Inexact), {});
    func->module = ENV;
    func->base = name;
    wasm->addFunction(std::move(func));
  };

  ensureImport(SCRATCH_LOAD_I32, {Type::i32}, Type::i32);
  ensureImport(SCRATCH_STORE_I32, {Type::i32, Type::i32}, Type::none);
  ensureImport(SCRATCH_LOAD_F32, {}, Type::f32);
  ensureImport(SCRATCH_STORE_F32, {Type::f32}, Type::none);
  ensureImport(SCRATCH_LOAD_F64, {}, Type::f64);
  ensureImport(SCRATCH_STORE_F64, {Type::f64}, Type::none);
  ensureImport(
    MEMORY_INIT, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::none);
  ensureImport(MEMORY_FILL, {Type::i32, Type::i32, Type::i32}, Type::none);
  ensureImport(MEMORY_COPY, {Type::i32, Type::i32, Type::i32}, Type::none);
  ensureImport(DATA_DROP, {Type::i32}, Type::none);
  ensureImport(ATOMIC_WAIT_I32,
               {Type::i32, Type::i32, Type::i32, Type::i32, Type::i32},
               Type::i32);
  ensureImport(
    ATOMIC_RMW_I64,
    {Type::i32, Type::i32, Type::i32, Type::i32, Type::i32, Type::i32},
    Type::i32);
  ensureImport(GET_STASHED_BITS, {}, Type::i32);
  ensureImport(TRAP, {}, Type::none);

  if (wasm->features.hasReferenceTypes()) {
    auto funcref = Type(HeapType::func, Nullable);
    ensureImport(TABLE_GROW, {funcref, Type::i32}, Type::none);
    ensureImport(TABLE_FILL, {Type::i32, funcref, Type::i32}, Type::none);
    ensureImport(TABLE_COPY, {Type::i32, Type::i32, Type::i32}, Type::none);
  }
}

inline bool isHelper(IString name) {
  return name == SCRATCH_LOAD_I32 || name == SCRATCH_STORE_I32 ||
         name == SCRATCH_LOAD_F32 || name == SCRATCH_STORE_F32 ||
         name == SCRATCH_LOAD_F64 || name == SCRATCH_STORE_F64 ||
         name == ATOMIC_WAIT_I32 || name == MEMORY_INIT ||
         name == MEMORY_FILL || name == MEMORY_COPY || name == TABLE_GROW ||
         name == TABLE_FILL || name == TABLE_COPY || name == DATA_DROP ||
         name == ATOMIC_RMW_I64 || name == GET_STASHED_BITS || name == TRAP;
}

} // namespace wasm2js

} // namespace ABI

} // namespace wasm

#endif // wasm_abi_abi_h
