// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/wasm/function-body-decoder.h"

#include "src/flags/flags.h"
#include "src/handles/handles.h"
#include "src/objects/objects-inl.h"
#include "src/utils/ostreams.h"
#include "src/wasm/decoder.h"
#include "src/wasm/function-body-decoder-impl.h"
#include "src/wasm/wasm-limits.h"
#include "src/wasm/wasm-linkage.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-opcodes-inl.h"

namespace v8 {
namespace internal {
namespace wasm {

bool DecodeLocalDecls(const WasmFeatures& enabled, BodyLocalDecls* decls,
                      const byte* start, const byte* end) {
  WasmFeatures no_features = WasmFeatures::None();
  Zone* zone = decls->type_list.get_allocator().zone();
  WasmDecoder<Decoder::kFullValidation> decoder(
      zone, nullptr, enabled, &no_features, nullptr, start, end, 0);
  uint32_t length;
  if (!decoder.DecodeLocals(decoder.pc(), &length, 0)) {
    decls->encoded_size = 0;
    return false;
  }
  DCHECK(decoder.ok());
  decls->encoded_size = length;
  // Copy the decoded locals types into {decls->type_list}.
  DCHECK(decls->type_list.empty());
  decls->type_list = std::move(decoder.local_types_);
  return true;
}

BytecodeIterator::BytecodeIterator(const byte* start, const byte* end,
                                   BodyLocalDecls* decls)
    : Decoder(start, end) {
  if (decls != nullptr) {
    if (DecodeLocalDecls(WasmFeatures::All(), decls, start, end)) {
      pc_ += decls->encoded_size;
      if (pc_ > end_) pc_ = end_;
    }
  }
}

DecodeResult VerifyWasmCode(AccountingAllocator* allocator,
                            const WasmFeatures& enabled,
                            const WasmModule* module, WasmFeatures* detected,
                            const FunctionBody& body) {
  Zone zone(allocator, ZONE_NAME);
  WasmFullDecoder<Decoder::kFullValidation, EmptyInterface> decoder(
      &zone, module, enabled, detected, body);
  decoder.Decode();
  return decoder.toResult(nullptr);
}

unsigned OpcodeLength(const byte* pc, const byte* end) {
  WasmFeatures no_features = WasmFeatures::None();
  Zone* no_zone = nullptr;
  WasmModule* no_module = nullptr;
  FunctionSig* no_sig = nullptr;
  WasmDecoder<Decoder::kNoValidation> decoder(no_zone, no_module, no_features,
                                              &no_features, no_sig, pc, end, 0);
  return WasmDecoder<Decoder::kNoValidation>::OpcodeLength(&decoder, pc);
}

std::pair<uint32_t, uint32_t> StackEffect(const WasmModule* module,
                                          const FunctionSig* sig,
                                          const byte* pc, const byte* end) {
  WasmFeatures unused_detected_features = WasmFeatures::None();
  Zone* no_zone = nullptr;
  WasmDecoder<Decoder::kNoValidation> decoder(
      no_zone, module, WasmFeatures::All(), &unused_detected_features, sig, pc,
      end);
  return decoder.StackEffect(pc);
}

void PrintRawWasmCode(const byte* start, const byte* end) {
  AccountingAllocator allocator;
  PrintRawWasmCode(&allocator, FunctionBody{nullptr, 0, start, end}, nullptr,
                   kPrintLocals);
}

namespace {
const char* RawOpcodeName(WasmOpcode opcode) {
  switch (opcode) {
#define DECLARE_NAME_CASE(name, opcode, sig) \
  case kExpr##name:                          \
    return "kExpr" #name;
    FOREACH_OPCODE(DECLARE_NAME_CASE)
#undef DECLARE_NAME_CASE
    default:
      break;
  }
  return "Unknown";
}
const char* PrefixName(WasmOpcode prefix_opcode) {
  switch (prefix_opcode) {
#define DECLARE_PREFIX_CASE(name, opcode) \
  case k##name##Prefix:                   \
    return "k" #name "Prefix";
    FOREACH_PREFIX(DECLARE_PREFIX_CASE)
#undef DECLARE_PREFIX_CASE
    default:
      return "Unknown prefix";
  }
}
}  // namespace

bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
                      const WasmModule* module, PrintLocals print_locals) {
  StdoutStream os;
  return PrintRawWasmCode(allocator, body, module, print_locals, os);
}

bool PrintRawWasmCode(AccountingAllocator* allocator, const FunctionBody& body,
                      const WasmModule* module, PrintLocals print_locals,
                      std::ostream& os, std::vector<int>* line_numbers) {
  Zone zone(allocator, ZONE_NAME);
  WasmFeatures unused_detected_features = WasmFeatures::None();
  WasmDecoder<Decoder::kNoValidation> decoder(
      &zone, module, WasmFeatures::All(), &unused_detected_features, body.sig,
      body.start, body.end);
  int line_nr = 0;
  constexpr int kNoByteCode = -1;

  // Print the function signature.
  if (body.sig) {
    os << "// signature: " << *body.sig << std::endl;
    if (line_numbers) line_numbers->push_back(kNoByteCode);
    ++line_nr;
  }

  // Print the local declarations.
  BodyLocalDecls decls(&zone);
  BytecodeIterator i(body.start, body.end, &decls);
  if (body.start != i.pc() && print_locals == kPrintLocals) {
    os << "// locals:";
    if (!decls.type_list.empty()) {
      ValueType type = decls.type_list[0];
      uint32_t count = 0;
      for (size_t pos = 0; pos < decls.type_list.size(); ++pos) {
        if (decls.type_list[pos] == type) {
          ++count;
        } else {
          os << " " << count << " " << type.name();
          type = decls.type_list[pos];
          count = 1;
        }
      }
      os << " " << count << " " << type.name();
    }
    os << std::endl;
    if (line_numbers) line_numbers->push_back(kNoByteCode);
    ++line_nr;

    for (const byte* locals = body.start; locals < i.pc(); locals++) {
      os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
    }
    os << std::endl;
    if (line_numbers) line_numbers->push_back(kNoByteCode);
    ++line_nr;
  }

  os << "// body:" << std::endl;
  if (line_numbers) line_numbers->push_back(kNoByteCode);
  ++line_nr;
  unsigned control_depth = 0;
  for (; i.has_next(); i.next()) {
    unsigned length =
        WasmDecoder<Decoder::kNoValidation>::OpcodeLength(&decoder, i.pc());

    unsigned offset = 1;
    WasmOpcode opcode = i.current();
    WasmOpcode prefix = kExprUnreachable;
    bool has_prefix = WasmOpcodes::IsPrefixOpcode(opcode);
    if (has_prefix) {
      prefix = i.current();
      opcode = i.prefixed_opcode();
      offset = 2;
    }
    if (line_numbers) line_numbers->push_back(i.position());
    if (opcode == kExprElse || opcode == kExprCatch) {
      control_depth--;
    }

    int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;

    // 64 whitespaces
    const char* padding =
        "                                                                ";
    os.write(padding, num_whitespaces);

    if (has_prefix) {
      os << PrefixName(prefix) << ", ";
    }

    os << RawOpcodeName(opcode) << ",";

    if (opcode == kExprLoop || opcode == kExprIf || opcode == kExprBlock ||
        opcode == kExprTry) {
      DCHECK_EQ(2, length);

      // TODO(7748) Update this for gc and ref types if needed
      switch (i.pc()[1]) {
#define CASE_LOCAL_TYPE(local_name, type_name) \
  case k##local_name##Code:                    \
    os << " kWasm" #type_name ",";             \
    break;

        CASE_LOCAL_TYPE(I32, I32)
        CASE_LOCAL_TYPE(I64, I64)
        CASE_LOCAL_TYPE(F32, F32)
        CASE_LOCAL_TYPE(F64, F64)
        CASE_LOCAL_TYPE(S128, S128)
        CASE_LOCAL_TYPE(Void, Stmt)
        default:
          os << " 0x" << AsHex(i.pc()[1], 2) << ",";
          break;
      }
#undef CASE_LOCAL_TYPE
    } else {
      for (unsigned j = offset; j < length; ++j) {
        os << " 0x" << AsHex(i.pc()[j], 2) << ",";
      }
    }

    os << "  // " << WasmOpcodes::OpcodeName(opcode);

    switch (opcode) {
      case kExprElse:
      case kExprCatch:
        os << " @" << i.pc_offset();
        control_depth++;
        break;
      case kExprLoop:
      case kExprIf:
      case kExprBlock:
      case kExprTry: {
        BlockTypeImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(), &i,
                                                       i.pc() + 1);
        os << " @" << i.pc_offset();
        if (decoder.Complete(imm)) {
          for (uint32_t i = 0; i < imm.out_arity(); i++) {
            os << " " << imm.out_type(i).name();
          }
        }
        control_depth++;
        break;
      }
      case kExprEnd:
        os << " @" << i.pc_offset();
        control_depth--;
        break;
      case kExprBr: {
        BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
        os << " depth=" << imm.depth;
        break;
      }
      case kExprBrIf: {
        BranchDepthImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
        os << " depth=" << imm.depth;
        break;
      }
      case kExprBrTable: {
        BranchTableImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
        os << " entries=" << imm.table_count;
        break;
      }
      case kExprCallIndirect: {
        CallIndirectImmediate<Decoder::kNoValidation> imm(WasmFeatures::All(),
                                                          &i, i.pc() + 1);
        os << " sig #" << imm.sig_index;
        if (decoder.Complete(imm)) {
          os << ": " << *imm.sig;
        }
        break;
      }
      case kExprCallFunction: {
        CallFunctionImmediate<Decoder::kNoValidation> imm(&i, i.pc() + 1);
        os << " function #" << imm.index;
        if (decoder.Complete(imm)) {
          os << ": " << *imm.sig;
        }
        break;
      }
      default:
        break;
    }
    os << std::endl;
    ++line_nr;
  }
  DCHECK(!line_numbers || line_numbers->size() == static_cast<size_t>(line_nr));

  return decoder.ok();
}

BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
                                           const byte* start, const byte* end) {
  WasmFeatures no_features = WasmFeatures::None();
  WasmDecoder<Decoder::kFullValidation> decoder(
      zone, nullptr, no_features, &no_features, nullptr, start, end, 0);
  return WasmDecoder<Decoder::kFullValidation>::AnalyzeLoopAssignment(
      &decoder, start, static_cast<uint32_t>(num_locals), zone);
}

}  // namespace wasm
}  // namespace internal
}  // namespace v8
