// 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/unit_test.h"

namespace dart {

static const intptr_t kPos = Scanner::kDummyTokenIndex;


CODEGEN_TEST_GENERATE(StackmapCodegen, test) {
  Assembler assembler;
  const String& function_name = String::ZoneHandle(Symbols::New("test"));
  Class& cls = Class::ZoneHandle();
  const Script& script = Script::Handle();
  cls = Class::New(function_name, script, Scanner::kDummyTokenIndex);
  const Function& function = Function::ZoneHandle(
      Function::New(function_name, RawFunction::kRegularFunction,
                    true, false, false, false, cls, 0));
  function.set_result_type(Type::Handle(Type::DynamicType()));
  const Array& functions = Array::Handle(Array::New(1));
  functions.SetAt(0, function);
  cls.SetFunctions(functions);
  Library& lib = Library::Handle(Library::CoreLibrary());
  lib.AddClass(cls);
  ParsedFunction* parsed_function = new ParsedFunction(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->set_default_parameter_values(Array::ZoneHandle());
  parsed_function->AllocateVariables();
  bool retval;
  Isolate* isolate = Isolate::Current();
  EXPECT(isolate != NULL);
  LongJump* base = isolate->long_jump_base();
  LongJump jump;
  isolate->set_long_jump_base(&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(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);
  isolate->set_long_jump_base(base);
}
CODEGEN_TEST_RUN(StackmapCodegen, Smi::New(1))


static void NativeFunc(Dart_NativeArguments args) {
  Dart_EnterScope();
  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);
  Isolate::Current()->heap()->CollectAllGarbage();
  Dart_ExitScope();
}


static Dart_NativeFunction native_resolver(Dart_Handle name,
                                           int argument_count) {
  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);
  EXPECT(ClassFinalizer::FinalizePendingClasses());
  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("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;
  for (int i = 0; i < descriptors.Length(); ++i) {
    if (descriptors.DescriptorKind(i) == PcDescriptors::kFuncCall) {
      stackmap_table_builder->AddEntry(descriptors.PC(i) - code.EntryPoint(),
                                       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());
}

}  // namespace dart

