// 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(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
