// Copyright (c) 2015, 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 "vm/precompiler.h"

#include "vm/compiler.h"
#include "vm/isolate.h"
#include "vm/longjump.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/resolver.h"
#include "vm/symbols.h"

namespace dart {


#define I (isolate())
#define Z (zone())


DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");


static void Jump(const Error& error) {
  Isolate::Current()->long_jump_base()->Jump(1, error);
}


RawError* Precompiler::CompileAll() {
  LongJumpScope jump;
  if (setjmp(*jump.Set()) == 0) {
    Precompiler precompiler(Thread::Current());
    precompiler.DoCompileAll();
    return Error::null();
  } else {
    Isolate* isolate = Isolate::Current();
    const Error& error = Error::Handle(isolate->object_store()->sticky_error());
    isolate->object_store()->clear_sticky_error();
    return error.raw();
  }
}


Precompiler::Precompiler(Thread* thread) :
  thread_(thread),
  zone_(thread->zone()),
  isolate_(thread->isolate()),
  changed_(false),
  function_count_(0),
  class_count_(0),
  libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
  pending_functions_(GrowableObjectArray::Handle(Z,
                                                 GrowableObjectArray::New())),
  collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())),
  sent_selectors_(GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
  error_(Error::Handle(Z)) {
}


void Precompiler::DoCompileAll() {
  // Drop all existing code so we can use the presence of code as an indicator
  // that we have already looked for the function's callees.
  ClearAllCode();

  // Start with the allocations and invocations that happen from C++.
  AddRoots();

  // TODO(rmacnak): Eagerly add field-invocation functions to all signature
  // classes so closure calls don't go through the runtime.

  // Compile newly found targets and add their callees until we reach a fixed
  // point.
  Iterate();

  CleanUp();

  if (FLAG_trace_precompiler) {
    OS::Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
              " %" Pd " dynamic selectors\n",
              function_count_,
              class_count_,
              sent_selectors_.Length());
  }

  I->set_compilation_allowed(false);
}


void Precompiler::ClearAllCode() {
  Library& lib = Library::Handle(Z);
  Class& cls = Class::Handle(Z);
  Array& functions = Array::Handle(Z);
  Function& function = Function::Handle(Z);

  for (intptr_t i = 0; i < libraries_.Length(); i++) {
    lib ^= libraries_.At(i);
    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
    while (it.HasNext()) {
      cls = it.GetNextClass();
      error_ = cls.EnsureIsFinalized(I);
      if (!error_.IsNull()) {
        Jump(error_);
      }
    }
  }

  for (intptr_t i = 0; i < libraries_.Length(); i++) {
    lib ^= libraries_.At(i);
    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
    while (it.HasNext()) {
      cls = it.GetNextClass();
      functions = cls.functions();
      for (intptr_t i = 0; i < functions.Length(); i++) {
        function ^= functions.At(i);
        function.ClearCode();
      }
    }
  }
}


void Precompiler::AddRoots() {
  // Note that <rootlibrary>.main is not a root. The appropriate main will be
  // discovered through _getMainClosure.

  AddSelector(Symbols::NoSuchMethod());

  AddSelector(Symbols::Call());  // For speed, not correctness.

  // Allocated from C++.
  static const intptr_t kExternallyAllocatedCids[] = {
    kBoolCid,
    kNullCid,

    kSmiCid,
    kMintCid,
    kBigintCid,
    kDoubleCid,

    kOneByteStringCid,
    kTwoByteStringCid,
    kExternalOneByteStringCid,
    kExternalTwoByteStringCid,

    kArrayCid,
    kImmutableArrayCid,
    kGrowableObjectArrayCid,
    kLinkedHashMapCid,

    kTypedDataUint8ClampedArrayCid,
    kTypedDataUint8ArrayCid,
    kTypedDataUint16ArrayCid,
    kTypedDataUint32ArrayCid,
    kTypedDataUint64ArrayCid,

    kTypedDataInt8ArrayCid,
    kTypedDataInt16ArrayCid,
    kTypedDataInt32ArrayCid,
    kTypedDataInt64ArrayCid,

    kExternalTypedDataUint8ArrayCid,

    kTypedDataFloat32ArrayCid,
    kTypedDataFloat64ArrayCid,

    kTypedDataFloat32x4ArrayCid,
    kTypedDataInt32x4ArrayCid,
    kTypedDataFloat64x2ArrayCid,

    kInt32x4Cid,
    kFloat32x4Cid,
    kFloat64x2Cid,

    kTypeCid,
    kTypeRefCid,
    kTypeParameterCid,
    kBoundedTypeCid,
    kLibraryPrefixCid,

    kJSRegExpCid,
    kUserTagCid,
    kStacktraceCid,
    kWeakPropertyCid,
    kCapabilityCid,
    ReceivePort::kClassId,
    SendPort::kClassId,

    kIllegalCid
  };

  Class& cls = Class::Handle(Z);
  for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) {
    cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]);
    AddClass(cls);
  }

  static const struct {
    const char* library_;
    const char* class_;
    const char* function_;
  } kExternallyCalled[] = {
    { "dart:_builtin", "::", "_getMainClosure" },
    { "dart:_builtin", "::", "_getPrintClosure" },
    { "dart:_builtin", "::", "_getUriBaseClosure" },
    { "dart:_builtin", "::", "_resolveUri" },
    { "dart:_builtin", "::", "_setWorkingDirectory" },
    { "dart:async", "::", "_setScheduleImmediateClosure" },
    { "dart:core", "_InternalError", "_InternalError." },
    { "dart:core", "_InvocationMirror", "_allocateInvocationMirror" },
    { "dart:io", "::", "_makeUint8ListView" },
    { "dart:io", "::", "_makeDatagram" },
    { "dart:io", "CertificateException", "CertificateException." },
    { "dart:io", "HandshakeException", "HandshakeException." },
    { "dart:io", "TlsException", "TlsException." },
    { "dart:io", "X509Certificate", "X509Certificate." },
    { "dart:io", "_ExternalBuffer", "set:data" },
    { "dart:io", "_Platform", "set:_nativeScript" },
    { "dart:io", "_ProcessStartStatus", "set:_errorCode" },
    { "dart:io", "_ProcessStartStatus", "set:_errorMessage" },
    { "dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE" },
    { "dart:io", "_SecureFilterImpl", "get:SIZE" },
    { "dart:isolate", "::", "_getIsolateScheduleImmediateClosure" },
    { "dart:isolate", "::", "_startMainIsolate" },
    { "dart:isolate", "_RawReceivePortImpl", "_handleMessage" },
    { "dart:isolate", "_RawReceivePortImpl", "_lookupHandler" },
    { "dart:vmservice", "::", "_registerIsolate" },
    { "dart:vmservice", "::", "boot" },
    { "dart:vmservice_io", "::", "_addResource" },
    { "dart:vmservice_io", "::", "main" },

    // Cf. Exceptions::Create
    { "dart:core", "RangeError", "RangeError." },
    { "dart:core", "RangeError", "RangeError.range" },
    { "dart:core", "ArgumentError", "ArgumentError." },
    { "dart:core", "NoSuchMethodError", "NoSuchMethodError._withType" },
    { "dart:core", "FormatException", "FormatException." },
    { "dart:core", "UnsupportedError", "UnsupportedError." },
    { "dart:core", "NullThrownError", "NullThrownError." },
    { "dart:isolate", "IsolateSpawnException", "IsolateSpawnException." },
    { "dart:isolate", "_IsolateUnhandledException",
                      "_IsolateUnhandledException." },
    { "dart:core", "_JavascriptIntegerOverflowError",
                   "_JavascriptIntegerOverflowError." },
    { "dart:core", "_JavascriptCompatibilityError",
                   "_JavascriptCompatibilityError." },
    { "dart:core", "AssertionError", "AssertionError." },
    { "dart:core", "_CastError", "_CastError._create" },
    { "dart:core", "_TypeError", "_TypeError._create" },
    { "dart:core", "FallThroughError", "FallThroughError._create" },
    { "dart:core", "AbstractClassInstantiationError",
                   "AbstractClassInstantiationError._create" },
    { "dart:core", "CyclicInitializationError",
                   "CyclicInitializationError." },
    { "dart:core", "StackOverflowError", "StackOverflowError." },
    { "dart:core", "OutOfMemoryError", "OutOfMemoryError." },
    { NULL, NULL, NULL }
  };

  Library& lib = Library::Handle(Z);
  Function& func = Function::Handle(Z);
  String& library_name = String::Handle(Z);
  String& class_name = String::Handle(Z);
  String& function_name = String::Handle(Z);
  for (intptr_t i = 0; kExternallyCalled[i].library_ != NULL; i++) {
    library_name = Symbols::New(kExternallyCalled[i].library_);
    class_name = Symbols::New(kExternallyCalled[i].class_);
    function_name = Symbols::New(kExternallyCalled[i].function_);

    lib = Library::LookupLibrary(library_name);
    if (lib.IsNull()) {
      if (FLAG_trace_precompiler) {
        OS::Print("WARNING: Missing %s\n", kExternallyCalled[i].library_);
      }
      continue;
    }

    if (class_name.raw() == Symbols::TopLevel().raw()) {
      func = lib.LookupFunctionAllowPrivate(function_name);
    } else {
      cls = lib.LookupClassAllowPrivate(class_name);
      if (cls.IsNull()) {
        if (FLAG_trace_precompiler) {
          OS::Print("WARNING: Missing %s %s\n",
                    kExternallyCalled[i].library_,
                    kExternallyCalled[i].class_);
        }
        continue;
      }

      ASSERT(!cls.IsNull());
      func = cls.LookupFunctionAllowPrivate(function_name);
    }

    if (func.IsNull()) {
      if (FLAG_trace_precompiler) {
        OS::Print("WARNING: Missing %s %s %s\n",
                  kExternallyCalled[i].library_,
                  kExternallyCalled[i].class_,
                  kExternallyCalled[i].function_);
      }
      continue;
    }

    AddFunction(func);
  }
}


void Precompiler::Iterate() {
  Function& function = Function::Handle(Z);

  while (changed_) {
    changed_ = false;

    while (pending_functions_.Length() > 0) {
      function ^= pending_functions_.RemoveLast();
      ProcessFunction(function);
    }

    CheckForNewDynamicFunctions();

    // Drain collected_closures last because additions to this list come from
    // outside the Precompiler and so do not flip our changed_ flag.
    while (collected_closures_.Length() > 0) {
      function ^= collected_closures_.RemoveLast();
      ProcessFunction(function);
    }
  }
}


void Precompiler::CleanUp() {
  I->set_collected_closures(GrowableObjectArray::Handle(Z));

  // TODO(rmacnak): Drop functions without code, classes without functions, etc.
}


void Precompiler::ProcessFunction(const Function& function) {
  if (!function.HasCode()) {
    function_count_++;

    if (FLAG_trace_precompiler) {
      OS::Print("Precompiling %" Pd " %s (%" Pd ", %s)\n",
                function_count_,
                function.ToLibNamePrefixedQualifiedCString(),
                function.token_pos(),
                Function::KindToCString(function.kind()));
    }

    ASSERT(!function.is_abstract());
    ASSERT(!function.IsRedirectingFactory());

    error_ = Compiler::CompileFunction(thread_, function);
    if (!error_.IsNull()) {
      Jump(error_);
    }
  }

  ASSERT(function.HasCode());
  AddCalleesOf(function);
}


void Precompiler::AddCalleesOf(const Function& function) {
  ASSERT(function.HasCode());

  const Code& code = Code::Handle(Z, function.CurrentCode());

  const Array& table = Array::Handle(Z, code.static_calls_target_table());
  Object& entry = Object::Handle(Z);
  Function& target = Function::Handle(Z);
  for (intptr_t i = 0; i < table.Length(); i++) {
    entry = table.At(i);
    if (entry.IsFunction()) {
      target ^= table.At(i);
      AddFunction(target);
    }
  }

#if defined(TARGET_ARCH_IA32)
  FATAL("Callee scanning unimplemented for IA32");
#endif

  const ObjectPool& pool = ObjectPool::Handle(Z, code.GetObjectPool());
  ICData& call_site = ICData::Handle(Z);
  String& selector = String::Handle(Z);
  Field& field = Field::Handle(Z);
  Class& cls = Class::Handle(Z);
  for (intptr_t i = 0; i < pool.Length(); i++) {
    if (pool.InfoAt(i) == ObjectPool::kTaggedObject) {
      entry = pool.ObjectAt(i);
      if (entry.IsICData()) {
        call_site ^= entry.raw();
        if (call_site.NumberOfChecks() == 1) {
          // Probably a static call.
          target = call_site.GetTargetAt(0);
          AddFunction(target);
          if (!target.is_static()) {
            // Super call (should not enqueue selector) or dynamic call with a
            // CHA prediction (should enqueue selector).
            selector = call_site.target_name();
            AddSelector(selector);
          }
        } else {
          // A dynamic call.
          selector = call_site.target_name();
          AddSelector(selector);
        }
      } else if (entry.IsField()) {
        // Potential need for field initializer.
        field ^= entry.raw();
        AddField(field);
      } else if (entry.IsInstance()) {
        // Potential const object.
        cls = entry.clazz();
        AddClass(cls);
      }
    }
  }
}


void Precompiler::AddField(const Field& field) {
  if (field.is_static()) {
    // Potential const object. Uninitialized field will harmlessly do a
    // redundant add of the Null class.
    const Object& value = Object::Handle(Z, field.value());
    const Class& cls = Class::Handle(Z, value.clazz());
    AddClass(cls);

    if (field.has_initializer()) {
      if (field.initializer() != Function::null()) return;

      if (FLAG_trace_precompiler) {
        OS::Print("Precompiling initializer for %s\n", field.ToCString());
      }
      Compiler::CompileStaticInitializer(field);

      const Function& function = Function::Handle(Z, field.initializer());
      AddCalleesOf(function);
    }
  }
}


void Precompiler::AddFunction(const Function& function) {
  if (function.HasCode()) return;

  pending_functions_.Add(function);
  changed_ = true;
}


bool Precompiler::IsSent(const String& selector) {
  ASSERT(selector.IsSymbol());

  // TODO(rmacnak): Use a proper set.
  for (intptr_t i = 0; i < sent_selectors_.Length(); i++) {
    if (sent_selectors_.At(i) == selector.raw()) {
      return true;
    }
  }

  return false;
}


void Precompiler::AddSelector(const String& selector) {
  if (!IsSent(selector)) {
    if (FLAG_trace_precompiler) {
      OS::Print("Enqueueing selector %" Pd " %s\n",
                sent_selectors_.Length(),
                selector.ToCString());
    }

    sent_selectors_.Add(selector);
    changed_ = true;

    if (!Field::IsGetterName(selector) &&
        !Field::IsSetterName(selector)) {
      // Regular method may be call-through-getter.
      // TODO(rmacnak): Do not create the symbol if it does not already exist.
      String& getter = String::Handle(Field::GetterName(selector));
      getter = Symbols::New(getter);
      AddSelector(getter);
    }
  }
}


void Precompiler::AddClass(const Class& cls) {
  if (cls.is_allocated()) return;

  class_count_++;
  cls.set_is_allocated();
  changed_ = true;

  if (FLAG_trace_precompiler) {
    OS::Print("Allocation %" Pd " %s\n", class_count_, cls.ToCString());
  }

  const Class& superclass = Class::Handle(cls.SuperClass());
  if (!superclass.IsNull()) {
    AddClass(superclass);
  }
}


void Precompiler::CheckForNewDynamicFunctions() {
  Library& lib = Library::Handle(Z);
  Class& cls = Class::Handle(Z);
  Array& functions = Array::Handle(Z);
  Function& function = Function::Handle(Z);
  String& selector = String::Handle(Z);

  for (intptr_t i = 0; i < libraries_.Length(); i++) {
    lib ^= libraries_.At(i);
    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
    while (it.HasNext()) {
      cls = it.GetNextClass();

      if (!cls.is_allocated()) {
        bool has_compiled_constructor = false;
        if (cls.allocation_stub() != Code::null()) {
          // Regular objects.
          has_compiled_constructor = true;
        } else if (cls.is_synthesized_class()) {
          // Enums.
          has_compiled_constructor = true;
        } else {
          // Objects only allocated via const constructors, and not stored in a
          // static field or code.
          // E.g. A in
          //   class A {
          //     const A();
          //     toString() => "Don't drop me!";
          //   }
          //   class B {
          //     const a = const A();
          //     const B();
          //     static const theB = const B();
          //   }
          //   main() => print(B.theB.a);
          functions = cls.functions();
          for (intptr_t k = 0; k < functions.Length(); k++) {
            function ^= functions.At(k);
            if (function.IsGenerativeConstructor() &&
                function.HasCode()) {
              has_compiled_constructor = true;
              break;
            }
          }
        }
        if (!has_compiled_constructor) {
          continue;
        }
        AddClass(cls);
      }

      functions = cls.functions();
      for (intptr_t k = 0; k < functions.Length(); k++) {
        function ^= functions.At(k);

        if (function.is_static() || function.is_abstract()) continue;

        // Don't bail out early if there is already code because we may discover
        // the corresponding getter selector is sent in some later iteration.
        // if (function.HasCode()) continue;

        selector = function.name();
        if (IsSent(selector)) {
          AddFunction(function);
        }

        if (function.kind() == RawFunction::kRegularFunction &&
            !Field::IsGetterName(selector) &&
            !Field::IsSetterName(selector)) {
          // TODO(rmacnak): Do not create the symbol if it does not already
          // exist.
          selector = Field::GetterName(selector);
          selector = Symbols::New(selector);
          if (IsSent(selector)) {
            function = function.ImplicitClosureFunction();
            AddFunction(function);
          }
        }
      }
    }
  }
}

}  // namespace dart
