// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/frontend/bytecode_fingerprints.h"

#include "vm/compiler/frontend/bytecode_reader.h"
#include "vm/constants_kbc.h"
#include "vm/hash.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {
namespace kernel {

static uint32_t CombineObject(uint32_t hash, const Object& obj) {
  if (obj.IsAbstractType()) {
    return CombineHashes(hash, AbstractType::Cast(obj).Hash());
  } else if (obj.IsClass()) {
    return CombineHashes(hash, Class::Cast(obj).id());
  } else if (obj.IsFunction()) {
    return CombineHashes(
        hash, AbstractType::Handle(Function::Cast(obj).result_type()).Hash());
  } else if (obj.IsField()) {
    return CombineHashes(hash,
                         AbstractType::Handle(Field::Cast(obj).type()).Hash());
  } else {
    return CombineHashes(hash, static_cast<uint32_t>(obj.GetClassId()));
  }
}

typedef uint32_t (*Fp)(uint32_t fp,
                       const KBCInstr* instr,
                       const ObjectPool& pool,
                       int32_t value);

static uint32_t Fp___(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return fp;
}

static uint32_t Fptgt(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return CombineHashes(fp, value);
}

static uint32_t Fplit(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return CombineObject(fp, Object::Handle(pool.ObjectAt(value)));
}

static uint32_t Fpreg(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return CombineHashes(fp, value);
}

static uint32_t Fpxeg(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return CombineHashes(fp, value);
}

static uint32_t Fpnum(uint32_t fp,
                      const KBCInstr* instr,
                      const ObjectPool& pool,
                      int32_t value) {
  return CombineHashes(fp, value);
}

static uint32_t Fingerprint0(uint32_t fp,
                             const KBCInstr* instr,
                             const ObjectPool& pool,
                             Fp op1,
                             Fp op2,
                             Fp op3) {
  return fp;
}

static uint32_t FingerprintA(uint32_t fp,
                             const KBCInstr* instr,
                             const ObjectPool& pool,
                             Fp op1,
                             Fp op2,
                             Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
  return fp;
}

static uint32_t FingerprintD(uint32_t fp,
                             const KBCInstr* instr,
                             const ObjectPool& pool,
                             Fp op1,
                             Fp op2,
                             Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr));
  return fp;
}

static uint32_t FingerprintX(uint32_t fp,
                             const KBCInstr* instr,
                             const ObjectPool& pool,
                             Fp op1,
                             Fp op2,
                             Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeX(instr));
  return fp;
}

static uint32_t FingerprintT(uint32_t fp,
                             const KBCInstr* instr,
                             const ObjectPool& pool,
                             Fp op1,
                             Fp op2,
                             Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeT(instr));
  return fp;
}

static uint32_t FingerprintA_E(uint32_t fp,
                               const KBCInstr* instr,
                               const ObjectPool& pool,
                               Fp op1,
                               Fp op2,
                               Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
  fp = op2(fp, instr, pool, KernelBytecode::DecodeE(instr));
  return fp;
}

static uint32_t FingerprintA_Y(uint32_t fp,
                               const KBCInstr* instr,
                               const ObjectPool& pool,
                               Fp op1,
                               Fp op2,
                               Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
  fp = op2(fp, instr, pool, KernelBytecode::DecodeY(instr));
  return fp;
}

static uint32_t FingerprintD_F(uint32_t fp,
                               const KBCInstr* instr,
                               const ObjectPool& pool,
                               Fp op1,
                               Fp op2,
                               Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr));
  fp = op2(fp, instr, pool, KernelBytecode::DecodeF(instr));
  return fp;
}

static uint32_t FingerprintA_B_C(uint32_t fp,
                                 const KBCInstr* instr,
                                 const ObjectPool& pool,
                                 Fp op1,
                                 Fp op2,
                                 Fp op3) {
  fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr));
  fp = op2(fp, instr, pool, KernelBytecode::DecodeB(instr));
  fp = op3(fp, instr, pool, KernelBytecode::DecodeC(instr));
  return fp;
}

uint32_t BytecodeFingerprintHelper::CalculateFunctionFingerprint(
    const Function& function) {
  ASSERT(function.is_declared_in_bytecode());
  const intptr_t kHashBits = 30;
  uint32_t fp = 0;
  fp = CombineHashes(fp, String::Handle(function.UserVisibleName()).Hash());
  if (function.is_abstract()) {
    return FinalizeHash(fp, kHashBits);
  }
  if (!function.HasBytecode()) {
    kernel::BytecodeReader::ReadFunctionBytecode(Thread::Current(), function);
  }
  const Bytecode& code = Bytecode::Handle(function.bytecode());
  const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
  const KBCInstr* const start =
      reinterpret_cast<const KBCInstr*>(code.instructions());
  for (const KBCInstr* instr = start; (instr - start) < code.Size();
       instr = KernelBytecode::Next(instr)) {
    const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr);
    fp = CombineHashes(fp, opcode);
    switch (opcode) {
#define FINGERPRINT_BYTECODE(name, encoding, kind, op1, op2, op3)              \
  case KernelBytecode::k##name:                                                \
    fp = Fingerprint##encoding(fp, instr, pool, Fp##op1, Fp##op2, Fp##op3);    \
    break;
      KERNEL_BYTECODES_LIST(FINGERPRINT_BYTECODE)
#undef FINGERPRINT_BYTECODE
      default:
        UNREACHABLE();
    }
  }

  return FinalizeHash(fp, kHashBits);
}

}  // namespace kernel
}  // namespace dart

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
