// 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 "include/dart_api.h"
#include "platform/assert.h"
#include "vm/class_finalizer.h"
#include "vm/compiler.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/resolver.h"
#include "vm/stack_frame.h"
#include "vm/unit_test.h"
#include "vm/verifier.h"
#include "vm/zone.h"

namespace dart {

// Unit test for empty stack frame iteration.
TEST_CASE(EmptyStackFrameIteration) {
  StackFrameIterator iterator(StackFrameIterator::kValidateFrames);
  EXPECT(!iterator.HasNextFrame());
  EXPECT(iterator.NextFrame() == NULL);
  VerifyPointersVisitor::VerifyPointers();
}


// Unit test for empty dart stack frame iteration.
TEST_CASE(EmptyDartStackFrameIteration) {
  DartFrameIterator iterator;
  EXPECT(iterator.NextFrame() == NULL);
  VerifyPointersVisitor::VerifyPointers();
}


#define FUNCTION_NAME(name) StackFrame_##name
#define REGISTER_FUNCTION(name, count)                                         \
  { ""#name, FUNCTION_NAME(name), count },


void FUNCTION_NAME(StackFrame_equals)(Dart_NativeArguments args) {
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0));
  const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1));
  if (!expected.Equals(actual)) {
    OS::Print("expected: '%s' actual: '%s'\n",
        expected.ToCString(), actual.ToCString());
    FATAL("Expect_equals fails.\n");
  }
}


void FUNCTION_NAME(StackFrame_frameCount)(Dart_NativeArguments args) {
  int count = 0;
  StackFrameIterator frames(StackFrameIterator::kValidateFrames);
  while (frames.NextFrame() != NULL) {
    count += 1;  // Count the frame.
  }
  VerifyPointersVisitor::VerifyPointers();
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  arguments->SetReturn(Object::Handle(Smi::New(count)));
}


void FUNCTION_NAME(StackFrame_dartFrameCount)(Dart_NativeArguments args) {
  int count = 0;
  DartFrameIterator frames;
  while (frames.NextFrame() != NULL) {
    count += 1;  // Count the dart frame.
  }
  VerifyPointersVisitor::VerifyPointers();
  NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
  arguments->SetReturn(Object::Handle(Smi::New(count)));
}


void FUNCTION_NAME(StackFrame_validateFrame)(Dart_NativeArguments args) {
  Dart_EnterScope();
  Dart_Handle index = Dart_GetNativeArgument(args, 0);
  Dart_Handle name = Dart_GetNativeArgument(args, 1);
  const Smi& frame_index_smi = Smi::CheckedHandle(Api::UnwrapHandle(index));
  const char* expected_name =
      String::CheckedHandle(Api::UnwrapHandle(name)).ToCString();
  int frame_index = frame_index_smi.Value();
  int count = 0;
  DartFrameIterator frames;
  StackFrame* frame = frames.NextFrame();
  while (frame != NULL) {
    if (count == frame_index) {
      // Find the function corresponding to this frame and check if it
      // matches the function name passed in.
      const Function& function =
          Function::Handle(frame->LookupDartFunction());
      if (function.IsNull()) {
        FATAL("StackFrame_validateFrame fails, invalid dart frame.\n");
      }
      const char* name = function.ToFullyQualifiedCString();
      // Currently all unit tests are loaded as being part of dart:core-lib.
      Isolate* isolate = Isolate::Current();
      String& url = String::Handle(String::New(TestCase::url()));
      const Library& lib = Library::Handle(Library::LookupLibrary(url));
      ASSERT(!lib.IsNull());
      const char* lib_name = String::Handle(lib.url()).ToCString();
      intptr_t length = OS::SNPrint(NULL, 0, "%s_%s", lib_name, expected_name);
      char* full_name = isolate->current_zone()->Alloc<char>(length + 1);
      ASSERT(full_name != NULL);
      OS::SNPrint(full_name, (length + 1), "%s_%s", lib_name, expected_name);
      if (strcmp(full_name, name) != 0) {
        FATAL("StackFrame_validateFrame fails, incorrect frame.\n");
      }
      Dart_ExitScope();
      return;
    }
    count += 1;  // Count the dart frames.
    frame = frames.NextFrame();
  }
  FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n");
}


// List all native functions implemented in the vm or core boot strap dart
// libraries so that we can resolve the native function to it's entry
// point.
#define STACKFRAME_NATIVE_LIST(V)                                              \
  V(StackFrame_equals, 2)                                                      \
  V(StackFrame_frameCount, 0)                                                  \
  V(StackFrame_dartFrameCount, 0)                                              \
  V(StackFrame_validateFrame, 2)                                               \


static struct NativeEntries {
  const char* name_;
  Dart_NativeFunction function_;
  int argument_count_;
} BuiltinEntries[] = {
  STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION)
};


static Dart_NativeFunction native_lookup(Dart_Handle name,
                                         int argument_count) {
  const Object& obj = Object::Handle(Api::UnwrapHandle(name));
  ASSERT(obj.IsString());
  const char* function_name = obj.ToCString();
  ASSERT(function_name != NULL);
  int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries);
  for (int i = 0; i < num_entries; i++) {
    struct NativeEntries* entry = &(BuiltinEntries[i]);
    if (!strcmp(function_name, entry->name_) &&
        (entry->argument_count_ == argument_count)) {
      return reinterpret_cast<Dart_NativeFunction>(entry->function_);
    }
  }
  return NULL;
}


// Unit test case to verify stack frame iteration.
TEST_CASE(ValidateStackFrameIteration) {
  const char* kScriptChars =
      "class StackFrame {"
      "  static equals(var obj1, var obj2) native \"StackFrame_equals\";"
      "  static int frameCount() native \"StackFrame_frameCount\";"
      "  static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
      "  static validateFrame(int index,"
      "                       String name) native \"StackFrame_validateFrame\";"
      "} "
      "class First {"
      "  First() { }"
      "  int method1(int param) {"
      "    if (param == 1) {"
      "      param = method2(200);"
      "    } else {"
      "      param = method2(100);"
      "    }"
      "  }"
      "  int method2(int param) {"
      "    if (param == 200) {"
      "      First.staticmethod(this, param);"
      "    } else {"
      "      First.staticmethod(this, 10);"
      "    }"
      "  }"
      "  static int staticmethod(First obj, int param) {"
      "    if (param == 10) {"
      "      obj.method3(10);"
      "    } else {"
      "      obj.method3(200);"
      "    }"
      "  }"
      "  method3(int param) {"
      "    StackFrame.equals(9, StackFrame.frameCount());"
      "    StackFrame.equals(7, StackFrame.dartFrameCount());"
      "    StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
      "    StackFrame.validateFrame(1, \"First_method3\");"
      "    StackFrame.validateFrame(2, \"First_staticmethod\");"
      "    StackFrame.validateFrame(3, \"First_method2\");"
      "    StackFrame.validateFrame(4, \"First_method1\");"
      "    StackFrame.validateFrame(5, \"Second_method1\");"
      "    StackFrame.validateFrame(6, \"StackFrameTest_testMain\");"
      "  }"
      "}"
      "class Second {"
      "  Second() { }"
      "  int method1(int param) {"
      "    if (param == 1) {"
      "      param = method2(200);"
      "    } else {"
      "      First obj = new First();"
      "      param = obj.method1(1);"
      "      param = obj.method1(2);"
      "    }"
      "  }"
      "  int method2(int param) {"
      "    Second.staticmethod(this, param);"
      "  }"
      "  static int staticmethod(Second obj, int param) {"
      "    obj.method3(10);"
      "  }"
      "  method3(int param) {"
      "    StackFrame.equals(8, StackFrame.frameCount());"
      "    StackFrame.equals(6, StackFrame.dartFrameCount());"
      "    StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
      "    StackFrame.validateFrame(1, \"Second_method3\");"
      "    StackFrame.validateFrame(2, \"Second_staticmethod\");"
      "    StackFrame.validateFrame(3, \"Second_method2\");"
      "    StackFrame.validateFrame(4, \"Second_method1\");"
      "    StackFrame.validateFrame(5, \"StackFrameTest_testMain\");"
      "  }"
      "}"
      "class StackFrameTest {"
      "  static testMain() {"
      "    Second obj = new Second();"
      "    obj.method1(1);"
      "    obj.method1(2);"
      "  }"
      "}";
  Dart_Handle lib = TestCase::LoadTestScript(
      kScriptChars,
      reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
  Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest"));
  EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL));
}


// Unit test case to verify stack frame iteration.
TEST_CASE(ValidateNoSuchMethodStackFrameIteration) {
  const char* kScriptChars =
      "class StackFrame {"
      "  static equals(var obj1, var obj2) native \"StackFrame_equals\";"
      "  static int frameCount() native \"StackFrame_frameCount\";"
      "  static int dartFrameCount() native \"StackFrame_dartFrameCount\";"
      "  static validateFrame(int index,"
      "                       String name) native \"StackFrame_validateFrame\";"
      "} "
      "class StackFrame2Test {"
      "  StackFrame2Test() {}"
      "  noSuchMethod(Invocation im) {"
      "    /* We should have 8 general frames and 3 dart frames as follows:"
      "     * exit frame"
      "     * dart frame corresponding to StackFrame.frameCount"
      "     * dart frame corresponding to StackFrame2Test.noSuchMethod"
      "     * entry frame"
      "     * exit frame"
      "     * frame for instance function invocation stub calling noSuchMethod"
      "     * dart frame corresponding to StackFrame2Test.testMain"
      "     * entry frame"
      "     */"
      "    StackFrame.equals(9, StackFrame.frameCount());"
      "    StackFrame.equals(4, StackFrame.dartFrameCount());"
      "    StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
      "    StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
      "    StackFrame.validateFrame(2, \"StackFrame2Test_foo\");"
      "    StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");"
      "    return 5;"
      "  }"
      "  static testMain() {"
      "    var obj = new StackFrame2Test();"
      "    StackFrame.equals(5, obj.foo(101, 202));"
      "  }"
      "}";
  Dart_Handle lib = TestCase::LoadTestScript(
      kScriptChars,
      reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
  Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test"));
  EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL));
}

}  // namespace dart
