// Copyright (c) 2012, 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 "platform/assert.h"
#include "vm/globals.h"

#include "vm/ast.h"
#include "vm/assembler.h"
#include "vm/code_descriptors.h"
#include "vm/compiler.h"
#include "vm/dart_entry.h"
#include "vm/native_entry.h"
#include "vm/parser.h"
#include "vm/symbols.h"
#include "vm/thread.h"
#include "vm/unit_test.h"

namespace dart {

static const TokenPosition kPos = TokenPosition::kNoSource;


CODEGEN_TEST_GENERATE(StackmapCodegen, test) {
  ParsedFunction* parsed_function =
      new ParsedFunction(Thread::Current(), test->function());
  LiteralNode* l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)));
  test->node_sequence()->Add(new ReturnNode(kPos, l));
  l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
  test->node_sequence()->Add(new ReturnNode(kPos, l));
  l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)));
  test->node_sequence()->Add(new ReturnNode(kPos, l));
  parsed_function->SetNodeSequence(test->node_sequence());
  parsed_function->set_instantiator(NULL);
  parsed_function->EnsureExpressionTemp();
  test->node_sequence()->scope()->AddVariable(
      parsed_function->expression_temp_var());
  test->node_sequence()->scope()->AddVariable(
      parsed_function->current_context_var());
  parsed_function->AllocateVariables();
  bool retval;
  Isolate* isolate = Isolate::Current();
  EXPECT(isolate != NULL);
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    // Build a stackmap table and some stackmap table entries.
    const intptr_t kStackSlotCount = 11;
    StackmapTableBuilder* stackmap_table_builder = new StackmapTableBuilder();
    EXPECT(stackmap_table_builder != NULL);

    BitmapBuilder* stack_bitmap = new BitmapBuilder();
    EXPECT(stack_bitmap != NULL);
    EXPECT_EQ(0, stack_bitmap->Length());
    stack_bitmap->Set(0, true);
    EXPECT_EQ(1, stack_bitmap->Length());
    stack_bitmap->SetLength(kStackSlotCount);
    EXPECT_EQ(kStackSlotCount, stack_bitmap->Length());

    bool expectation0[kStackSlotCount] = { true };
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation0[i], stack_bitmap->Get(i));
    }
    // Add a stack map entry at pc offset 0.
    stackmap_table_builder->AddEntry(0, stack_bitmap, 0);

    stack_bitmap = new BitmapBuilder();
    EXPECT(stack_bitmap != NULL);
    EXPECT_EQ(0, stack_bitmap->Length());
    stack_bitmap->Set(0, true);
    stack_bitmap->Set(1, false);
    stack_bitmap->Set(2, true);
    EXPECT_EQ(3, stack_bitmap->Length());
    stack_bitmap->SetLength(kStackSlotCount);
    EXPECT_EQ(kStackSlotCount, stack_bitmap->Length());

    bool expectation1[kStackSlotCount] = { true, false, true };
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation1[i], stack_bitmap->Get(i));
    }
    // Add a stack map entry at pc offset 1.
    stackmap_table_builder->AddEntry(1, stack_bitmap, 0);

    stack_bitmap = new BitmapBuilder();
    EXPECT(stack_bitmap != NULL);
    EXPECT_EQ(0, stack_bitmap->Length());
    stack_bitmap->Set(0, true);
    stack_bitmap->Set(1, false);
    stack_bitmap->Set(2, true);
    stack_bitmap->SetRange(3, 5, true);
    EXPECT_EQ(6, stack_bitmap->Length());
    stack_bitmap->SetLength(kStackSlotCount);
    EXPECT_EQ(kStackSlotCount, stack_bitmap->Length());

    bool expectation2[kStackSlotCount] =
        { true, false, true, true, true, true };
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation2[i], stack_bitmap->Get(i));
    }
    // Add a stack map entry at pc offset 2.
    stackmap_table_builder->AddEntry(2, stack_bitmap, 0);

    stack_bitmap = new BitmapBuilder();
    EXPECT(stack_bitmap != NULL);
    EXPECT_EQ(0, stack_bitmap->Length());
    stack_bitmap->Set(0, true);
    stack_bitmap->Set(1, false);
    stack_bitmap->Set(2, true);
    stack_bitmap->SetRange(3, 5, true);
    stack_bitmap->SetRange(6, 9, false);
    stack_bitmap->Set(10, true);
    EXPECT_EQ(11, stack_bitmap->Length());
    stack_bitmap->SetLength(kStackSlotCount);
    EXPECT_EQ(kStackSlotCount, stack_bitmap->Length());

    bool expectation3[kStackSlotCount] =
        { true, false, true, true, true, true, false, false,
          false, false, true };
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation3[i], stack_bitmap->Get(i));
    }
    // Add a stack map entry at pc offset 3.
    stackmap_table_builder->AddEntry(3, stack_bitmap, 0);

    const Error& error =
        Error::Handle(Compiler::CompileParsedFunction(parsed_function));
    EXPECT(error.IsNull());
    const Code& code = Code::Handle(test->function().CurrentCode());

    const Array& stack_maps =
        Array::Handle(stackmap_table_builder->FinalizeStackmaps(code));
    code.set_stackmaps(stack_maps);
    const Array& stack_map_list = Array::Handle(code.stackmaps());
    EXPECT(!stack_map_list.IsNull());
    Stackmap& stack_map = Stackmap::Handle();
    EXPECT_EQ(4, stack_map_list.Length());

    // Validate the first stack map entry.
    stack_map ^= stack_map_list.At(0);
    EXPECT_EQ(kStackSlotCount, stack_map.Length());
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation0[i], stack_map.IsObject(i));
    }

    // Validate the second stack map entry.
    stack_map ^= stack_map_list.At(1);
    EXPECT_EQ(kStackSlotCount, stack_map.Length());
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation1[i], stack_map.IsObject(i));
    }

    // Validate the third stack map entry.
    stack_map ^= stack_map_list.At(2);
    EXPECT_EQ(kStackSlotCount, stack_map.Length());
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation2[i], stack_map.IsObject(i));
    }

    // Validate the fourth stack map entry.
    stack_map ^= stack_map_list.At(3);
    EXPECT_EQ(kStackSlotCount, stack_map.Length());
    for (intptr_t i = 0; i < kStackSlotCount; ++i) {
      EXPECT_EQ(expectation3[i], stack_map.IsObject(i));
    }
    retval = true;
  } else {
    retval = false;
  }
  EXPECT(retval);
}
CODEGEN_TEST_RUN(StackmapCodegen, Smi::New(1))


static void NativeFunc(Dart_NativeArguments args) {
  Dart_Handle i = Dart_GetNativeArgument(args, 0);
  Dart_Handle k = Dart_GetNativeArgument(args, 1);
  int64_t value = -1;
  EXPECT_VALID(Dart_IntegerToInt64(i, &value));
  EXPECT_EQ(10, value);
  EXPECT_VALID(Dart_IntegerToInt64(k, &value));
  EXPECT_EQ(20, value);
  {
    TransitionNativeToVM transition(Thread::Current());
    Isolate::Current()->heap()->CollectAllGarbage();
  }
}


static Dart_NativeFunction native_resolver(Dart_Handle name,
                                           int argument_count,
                                           bool* auto_setup_scope) {
  ASSERT(auto_setup_scope);
  *auto_setup_scope = false;
  return reinterpret_cast<Dart_NativeFunction>(&NativeFunc);
}


TEST_CASE(StackmapGC) {
  const char* kScriptChars =
      "class A {"
      "  static void func(var i, var k) native 'NativeFunc';"
      "  static foo() {"
      "    var i;"
      "    var s1;"
      "    var k;"
      "    var s2;"
      "    var s3;"
      "    i = 10; s1 = 'abcd'; k = 20; s2 = 'B'; s3 = 'C';"
      "    func(i, k);"
      "    return i + k; }"
      "  static int moo() {"
      "    var i = A.foo();"
      "    Expect.equals(30, i);"
      "  }\n"
      "}\n";
  // First setup the script and compile the script.
  TestCase::LoadTestScript(kScriptChars, native_resolver);
  TransitionNativeToVM transition(thread);

  EXPECT(ClassFinalizer::ProcessPendingClasses());
  const String& name = String::Handle(String::New(TestCase::url()));
  const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
  EXPECT(!lib.IsNull());
  Class& cls = Class::Handle(
      lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
  EXPECT(!cls.IsNull());

  // Now compile the two functions 'A.foo' and 'A.moo'
  String& function_moo_name = String::Handle(String::New("moo"));
  Function& function_moo =
      Function::Handle(cls.LookupStaticFunction(function_moo_name));
  EXPECT(CompilerTest::TestCompileFunction(function_moo));
  EXPECT(function_moo.HasCode());

  String& function_foo_name = String::Handle(String::New("foo"));
  Function& function_foo =
      Function::Handle(cls.LookupStaticFunction(function_foo_name));
  EXPECT(CompilerTest::TestCompileFunction(function_foo));
  EXPECT(function_foo.HasCode());

  // Build and setup a stackmap for the call to 'func' in 'A.foo' in order
  // to test the traversal of stack maps when a GC happens.
  StackmapTableBuilder* stackmap_table_builder = new StackmapTableBuilder();
  EXPECT(stackmap_table_builder != NULL);
  BitmapBuilder* stack_bitmap = new BitmapBuilder();
  EXPECT(stack_bitmap != NULL);
  stack_bitmap->Set(0, false);  // var i.
  stack_bitmap->Set(1, true);  // var s1.
  stack_bitmap->Set(2, false);  // var k.
  stack_bitmap->Set(3, true);  // var s2.
  stack_bitmap->Set(4, true);  // var s3.
  const Code& code = Code::Handle(function_foo.unoptimized_code());
  // Search for the pc of the call to 'func'.
  const PcDescriptors& descriptors =
      PcDescriptors::Handle(code.pc_descriptors());
  int call_count = 0;
  PcDescriptors::Iterator iter(descriptors,
                               RawPcDescriptors::kUnoptStaticCall);
  while (iter.MoveNext()) {
    stackmap_table_builder->AddEntry(iter.PcOffset(), stack_bitmap, 0);
    ++call_count;
  }
  // We can't easily check that we put the stackmap at the correct pc, but
  // we did if there was exactly one call seen.
  EXPECT(call_count == 1);
  const Array& stack_maps =
      Array::Handle(stackmap_table_builder->FinalizeStackmaps(code));
  code.set_stackmaps(stack_maps);

  // Now invoke 'A.moo' and it will trigger a GC when the native function
  // is called, this should then cause the stack map of function 'A.foo'
  // to be traversed and the appropriate objects visited.
  const Object& result = Object::Handle(
      DartEntry::InvokeFunction(function_foo, Object::empty_array()));
  EXPECT(!result.IsError());
}


TEST_CASE(DescriptorList_TokenPositions) {
  DescriptorList* descriptors = new DescriptorList(64);
  ASSERT(descriptors != NULL);
  const intptr_t token_positions[] = {
    kMinInt32,
    5,
    13,
    13,
    13,
    13,
    31,
    23,
    23,
    23,
    33,
    33,
    5,
    5,
    TokenPosition::kMinSourcePos,
    TokenPosition::kMaxSourcePos,
  };
  const intptr_t num_token_positions =
      sizeof(token_positions) / sizeof(token_positions[0]);

  for (intptr_t i = 0; i < num_token_positions; i++) {
    descriptors->AddDescriptor(RawPcDescriptors::kRuntimeCall, 0, 0,
                               TokenPosition(token_positions[i]), 0);
  }

  const PcDescriptors& finalized_descriptors =
      PcDescriptors::Handle(descriptors->FinalizePcDescriptors(0));

  ASSERT(!finalized_descriptors.IsNull());
  PcDescriptors::Iterator it(finalized_descriptors,
                             RawPcDescriptors::kRuntimeCall);

  intptr_t i = 0;
  while (it.MoveNext()) {
    if (token_positions[i] != it.TokenPos().value()) {
      OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
                i, token_positions[i], it.TokenPos().value());
    }
    EXPECT(token_positions[i] == it.TokenPos().value());
    i++;
  }
}


TEST_CASE(CodeSourceMap_TokenPositions) {
  const intptr_t token_positions[] = {
    kMinInt32,
    5,
    13,
    13,
    13,
    13,
    31,
    23,
    23,
    23,
    33,
    33,
    5,
    5,
    TokenPosition::kMinSourcePos,
    TokenPosition::kMaxSourcePos,
  };
  const intptr_t num_token_positions =
      sizeof(token_positions) / sizeof(token_positions[0]);

  CodeSourceMapBuilder* builder = new CodeSourceMapBuilder();
  ASSERT(builder != NULL);

  for (intptr_t i = 0; i < num_token_positions; i++) {
    builder->AddEntry(i, TokenPosition(token_positions[i]));
  }

  const CodeSourceMap& code_Source_map =
      CodeSourceMap::Handle(builder->Finalize());

  ASSERT(!code_Source_map.IsNull());
  CodeSourceMap::Iterator it(code_Source_map);

  uintptr_t i = 0;
  while (it.MoveNext()) {
    EXPECT(it.PcOffset() == i);
    if (token_positions[i] != it.TokenPos().value()) {
      OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
                i, token_positions[i], it.TokenPos().value());
    }
    EXPECT(token_positions[i] == it.TokenPos().value());
    i++;
  }
}

}  // namespace dart
