// Copyright 2017 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/interpreter/setup-interpreter.h"

#include "src/handles-inl.h"
#include "src/interpreter/bytecodes.h"
#include "src/interpreter/interpreter-generator.h"
#include "src/interpreter/interpreter.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {
namespace interpreter {

namespace {
void PrintBuiltinSize(Bytecode bytecode, OperandScale operand_scale,
                      Handle<Code> code) {
  PrintF(stdout, "Ignition Handler, %s, %d\n",
         Bytecodes::ToString(bytecode, operand_scale).c_str(),
         code->instruction_size());
}
}  // namespace

// static
void SetupInterpreter::InstallBytecodeHandlers(Interpreter* interpreter) {
  DCHECK(!interpreter->IsDispatchTableInitialized());
  HandleScope scope(interpreter->isolate_);
  // Canonicalize handles, so that we can share constant pool entries pointing
  // to code targets without dereferencing their handles.
  CanonicalHandleScope canonical(interpreter->isolate_);
  Address* dispatch_table = interpreter->dispatch_table_;

  // Generate bytecode handlers for all bytecodes and scales.
  const OperandScale kOperandScales[] = {
#define VALUE(Name, _) OperandScale::k##Name,
      OPERAND_SCALE_LIST(VALUE)
#undef VALUE
  };

  for (OperandScale operand_scale : kOperandScales) {
#define GENERATE_CODE(Name, ...)                                \
  InstallBytecodeHandler(interpreter->isolate_, dispatch_table, \
                         Bytecode::k##Name, operand_scale);
    BYTECODE_LIST(GENERATE_CODE)
#undef GENERATE_CODE
  }

  // Fill unused entries will the illegal bytecode handler.
  size_t illegal_index = Interpreter::GetDispatchTableIndex(
      Bytecode::kIllegal, OperandScale::kSingle);
  for (size_t index = 0; index < Interpreter::kDispatchTableSize; ++index) {
    if (dispatch_table[index] == nullptr) {
      dispatch_table[index] = dispatch_table[illegal_index];
    }
  }

  // Generate the DeserializeLazy handlers, one for each operand scale.
  Heap* heap = interpreter->isolate_->heap();
  DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler());
  heap->SetDeserializeLazyHandler(*GenerateDeserializeLazyHandler(
      interpreter->isolate_, OperandScale::kSingle));
  DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_wide());
  heap->SetDeserializeLazyHandlerWide(*GenerateDeserializeLazyHandler(
      interpreter->isolate_, OperandScale::kDouble));
  DCHECK_EQ(Smi::kZero, heap->deserialize_lazy_handler_extra_wide());
  heap->SetDeserializeLazyHandlerExtraWide(*GenerateDeserializeLazyHandler(
      interpreter->isolate_, OperandScale::kQuadruple));

  // Initialization should have been successful.
  DCHECK(interpreter->IsDispatchTableInitialized());
}

// static
void SetupInterpreter::InstallBytecodeHandler(Isolate* isolate,
                                              Address* dispatch_table,
                                              Bytecode bytecode,
                                              OperandScale operand_scale) {
  if (!Bytecodes::BytecodeHasHandler(bytecode, operand_scale)) return;

  size_t index = Interpreter::GetDispatchTableIndex(bytecode, operand_scale);
  Handle<Code> code = GenerateBytecodeHandler(isolate, bytecode, operand_scale);
  dispatch_table[index] = code->entry();

  if (FLAG_print_builtin_size) PrintBuiltinSize(bytecode, operand_scale, code);
}

}  // namespace interpreter
}  // namespace internal
}  // namespace v8
