<commit_before>//===----- ModuleInterfaceBuilder.cpp - Compiles .swiftinterface files ----===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "textual-module-interface"

#include "swift/Frontend/ModuleInterfaceLoader.h"
#include "ModuleInterfaceBuilder.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/FileSystem.h"
#include "swift/AST/Module.h"
#include "swift/Basic/Defer.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/ModuleInterfaceSupport.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/Serialization/SerializationOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/xxhash.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/LockFileManager.h"

using namespace swift;
using FileDependency = SerializationOptions::FileDependency;
namespace path = llvm::sys::path;

/// If the file dependency in \p FullDepPath is inside the \p Base directory,
/// this returns its path relative to \p Base. Otherwise it returns None.
static Optional<StringRef> getRelativeDepPath(StringRef DepPath,
                                              StringRef Base) {
  // If Base is the root directory, or DepPath does not start with Base, bail.
  if (Base.size() <= 1 || !DepPath.startswith(Base)) {
    return None;
  }

  assert(DepPath.size() > Base.size() &&
      "should never depend on a directory");

  // Is the DepName something like ${Base}/foo.h"?
  if (path::is_separator(DepPath[Base.size()]))
    return DepPath.substr(Base.size() + 1);

  // Is the DepName something like "${Base}foo.h", where Base
  // itself contains a trailing slash?
  if (path::is_separator(Base.back()))
    return DepPath.substr(Base.size());

  // We have something next to Base, like "Base.h", that's somehow
  // become a dependency.
  return None;
}

bool ModuleInterfaceBuilder::collectDepsForSerialization(
    CompilerInstance &SubInstance, SmallVectorImpl<FileDependency> &Deps,
    bool IsHashBased) {
  llvm::vfs::FileSystem &fs = *sourceMgr.getFileSystem();

  auto &Opts = SubInstance.getASTContext().SearchPathOpts;
  SmallString<128> SDKPath(Opts.SDKPath);
  path::native(SDKPath);
  SmallString<128> ResourcePath(Opts.RuntimeResourcePath);
  path::native(ResourcePath);

  auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
  SmallVector<StringRef, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
  InitialDepNames.push_back(interfacePath);
  InitialDepNames.insert(InitialDepNames.end(),
                         extraDependencies.begin(), extraDependencies.end());
  SmallString<128> Scratch;

  for (const auto &InitialDepName : InitialDepNames) {
    path::native(InitialDepName, Scratch);
    StringRef DepName = Scratch.str();

    assert(moduleCachePath.empty() || !DepName.startswith(moduleCachePath));

    // Serialize the paths of dependencies in the SDK relative to it.
    Optional<StringRef> SDKRelativePath = getRelativeDepPath(DepName, SDKPath);
    StringRef DepNameToStore = SDKRelativePath.getValueOr(DepName);
    bool IsSDKRelative = SDKRelativePath.hasValue();

    // Forwarding modules add the underlying prebuilt module to their
    // dependency list -- don't serialize that.
    if (!prebuiltCachePath.empty() && DepName.startswith(prebuiltCachePath))
      continue;

    if (dependencyTracker) {
      dependencyTracker->addDependency(DepName, /*isSystem*/IsSDKRelative);
    }

    // Don't serialize compiler-relative deps so the cache is relocatable.
    if (DepName.startswith(ResourcePath))
      continue;

    auto Status = fs.status(DepName);
    if (!Status)
      return true;

    /// Lazily load the dependency buffer if we need it. If we're not
    /// dealing with a hash-based dependencies, and if the dependency is
    /// not a .swiftmodule, we can avoid opening the buffer.
    std::unique_ptr<llvm::MemoryBuffer> DepBuf = nullptr;
    auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
      if (DepBuf) return DepBuf.get();
      if (auto Buf = fs.getBufferForFile(DepName, /*FileSize=*/-1,
                                         /*RequiresNullTerminator=*/false)) {
        DepBuf = std::move(Buf.get());
        return DepBuf.get();
      }
      return nullptr;
    };

    if (IsHashBased) {
      auto buf = getDepBuf();
      if (!buf) return true;
      uint64_t hash = xxHash64(buf->getBuffer());
      Deps.push_back(
                     FileDependency::hashBased(DepNameToStore, IsSDKRelative,
                                               Status->getSize(), hash));
    } else {
      uint64_t mtime =
      Status->getLastModificationTime().time_since_epoch().count();
      Deps.push_back(
                     FileDependency::modTimeBased(DepNameToStore, IsSDKRelative,
                                                  Status->getSize(), mtime));
    }
  }
  return false;
}

bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
    StringRef OutPath, bool ShouldSerializeDeps,
    std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
    ArrayRef<std::string> CompiledCandidates) {

  auto outerPrettyStackState = llvm::SavePrettyStackState();

  bool SubError = false;
  bool RunSuccess = llvm::CrashRecoveryContext().RunSafelyOnThread([&] {
    // Pretend we're on the original thread for pretty-stack-trace purposes.
    auto savedInnerPrettyStackState = llvm::SavePrettyStackState();
    llvm::RestorePrettyStackState(outerPrettyStackState);
    SWIFT_DEFER {
      llvm::RestorePrettyStackState(savedInnerPrettyStackState);
    };

    SubError = (bool)subASTDelegate.runInSubCompilerInstance(moduleName,
                                                             interfacePath,
                                                             OutPath,
                                                             diagnosticLoc,
                                           [&](SubCompilerInstanceInfo &info) {
    auto &SubInstance = *info.Instance;
    auto subInvocation = SubInstance.getInvocation();
    // Try building forwarding module first. If succeed, return.
    if (static_cast<ModuleInterfaceLoader*>(SubInstance.getASTContext()
        .getModuleInterfaceLoader())->tryEmitForwardingModule(moduleName,
                                                              interfacePath,
                                                  CompiledCandidates, OutPath)) {
      return std::error_code();
    }
    FrontendOptions &FEOpts = subInvocation.getFrontendOptions();
    bool isTypeChecking =
        (FEOpts.RequestedAction == FrontendOptions::ActionType::Typecheck);
    const auto &InputInfo = FEOpts.InputsAndOutputs.firstInput();
    StringRef InPath = InputInfo.getFileName();
    const auto &OutputInfo =
    InputInfo.getPrimarySpecificPaths().SupplementaryOutputs;
    StringRef OutPath = OutputInfo.ModuleOutputPath;

    // Build the .swiftmodule; this is a _very_ abridged version of the logic
    // in performCompile in libFrontendTool, specialized, to just the one
    // module-serialization task we're trying to do here.
    LLVM_DEBUG(llvm::dbgs() << "Setting up instance to compile "
               << InPath << " to " << OutPath << "\n");

    SWIFT_DEFER {
      // Make sure to emit a generic top-level error if a module fails to
      // load. This is not only good for users; it also makes sure that we've
      // emitted an error in the parent diagnostic engine, which is what
      // determines whether the process exits with a proper failure status.
      if (SubInstance.getASTContext().hadError()) {
        auto builtByCompiler =
            getSwiftInterfaceCompilerVersionForCurrentCompiler(
                SubInstance.getASTContext());
        StringRef emittedByCompiler = info.CompilerVersion;
        diagnose(diag::module_interface_build_failed, isTypeChecking,
                 moduleName, emittedByCompiler == builtByCompiler,
                 emittedByCompiler, builtByCompiler);
      }
    };

    LLVM_DEBUG(llvm::dbgs() << "Performing sema\n");
    SubInstance.performSema();
    if (SubInstance.getASTContext().hadError()) {
      LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
      return std::make_error_code(std::errc::not_supported);
    }

    SILOptions &SILOpts = subInvocation.getSILOptions();
    auto Mod = SubInstance.getMainModule();
    auto &TC = SubInstance.getSILTypes();
    auto SILMod = performASTLowering(Mod, TC, SILOpts);
    if (!SILMod) {
      LLVM_DEBUG(llvm::dbgs() << "SILGen did not produce a module\n");
      return std::make_error_code(std::errc::not_supported);
    }

    // Setup the callbacks for serialization, which can occur during the
    // optimization pipeline.
    SerializationOptions SerializationOpts;
    std::string OutPathStr = OutPath.str();
    SerializationOpts.OutputPath = OutPathStr.c_str();
    SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
    SerializationOpts.AutolinkForceLoad =
      !subInvocation.getIRGenOptions().ForceLoadSymbolName.empty();

    // Record any non-SDK module interface files for the debug info.
    StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.SDKPath;
    if (!getRelativeDepPath(InPath, SDKPath))
      SerializationOpts.ModuleInterface = InPath;

    SmallVector<FileDependency, 16> Deps;
    bool serializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
    if (collectDepsForSerialization(SubInstance, Deps, serializeHashes)) {
      return std::make_error_code(std::errc::not_supported);
    }
    if (ShouldSerializeDeps)
      SerializationOpts.Dependencies = Deps;
    SILMod->setSerializeSILAction([&]() {
      if (isTypeChecking)
        return;

      // We don't want to serialize module docs in the cache -- they
      // will be serialized beside the interface file.
      serializeToBuffers(Mod, SerializationOpts, ModuleBuffer,
                         /*ModuleDocBuffer*/nullptr,
                         /*SourceInfoBuffer*/nullptr,
                         SILMod.get());
    });

    LLVM_DEBUG(llvm::dbgs() << "Running SIL processing passes\n");
    if (SubInstance.performSILProcessing(SILMod.get())) {
      LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
      return std::make_error_code(std::errc::not_supported);
    }
    if (SubInstance.getDiags().hadAnyError()) {
      return std::make_error_code(std::errc::not_supported);
    }
    return std::error_code();
    });
  });
  return !RunSuccess || SubError;
}

bool ModuleInterfaceBuilder::buildSwiftModule(StringRef OutPath,
                                              bool ShouldSerializeDeps,
                          std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
                          llvm::function_ref<void()> RemarkRebuild,
                          ArrayRef<std::string> CompiledCandidates) {
  auto build = [&]() {
    if (RemarkRebuild) {
      RemarkRebuild();
    }
    return buildSwiftModuleInternal(OutPath, ShouldSerializeDeps, ModuleBuffer,
                                    CompiledCandidates);
  };
  if (disableInterfaceFileLock) {
    return build();
  }
  while (1) {
  // Attempt to lock the interface file. Only one process is allowed to build
  // module from the interface so we don't consume too much memory when multiple
  // processes are doing the same.
  // FIXME: We should surface the module building step to the build system so
  // we don't need to synchronize here.
  llvm::LockFileManager Locked(interfacePath);
  switch (Locked) {
  case llvm::LockFileManager::LFS_Error:{
    // ModuleInterfaceBuilder takes care of correctness and locks are only
    // necessary for performance. Fallback to building the module in case of any lock
    // related errors.
    if (RemarkRebuild) {
      diagnose(diag::interface_file_lock_failure, interfacePath);
    }
    // Clear out any potential leftover.
    Locked.unsafeRemoveLockFile();
    LLVM_FALLTHROUGH;
  }
  case llvm::LockFileManager::LFS_Owned: {
    return build();
  }
  case llvm::LockFileManager::LFS_Shared: {
    // Someone else is responsible for building the module. Wait for them to
    // finish.
    switch (Locked.waitForUnlock(256)) {
    case llvm::LockFileManager::Res_Success: {
      // This process may have a different module output path. If the other
      // process doesn't build the interface to this output path, we should try
      // building ourselves.
      auto bufferOrError = llvm::MemoryBuffer::getFile(OutPath);
      if (!bufferOrError)
        continue;
      if (ModuleBuffer)
        *ModuleBuffer = std::move(bufferOrError.get());
      return false;
    }
    case llvm::LockFileManager::Res_OwnerDied: {
      continue; // try again to get the lock.
    }
    case llvm::LockFileManager::Res_Timeout: {
      // Since ModuleInterfaceBuilder takes care of correctness, we try waiting for
      // another process to complete the build so swift does not do it done
      // twice. If case of timeout, build it ourselves.
      if (RemarkRebuild) {
        diagnose(diag::interface_file_lock_timed_out, interfacePath);
      }
      // Clear the lock file so that future invocations can make progress.
      Locked.unsafeRemoveLockFile();
      continue;
    }
    }
    break;
  }
  }
  }
}
<commit_msg>When building modules on secondary threads via RunSafelyOnThread, request 8 MB of stack<commit_after>//===----- ModuleInterfaceBuilder.cpp - Compiles .swiftinterface files ----===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "textual-module-interface"

#include "swift/Frontend/ModuleInterfaceLoader.h"
#include "ModuleInterfaceBuilder.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/FileSystem.h"
#include "swift/AST/Module.h"
#include "swift/Basic/Defer.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/ModuleInterfaceSupport.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/Serialization/SerializationOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/xxhash.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/LockFileManager.h"

using namespace swift;
using FileDependency = SerializationOptions::FileDependency;
namespace path = llvm::sys::path;

/// If the file dependency in \p FullDepPath is inside the \p Base directory,
/// this returns its path relative to \p Base. Otherwise it returns None.
static Optional<StringRef> getRelativeDepPath(StringRef DepPath,
                                              StringRef Base) {
  // If Base is the root directory, or DepPath does not start with Base, bail.
  if (Base.size() <= 1 || !DepPath.startswith(Base)) {
    return None;
  }

  assert(DepPath.size() > Base.size() &&
      "should never depend on a directory");

  // Is the DepName something like ${Base}/foo.h"?
  if (path::is_separator(DepPath[Base.size()]))
    return DepPath.substr(Base.size() + 1);

  // Is the DepName something like "${Base}foo.h", where Base
  // itself contains a trailing slash?
  if (path::is_separator(Base.back()))
    return DepPath.substr(Base.size());

  // We have something next to Base, like "Base.h", that's somehow
  // become a dependency.
  return None;
}

bool ModuleInterfaceBuilder::collectDepsForSerialization(
    CompilerInstance &SubInstance, SmallVectorImpl<FileDependency> &Deps,
    bool IsHashBased) {
  llvm::vfs::FileSystem &fs = *sourceMgr.getFileSystem();

  auto &Opts = SubInstance.getASTContext().SearchPathOpts;
  SmallString<128> SDKPath(Opts.SDKPath);
  path::native(SDKPath);
  SmallString<128> ResourcePath(Opts.RuntimeResourcePath);
  path::native(ResourcePath);

  auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
  SmallVector<StringRef, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
  InitialDepNames.push_back(interfacePath);
  InitialDepNames.insert(InitialDepNames.end(),
                         extraDependencies.begin(), extraDependencies.end());
  SmallString<128> Scratch;

  for (const auto &InitialDepName : InitialDepNames) {
    path::native(InitialDepName, Scratch);
    StringRef DepName = Scratch.str();

    assert(moduleCachePath.empty() || !DepName.startswith(moduleCachePath));

    // Serialize the paths of dependencies in the SDK relative to it.
    Optional<StringRef> SDKRelativePath = getRelativeDepPath(DepName, SDKPath);
    StringRef DepNameToStore = SDKRelativePath.getValueOr(DepName);
    bool IsSDKRelative = SDKRelativePath.hasValue();

    // Forwarding modules add the underlying prebuilt module to their
    // dependency list -- don't serialize that.
    if (!prebuiltCachePath.empty() && DepName.startswith(prebuiltCachePath))
      continue;

    if (dependencyTracker) {
      dependencyTracker->addDependency(DepName, /*isSystem*/IsSDKRelative);
    }

    // Don't serialize compiler-relative deps so the cache is relocatable.
    if (DepName.startswith(ResourcePath))
      continue;

    auto Status = fs.status(DepName);
    if (!Status)
      return true;

    /// Lazily load the dependency buffer if we need it. If we're not
    /// dealing with a hash-based dependencies, and if the dependency is
    /// not a .swiftmodule, we can avoid opening the buffer.
    std::unique_ptr<llvm::MemoryBuffer> DepBuf = nullptr;
    auto getDepBuf = [&]() -> llvm::MemoryBuffer * {
      if (DepBuf) return DepBuf.get();
      if (auto Buf = fs.getBufferForFile(DepName, /*FileSize=*/-1,
                                         /*RequiresNullTerminator=*/false)) {
        DepBuf = std::move(Buf.get());
        return DepBuf.get();
      }
      return nullptr;
    };

    if (IsHashBased) {
      auto buf = getDepBuf();
      if (!buf) return true;
      uint64_t hash = xxHash64(buf->getBuffer());
      Deps.push_back(
                     FileDependency::hashBased(DepNameToStore, IsSDKRelative,
                                               Status->getSize(), hash));
    } else {
      uint64_t mtime =
      Status->getLastModificationTime().time_since_epoch().count();
      Deps.push_back(
                     FileDependency::modTimeBased(DepNameToStore, IsSDKRelative,
                                                  Status->getSize(), mtime));
    }
  }
  return false;
}

bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
    StringRef OutPath, bool ShouldSerializeDeps,
    std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
    ArrayRef<std::string> CompiledCandidates) {

  auto outerPrettyStackState = llvm::SavePrettyStackState();

  bool SubError = false;
  static const size_t ThreadStackSize = 8 << 20; // 8 MB.
  bool RunSuccess = llvm::CrashRecoveryContext().RunSafelyOnThread([&] {
    // Pretend we're on the original thread for pretty-stack-trace purposes.
    auto savedInnerPrettyStackState = llvm::SavePrettyStackState();
    llvm::RestorePrettyStackState(outerPrettyStackState);
    SWIFT_DEFER {
      llvm::RestorePrettyStackState(savedInnerPrettyStackState);
    };

    SubError = (bool)subASTDelegate.runInSubCompilerInstance(moduleName,
                                                             interfacePath,
                                                             OutPath,
                                                             diagnosticLoc,
                                           [&](SubCompilerInstanceInfo &info) {
    auto &SubInstance = *info.Instance;
    auto subInvocation = SubInstance.getInvocation();
    // Try building forwarding module first. If succeed, return.
    if (static_cast<ModuleInterfaceLoader*>(SubInstance.getASTContext()
        .getModuleInterfaceLoader())->tryEmitForwardingModule(moduleName,
                                                              interfacePath,
                                                  CompiledCandidates, OutPath)) {
      return std::error_code();
    }
    FrontendOptions &FEOpts = subInvocation.getFrontendOptions();
    bool isTypeChecking =
        (FEOpts.RequestedAction == FrontendOptions::ActionType::Typecheck);
    const auto &InputInfo = FEOpts.InputsAndOutputs.firstInput();
    StringRef InPath = InputInfo.getFileName();
    const auto &OutputInfo =
    InputInfo.getPrimarySpecificPaths().SupplementaryOutputs;
    StringRef OutPath = OutputInfo.ModuleOutputPath;

    // Build the .swiftmodule; this is a _very_ abridged version of the logic
    // in performCompile in libFrontendTool, specialized, to just the one
    // module-serialization task we're trying to do here.
    LLVM_DEBUG(llvm::dbgs() << "Setting up instance to compile "
               << InPath << " to " << OutPath << "\n");

    SWIFT_DEFER {
      // Make sure to emit a generic top-level error if a module fails to
      // load. This is not only good for users; it also makes sure that we've
      // emitted an error in the parent diagnostic engine, which is what
      // determines whether the process exits with a proper failure status.
      if (SubInstance.getASTContext().hadError()) {
        auto builtByCompiler =
            getSwiftInterfaceCompilerVersionForCurrentCompiler(
                SubInstance.getASTContext());
        StringRef emittedByCompiler = info.CompilerVersion;
        diagnose(diag::module_interface_build_failed, isTypeChecking,
                 moduleName, emittedByCompiler == builtByCompiler,
                 emittedByCompiler, builtByCompiler);
      }
    };

    LLVM_DEBUG(llvm::dbgs() << "Performing sema\n");
    SubInstance.performSema();
    if (SubInstance.getASTContext().hadError()) {
      LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
      return std::make_error_code(std::errc::not_supported);
    }

    SILOptions &SILOpts = subInvocation.getSILOptions();
    auto Mod = SubInstance.getMainModule();
    auto &TC = SubInstance.getSILTypes();
    auto SILMod = performASTLowering(Mod, TC, SILOpts);
    if (!SILMod) {
      LLVM_DEBUG(llvm::dbgs() << "SILGen did not produce a module\n");
      return std::make_error_code(std::errc::not_supported);
    }

    // Setup the callbacks for serialization, which can occur during the
    // optimization pipeline.
    SerializationOptions SerializationOpts;
    std::string OutPathStr = OutPath.str();
    SerializationOpts.OutputPath = OutPathStr.c_str();
    SerializationOpts.ModuleLinkName = FEOpts.ModuleLinkName;
    SerializationOpts.AutolinkForceLoad =
      !subInvocation.getIRGenOptions().ForceLoadSymbolName.empty();

    // Record any non-SDK module interface files for the debug info.
    StringRef SDKPath = SubInstance.getASTContext().SearchPathOpts.SDKPath;
    if (!getRelativeDepPath(InPath, SDKPath))
      SerializationOpts.ModuleInterface = InPath;

    SmallVector<FileDependency, 16> Deps;
    bool serializeHashes = FEOpts.SerializeModuleInterfaceDependencyHashes;
    if (collectDepsForSerialization(SubInstance, Deps, serializeHashes)) {
      return std::make_error_code(std::errc::not_supported);
    }
    if (ShouldSerializeDeps)
      SerializationOpts.Dependencies = Deps;
    SILMod->setSerializeSILAction([&]() {
      if (isTypeChecking)
        return;

      // We don't want to serialize module docs in the cache -- they
      // will be serialized beside the interface file.
      serializeToBuffers(Mod, SerializationOpts, ModuleBuffer,
                         /*ModuleDocBuffer*/nullptr,
                         /*SourceInfoBuffer*/nullptr,
                         SILMod.get());
    });

    LLVM_DEBUG(llvm::dbgs() << "Running SIL processing passes\n");
    if (SubInstance.performSILProcessing(SILMod.get())) {
      LLVM_DEBUG(llvm::dbgs() << "encountered errors\n");
      return std::make_error_code(std::errc::not_supported);
    }
    if (SubInstance.getDiags().hadAnyError()) {
      return std::make_error_code(std::errc::not_supported);
    }
    return std::error_code();
    });
  }, ThreadStackSize);
  return !RunSuccess || SubError;
}

bool ModuleInterfaceBuilder::buildSwiftModule(StringRef OutPath,
                                              bool ShouldSerializeDeps,
                          std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
                          llvm::function_ref<void()> RemarkRebuild,
                          ArrayRef<std::string> CompiledCandidates) {
  auto build = [&]() {
    if (RemarkRebuild) {
      RemarkRebuild();
    }
    return buildSwiftModuleInternal(OutPath, ShouldSerializeDeps, ModuleBuffer,
                                    CompiledCandidates);
  };
  if (disableInterfaceFileLock) {
    return build();
  }
  while (1) {
  // Attempt to lock the interface file. Only one process is allowed to build
  // module from the interface so we don't consume too much memory when multiple
  // processes are doing the same.
  // FIXME: We should surface the module building step to the build system so
  // we don't need to synchronize here.
  llvm::LockFileManager Locked(interfacePath);
  switch (Locked) {
  case llvm::LockFileManager::LFS_Error:{
    // ModuleInterfaceBuilder takes care of correctness and locks are only
    // necessary for performance. Fallback to building the module in case of any lock
    // related errors.
    if (RemarkRebuild) {
      diagnose(diag::interface_file_lock_failure, interfacePath);
    }
    // Clear out any potential leftover.
    Locked.unsafeRemoveLockFile();
    LLVM_FALLTHROUGH;
  }
  case llvm::LockFileManager::LFS_Owned: {
    return build();
  }
  case llvm::LockFileManager::LFS_Shared: {
    // Someone else is responsible for building the module. Wait for them to
    // finish.
    switch (Locked.waitForUnlock(256)) {
    case llvm::LockFileManager::Res_Success: {
      // This process may have a different module output path. If the other
      // process doesn't build the interface to this output path, we should try
      // building ourselves.
      auto bufferOrError = llvm::MemoryBuffer::getFile(OutPath);
      if (!bufferOrError)
        continue;
      if (ModuleBuffer)
        *ModuleBuffer = std::move(bufferOrError.get());
      return false;
    }
    case llvm::LockFileManager::Res_OwnerDied: {
      continue; // try again to get the lock.
    }
    case llvm::LockFileManager::Res_Timeout: {
      // Since ModuleInterfaceBuilder takes care of correctness, we try waiting for
      // another process to complete the build so swift does not do it done
      // twice. If case of timeout, build it ourselves.
      if (RemarkRebuild) {
        diagnose(diag::interface_file_lock_timed_out, interfacePath);
      }
      // Clear the lock file so that future invocations can make progress.
      Locked.unsafeRemoveLockFile();
      continue;
    }
    }
    break;
  }
  }
  }
}
<|endoftext|>


<commit_before>//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that expand pseudo instructions into target
// instructions to allow proper scheduling, if-conversion, and other late
// optimizations. This pass should be run after register allocation but before
// post- regalloc scheduling pass.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "arm-pseudo"
#include "ARM.h"
#include "ARMBaseInstrInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"

using namespace llvm;

namespace {
  class ARMExpandPseudo : public MachineFunctionPass {
  public:
    static char ID;
    ARMExpandPseudo() : MachineFunctionPass(&ID) {}

    const TargetInstrInfo *TII;

    virtual bool runOnMachineFunction(MachineFunction &Fn);

    virtual const char *getPassName() const {
      return "ARM pseudo instruction expansion pass";
    }

  private:
    void TransferImpOps(MachineInstr &OldMI,
                        MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
    bool ExpandMBB(MachineBasicBlock &MBB);
  };
  char ARMExpandPseudo::ID = 0;
}

/// TransferImpOps - Transfer implicit operands on the pseudo instruction to
/// the instructions created from the expansion.
void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
                                     MachineInstrBuilder &UseMI,
                                     MachineInstrBuilder &DefMI) {
  const TargetInstrDesc &Desc = OldMI.getDesc();
  for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
       i != e; ++i) {
    const MachineOperand &MO = OldMI.getOperand(i);
    assert(MO.isReg() && MO.getReg());
    if (MO.isUse())
      UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill()));
    else
      DefMI.addReg(MO.getReg(),
                   getDefRegState(true) | getDeadRegState(MO.isDead()));
  }
}

bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
  bool Modified = false;

  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  while (MBBI != E) {
    MachineInstr &MI = *MBBI;
    MachineBasicBlock::iterator NMBBI = llvm::next(MBBI);

    unsigned Opcode = MI.getOpcode();
    switch (Opcode) {
    default: break;
    case ARM::tLDRpci_pic:
    case ARM::t2LDRpci_pic: {
      unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
        ? ARM::tLDRpci : ARM::t2LDRpci;
      unsigned DstReg = MI.getOperand(0).getReg();
      bool DstIsDead = MI.getOperand(0).isDead();
      MachineInstrBuilder MIB1 =
        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
                               TII->get(NewLdOpc), DstReg)
                       .addOperand(MI.getOperand(1)));
      (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
                                         TII->get(ARM::tPICADD))
        .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
        .addReg(DstReg)
        .addOperand(MI.getOperand(2));
      TransferImpOps(MI, MIB1, MIB2);
      MI.eraseFromParent();
      Modified = true;
      break;
    }

    case ARM::t2MOVi32imm: {
      unsigned PredReg = 0;
      ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
      unsigned DstReg = MI.getOperand(0).getReg();
      bool DstIsDead = MI.getOperand(0).isDead();
      const MachineOperand &MO = MI.getOperand(1);
      MachineInstrBuilder LO16, HI16;

      LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
                     DstReg);
      HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
        .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
        .addReg(DstReg);

      if (MO.isImm()) {
        unsigned Imm = MO.getImm();
        unsigned Lo16 = Imm & 0xffff;
        unsigned Hi16 = (Imm >> 16) & 0xffff;
        LO16 = LO16.addImm(Lo16);
        HI16 = HI16.addImm(Hi16);
      } else {
        const GlobalValue *GV = MO.getGlobal();
        unsigned TF = MO.getTargetFlags();
        LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
        HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
      }
      (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      LO16.addImm(Pred).addReg(PredReg);
      HI16.addImm(Pred).addReg(PredReg);
      TransferImpOps(MI, LO16, HI16);
      MI.eraseFromParent();
      Modified = true;
    }
    }
    MBBI = NMBBI;
  }

  return Modified;
}

bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  TII = MF.getTarget().getInstrInfo();

  bool Modified = false;
  for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
       ++MFI)
    Modified |= ExpandMBB(*MFI);
  return Modified;
}

/// createARMExpandPseudoPass - returns an instance of the pseudo instruction
/// expansion pass.
FunctionPass *llvm::createARMExpandPseudoPass() {
  return new ARMExpandPseudo();
}
<commit_msg>Expand VMOVQQ into a pair of VMOVQ.<commit_after>//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that expand pseudo instructions into target
// instructions to allow proper scheduling, if-conversion, and other late
// optimizations. This pass should be run after register allocation but before
// post- regalloc scheduling pass.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "arm-pseudo"
#include "ARM.h"
#include "ARMBaseInstrInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"

using namespace llvm;

namespace {
  class ARMExpandPseudo : public MachineFunctionPass {
  public:
    static char ID;
    ARMExpandPseudo() : MachineFunctionPass(&ID) {}

    const TargetInstrInfo *TII;
    const TargetRegisterInfo *TRI;

    virtual bool runOnMachineFunction(MachineFunction &Fn);

    virtual const char *getPassName() const {
      return "ARM pseudo instruction expansion pass";
    }

  private:
    void TransferImpOps(MachineInstr &OldMI,
                        MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
    bool ExpandMBB(MachineBasicBlock &MBB);
  };
  char ARMExpandPseudo::ID = 0;
}

/// TransferImpOps - Transfer implicit operands on the pseudo instruction to
/// the instructions created from the expansion.
void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
                                     MachineInstrBuilder &UseMI,
                                     MachineInstrBuilder &DefMI) {
  const TargetInstrDesc &Desc = OldMI.getDesc();
  for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
       i != e; ++i) {
    const MachineOperand &MO = OldMI.getOperand(i);
    assert(MO.isReg() && MO.getReg());
    if (MO.isUse())
      UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill()));
    else
      DefMI.addReg(MO.getReg(),
                   getDefRegState(true) | getDeadRegState(MO.isDead()));
  }
}

bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
  bool Modified = false;

  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
  while (MBBI != E) {
    MachineInstr &MI = *MBBI;
    MachineBasicBlock::iterator NMBBI = llvm::next(MBBI);

    unsigned Opcode = MI.getOpcode();
    switch (Opcode) {
    default: break;
    case ARM::tLDRpci_pic:
    case ARM::t2LDRpci_pic: {
      unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
        ? ARM::tLDRpci : ARM::t2LDRpci;
      unsigned DstReg = MI.getOperand(0).getReg();
      bool DstIsDead = MI.getOperand(0).isDead();
      MachineInstrBuilder MIB1 =
        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
                               TII->get(NewLdOpc), DstReg)
                       .addOperand(MI.getOperand(1)));
      (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
                                         TII->get(ARM::tPICADD))
        .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
        .addReg(DstReg)
        .addOperand(MI.getOperand(2));
      TransferImpOps(MI, MIB1, MIB2);
      MI.eraseFromParent();
      Modified = true;
      break;
    }

    case ARM::t2MOVi32imm: {
      unsigned PredReg = 0;
      ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
      unsigned DstReg = MI.getOperand(0).getReg();
      bool DstIsDead = MI.getOperand(0).isDead();
      const MachineOperand &MO = MI.getOperand(1);
      MachineInstrBuilder LO16, HI16;

      LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16),
                     DstReg);
      HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16))
        .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
        .addReg(DstReg);

      if (MO.isImm()) {
        unsigned Imm = MO.getImm();
        unsigned Lo16 = Imm & 0xffff;
        unsigned Hi16 = (Imm >> 16) & 0xffff;
        LO16 = LO16.addImm(Lo16);
        HI16 = HI16.addImm(Hi16);
      } else {
        const GlobalValue *GV = MO.getGlobal();
        unsigned TF = MO.getTargetFlags();
        LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
        HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
      }
      (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
      LO16.addImm(Pred).addReg(PredReg);
      HI16.addImm(Pred).addReg(PredReg);
      TransferImpOps(MI, LO16, HI16);
      MI.eraseFromParent();
      Modified = true;
      break;
    }

    case ARM::VMOVQQ: {
      unsigned DstReg = MI.getOperand(0).getReg();
      bool DstIsDead = MI.getOperand(0).isDead();
      unsigned EvenDst = TRI->getSubReg(DstReg, ARM::QSUBREG_0);
      unsigned OddDst  = TRI->getSubReg(DstReg, ARM::QSUBREG_1);
      unsigned SrcReg = MI.getOperand(1).getReg();
      bool SrcIsKill = MI.getOperand(1).isKill();
      unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::QSUBREG_0);
      unsigned OddSrc  = TRI->getSubReg(SrcReg, ARM::QSUBREG_1);
      MachineInstrBuilder Even =
        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
                               TII->get(ARM::VMOVQ))
                       .addReg(EvenDst, getDefRegState(true) | getDeadRegState(DstIsDead))
                       .addReg(EvenSrc, getKillRegState(SrcIsKill)));
      MachineInstrBuilder Odd =
        AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
                               TII->get(ARM::VMOVQ))
                       .addReg(OddDst, getDefRegState(true) | getDeadRegState(DstIsDead))
                       .addReg(OddSrc, getKillRegState(SrcIsKill)));
      TransferImpOps(MI, Even, Odd);
      MI.eraseFromParent();
      Modified = true;
    }
    }
    MBBI = NMBBI;
  }

  return Modified;
}

bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
  TII = MF.getTarget().getInstrInfo();
  TRI = MF.getTarget().getRegisterInfo();

  bool Modified = false;
  for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
       ++MFI)
    Modified |= ExpandMBB(*MFI);
  return Modified;
}

/// createARMExpandPseudoPass - returns an instance of the pseudo instruction
/// expansion pass.
FunctionPass *llvm::createARMExpandPseudoPass() {
  return new ARMExpandPseudo();
}
<|endoftext|>


<commit_before>//===- PowerPCInstrInfo.cpp - PowerPC Instruction Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "PowerPCInstrInfo.h"
#include "PowerPC.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "PowerPCGenInstrInfo.inc"
using namespace llvm;

PowerPCInstrInfo::PowerPCInstrInfo()
  : TargetInstrInfo(PowerPCInsts, sizeof(PowerPCInsts)/sizeof(PowerPCInsts[0])){
}
<commit_msg>Implement PowerPCInstrInfo::isMoveInstr(), patch by Nate Begeman<commit_after>//===- PowerPCInstrInfo.cpp - PowerPC Instruction Information ---*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the PowerPC implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "PowerPCInstrInfo.h"
#include "PowerPC.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "PowerPCGenInstrInfo.inc"
#include <iostream>
using namespace llvm;

PowerPCInstrInfo::PowerPCInstrInfo()
  : TargetInstrInfo(PowerPCInsts, sizeof(PowerPCInsts)/sizeof(PowerPCInsts[0])){
}

bool PowerPCInstrInfo::isMoveInstr(const MachineInstr& MI,
                               unsigned& sourceReg,
                               unsigned& destReg) const {
  MachineOpCode oc = MI.getOpcode();
  if (oc == PPC32::OR) {
      assert(MI.getNumOperands() == 3 &&
             MI.getOperand(0).isRegister() &&
             MI.getOperand(1).isRegister() &&
             MI.getOperand(2).isRegister() &&
             "invalid register-register int move instruction");
      if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
        sourceReg = MI.getOperand(1).getReg();
        destReg = MI.getOperand(0).getReg();
        return true;
      }
  }
  else if (oc == PPC32::FMR) {
      assert(MI.getNumOperands() == 2 &&
             MI.getOperand(0).isRegister() &&
             MI.getOperand(1).isRegister() &&
             "invalid register-register fp move instruction");
      sourceReg = MI.getOperand(1).getReg();
      destReg = MI.getOperand(0).getReg();
      return true;
  }
  return false;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ComponentDescriptorRegistry.h"

#include <react/core/ShadowNodeFragment.h>
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>
#include <react/uimanager/primitives.h>

namespace facebook {
namespace react {

ComponentDescriptorRegistry::ComponentDescriptorRegistry(
    ComponentDescriptorParameters const &parameters,
    ComponentDescriptorProviderRegistry const &providerRegistry)
    : parameters_(parameters), providerRegistry_(providerRegistry) {}

void ComponentDescriptorRegistry::add(
    ComponentDescriptorProvider componentDescriptorProvider) const {
  std::unique_lock<better::shared_mutex> lock(mutex_);

  auto componentDescriptor = componentDescriptorProvider.constructor(
      {parameters_.eventDispatcher,
       parameters_.contextContainer,
       componentDescriptorProvider.flavor});
  assert(
      componentDescriptor->getComponentHandle() ==
      componentDescriptorProvider.handle);
  assert(
      componentDescriptor->getComponentName() ==
      componentDescriptorProvider.name);

  auto sharedComponentDescriptor = std::shared_ptr<ComponentDescriptor const>(
      std::move(componentDescriptor));
  _registryByHandle[componentDescriptorProvider.handle] =
      sharedComponentDescriptor;
  _registryByName[componentDescriptorProvider.name] = sharedComponentDescriptor;

  if (strcmp(componentDescriptorProvider.name, "UnimplementedNativeView") ==
      0) {
    auto *self = const_cast<ComponentDescriptorRegistry *>(this);
    self->setFallbackComponentDescriptor(sharedComponentDescriptor);
  }
}

void ComponentDescriptorRegistry::registerComponentDescriptor(
    SharedComponentDescriptor componentDescriptor) const {
  ComponentHandle componentHandle = componentDescriptor->getComponentHandle();
  _registryByHandle[componentHandle] = componentDescriptor;

  ComponentName componentName = componentDescriptor->getComponentName();
  _registryByName[componentName] = componentDescriptor;
}

static std::string componentNameByReactViewName(std::string viewName) {
  // We need this function only for the transition period;
  // eventually, all names will be unified.

  std::string rctPrefix("RCT");
  if (std::mismatch(rctPrefix.begin(), rctPrefix.end(), viewName.begin())
          .first == rctPrefix.end()) {
    // If `viewName` has "RCT" prefix, remove it.
    viewName.erase(0, rctPrefix.length());
  }

  // Fabric uses slightly new names for Text components because of differences
  // in semantic.
  if (viewName == "Text") {
    return "Paragraph";
  }
  if (viewName == "VirtualText") {
    return "Text";
  }

  if (viewName == "ImageView") {
    return "Image";
  }

  if (viewName == "AndroidHorizontalScrollView") {
    return "ScrollView";
  }

  if (viewName == "RKShimmeringView") {
    return "ShimmeringView";
  }

  if (viewName == "RefreshControl") {
    return "PullToRefreshView";
  }

  if (viewName == "AndroidProgressBar") {
    return "ActivityIndicatorView";
  }

  // We need this temporarily for testing purposes until we have proper
  // implementation of core components.
  if (viewName == "ScrollContentView" ||
      viewName == "AndroidHorizontalScrollContentView" // Android
  ) {
    return "View";
  }

  return viewName;
}

ComponentDescriptor const &ComponentDescriptorRegistry::at(
    std::string const &componentName) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  auto unifiedComponentName = componentNameByReactViewName(componentName);

  auto it = _registryByName.find(unifiedComponentName);
  if (it == _registryByName.end()) {
    mutex_.unlock_shared();
    providerRegistry_.request(unifiedComponentName.c_str());
    mutex_.lock_shared();

    it = _registryByName.find(unifiedComponentName);

    /*
     * TODO: T54849676
     * Uncomment the `assert` after the following block that checks
     * `_fallbackComponentDescriptor` is no longer needed. The assert assumes
     * that `componentDescriptorProviderRequest` is always not null and register
     * some component on every single request.
     */
    // assert(it != _registryByName.end());
  }

  if (it == _registryByName.end()) {
    if (_fallbackComponentDescriptor == nullptr) {
      throw std::invalid_argument(
          ("Unable to find componentDescriptor for " + unifiedComponentName)
              .c_str());
    }
    return *_fallbackComponentDescriptor.get();
  }

  return *it->second;
}

ComponentDescriptor const *ComponentDescriptorRegistry::
    findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
        ComponentHandle componentHandle) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  auto iterator = _registryByHandle.find(componentHandle);
  if (iterator == _registryByHandle.end()) {
    return nullptr;
  }

  return iterator->second.get();
}

ComponentDescriptor const &ComponentDescriptorRegistry::at(
    ComponentHandle componentHandle) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  return *_registryByHandle.at(componentHandle);
}

SharedShadowNode ComponentDescriptorRegistry::createNode(
    Tag tag,
    std::string const &viewName,
    SurfaceId surfaceId,
    folly::dynamic const &propsDynamic,
    SharedEventTarget const &eventTarget) const {
  auto unifiedComponentName = componentNameByReactViewName(viewName);
  auto const &componentDescriptor = this->at(unifiedComponentName);

  auto const eventEmitter =
      componentDescriptor.createEventEmitter(std::move(eventTarget), tag);
  auto const props =
      componentDescriptor.cloneProps(nullptr, RawProps(propsDynamic));
  auto const state = componentDescriptor.createInitialState(
      ShadowNodeFragment{tag, surfaceId, props, eventEmitter});

  return componentDescriptor.createShadowNode({
      /* .tag = */ tag,
      /* .surfaceId = */ surfaceId,
      /* .props = */ props,
      /* .eventEmitter = */ eventEmitter,
      /* .children = */ ShadowNodeFragment::childrenPlaceholder(),
      /* .localData = */ ShadowNodeFragment::localDataPlaceholder(),
      /* .state = */ state,
  });
}

void ComponentDescriptorRegistry::setFallbackComponentDescriptor(
    SharedComponentDescriptor descriptor) {
  _fallbackComponentDescriptor = descriptor;
  registerComponentDescriptor(descriptor);
}

ComponentDescriptor::Shared
ComponentDescriptorRegistry::getFallbackComponentDescriptor() const {
  return _fallbackComponentDescriptor;
}

} // namespace react
} // namespace facebook
<commit_msg>Fabric: Removing a workaround from ComponentDescriptorRegistry<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "ComponentDescriptorRegistry.h"

#include <react/core/ShadowNodeFragment.h>
#include <react/uimanager/ComponentDescriptorProviderRegistry.h>
#include <react/uimanager/primitives.h>

namespace facebook {
namespace react {

ComponentDescriptorRegistry::ComponentDescriptorRegistry(
    ComponentDescriptorParameters const &parameters,
    ComponentDescriptorProviderRegistry const &providerRegistry)
    : parameters_(parameters), providerRegistry_(providerRegistry) {}

void ComponentDescriptorRegistry::add(
    ComponentDescriptorProvider componentDescriptorProvider) const {
  std::unique_lock<better::shared_mutex> lock(mutex_);

  auto componentDescriptor = componentDescriptorProvider.constructor(
      {parameters_.eventDispatcher,
       parameters_.contextContainer,
       componentDescriptorProvider.flavor});
  assert(
      componentDescriptor->getComponentHandle() ==
      componentDescriptorProvider.handle);
  assert(
      componentDescriptor->getComponentName() ==
      componentDescriptorProvider.name);

  auto sharedComponentDescriptor = std::shared_ptr<ComponentDescriptor const>(
      std::move(componentDescriptor));
  _registryByHandle[componentDescriptorProvider.handle] =
      sharedComponentDescriptor;
  _registryByName[componentDescriptorProvider.name] = sharedComponentDescriptor;
}

void ComponentDescriptorRegistry::registerComponentDescriptor(
    SharedComponentDescriptor componentDescriptor) const {
  ComponentHandle componentHandle = componentDescriptor->getComponentHandle();
  _registryByHandle[componentHandle] = componentDescriptor;

  ComponentName componentName = componentDescriptor->getComponentName();
  _registryByName[componentName] = componentDescriptor;
}

static std::string componentNameByReactViewName(std::string viewName) {
  // We need this function only for the transition period;
  // eventually, all names will be unified.

  std::string rctPrefix("RCT");
  if (std::mismatch(rctPrefix.begin(), rctPrefix.end(), viewName.begin())
          .first == rctPrefix.end()) {
    // If `viewName` has "RCT" prefix, remove it.
    viewName.erase(0, rctPrefix.length());
  }

  // Fabric uses slightly new names for Text components because of differences
  // in semantic.
  if (viewName == "Text") {
    return "Paragraph";
  }
  if (viewName == "VirtualText") {
    return "Text";
  }

  if (viewName == "ImageView") {
    return "Image";
  }

  if (viewName == "AndroidHorizontalScrollView") {
    return "ScrollView";
  }

  if (viewName == "RKShimmeringView") {
    return "ShimmeringView";
  }

  if (viewName == "RefreshControl") {
    return "PullToRefreshView";
  }

  if (viewName == "AndroidProgressBar") {
    return "ActivityIndicatorView";
  }

  // We need this temporarily for testing purposes until we have proper
  // implementation of core components.
  if (viewName == "ScrollContentView" ||
      viewName == "AndroidHorizontalScrollContentView" // Android
  ) {
    return "View";
  }

  return viewName;
}

ComponentDescriptor const &ComponentDescriptorRegistry::at(
    std::string const &componentName) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  auto unifiedComponentName = componentNameByReactViewName(componentName);

  auto it = _registryByName.find(unifiedComponentName);
  if (it == _registryByName.end()) {
    mutex_.unlock_shared();
    providerRegistry_.request(unifiedComponentName.c_str());
    mutex_.lock_shared();

    it = _registryByName.find(unifiedComponentName);

    /*
     * TODO: T54849676
     * Uncomment the `assert` after the following block that checks
     * `_fallbackComponentDescriptor` is no longer needed. The assert assumes
     * that `componentDescriptorProviderRequest` is always not null and register
     * some component on every single request.
     */
    // assert(it != _registryByName.end());
  }

  if (it == _registryByName.end()) {
    if (_fallbackComponentDescriptor == nullptr) {
      throw std::invalid_argument(
          ("Unable to find componentDescriptor for " + unifiedComponentName)
              .c_str());
    }
    return *_fallbackComponentDescriptor.get();
  }

  return *it->second;
}

ComponentDescriptor const *ComponentDescriptorRegistry::
    findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
        ComponentHandle componentHandle) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  auto iterator = _registryByHandle.find(componentHandle);
  if (iterator == _registryByHandle.end()) {
    return nullptr;
  }

  return iterator->second.get();
}

ComponentDescriptor const &ComponentDescriptorRegistry::at(
    ComponentHandle componentHandle) const {
  std::shared_lock<better::shared_mutex> lock(mutex_);

  return *_registryByHandle.at(componentHandle);
}

SharedShadowNode ComponentDescriptorRegistry::createNode(
    Tag tag,
    std::string const &viewName,
    SurfaceId surfaceId,
    folly::dynamic const &propsDynamic,
    SharedEventTarget const &eventTarget) const {
  auto unifiedComponentName = componentNameByReactViewName(viewName);
  auto const &componentDescriptor = this->at(unifiedComponentName);

  auto const eventEmitter =
      componentDescriptor.createEventEmitter(std::move(eventTarget), tag);
  auto const props =
      componentDescriptor.cloneProps(nullptr, RawProps(propsDynamic));
  auto const state = componentDescriptor.createInitialState(
      ShadowNodeFragment{tag, surfaceId, props, eventEmitter});

  return componentDescriptor.createShadowNode({
      /* .tag = */ tag,
      /* .surfaceId = */ surfaceId,
      /* .props = */ props,
      /* .eventEmitter = */ eventEmitter,
      /* .children = */ ShadowNodeFragment::childrenPlaceholder(),
      /* .localData = */ ShadowNodeFragment::localDataPlaceholder(),
      /* .state = */ state,
  });
}

void ComponentDescriptorRegistry::setFallbackComponentDescriptor(
    SharedComponentDescriptor descriptor) {
  _fallbackComponentDescriptor = descriptor;
  registerComponentDescriptor(descriptor);
}

ComponentDescriptor::Shared
ComponentDescriptorRegistry::getFallbackComponentDescriptor() const {
  return _fallbackComponentDescriptor;
}

} // namespace react
} // namespace facebook
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName      :    NFCLuaScriptModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLuaScriptModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCLuaScriptModule.h"
#include "NFLuaScriptPlugin.h"
#include <assert.h>

#define TRY_RUN_GLOBAL_SCRIPT_FUN0(strFuncName)  try{luacpp::call<void>(lw, strFuncName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_RUN_GLOBAL_SCRIPT_FUN1(strFuncName, arg1)  try{luacpp::call<void>(lw, strFuncName, arg1);} catch (string &err){printf("%s\n", err.c_str());}

#define TRY_LOAD_SCRIPT_FLE(strFileName)  try{lw.dofile(strFileName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_ADD_PACKAGE_PATH(strFilePath)  try{lw.addPackagePath(strFilePath);} catch (string &err){printf("%s\n", err.c_str());}

bool NFCLuaScriptModule::Init()
{
	mnTime = pPluginManager->GetNowTime();

	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>("NFCKernelModule");
	m_pLogicClassModule = pPluginManager->FindModule<NFILogicClassModule>("NFCLogicClassModule");
	m_pElementInfoModule = pPluginManager->FindModule<NFIElementInfoModule>("NFCElementInfoModule");

	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLogicClassModule);
	assert(NULL != m_pElementInfoModule);

	Regisger();
	TRY_ADD_PACKAGE_PATH("../../NFDataCfg/ScriptModule");
	TRY_LOAD_SCRIPT_FLE("script_init.lua");
	TRY_RUN_GLOBAL_SCRIPT_FUN1("init_script_system", m_pKernelModule);
	TRY_LOAD_SCRIPT_FLE("script_list.lua");

	TRY_RUN_GLOBAL_SCRIPT_FUN0("Init");

	return true;
}

bool NFCLuaScriptModule::AfterInit()
{
	//add all callback
	m_pKernelModule->ResgisterCommonPropertyEvent(this, &NFCLuaScriptModule::OnPropertyCommEvent);
	m_pKernelModule->ResgisterCommonRecordEvent(this, &NFCLuaScriptModule::OnRecordCommonEvent);
	m_pKernelModule->ResgisterCommonClassEvent(this, &NFCLuaScriptModule::OnClassCommonEvent);

	TRY_RUN_GLOBAL_SCRIPT_FUN0("AfterInit");

	return true;
}

bool NFCLuaScriptModule::Shut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("Shut");

	return true;
}

bool NFCLuaScriptModule::Execute()
{
	//10秒钟reload一次
	if (pPluginManager->GetNowTime() - mnTime > 5)
	{
		mnTime = pPluginManager->GetNowTime();

		TRY_RUN_GLOBAL_SCRIPT_FUN0("Execute");

		TRY_LOAD_SCRIPT_FLE("script_reload.lua")

	}

	return true;
}

bool NFCLuaScriptModule::BeforeShut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("BeforeShut");

	return true;
}

int NFCLuaScriptModule::OnPropertyCommEvent(const NFGUID& self, const std::string& strPropertyName, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoPropertyCommEvent(self, strPropertyName, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnRecordCommonEvent(const NFGUID& self, const RECORD_EVENT_DATA& xEventData, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoRecordCommonEvent(self, xEventData, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnClassCommonEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFIDataList& var)
{
	DoClassCommonEvent(m_pLogicClassModule, self, strClassName, eClassEvent, var);

	return 0;
}

int NFCLuaScriptModule::DoScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}

	return 1;
}

int NFCLuaScriptModule::DoEventScript(const NFGUID& self, const int nEventID, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, nEventID, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, nEventID, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoHeartBeatScript(const NFGUID& self, const std::string& strHeartBeat, const float fTime, const int nCount, std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strHeartBeat.c_str(), fTime, nCount);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strHeartBeat.c_str(), fTime, nCount);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptPropertyCallBack(const NFGUID& self, const std::string& strPropertyName, const std::string& strComponentName, const std::string& strFunction, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strPropertyName.c_str(), &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strPropertyName.c_str(), oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptRecordCallBack(const NFGUID& self, const std::string& strRecordName, const std::string& strComponentName, const std::string& strFunction, const int nOpType, const int nRow, const int nCol, const NFCDataList::TData& oldVar, const NFCDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strRecordName.c_str(), nOpType, nRow, nCol, &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strRecordName.c_str(), nOpType, nRow, nCol, oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

bool NFCLuaScriptModule::Regisger()
{
	luacpp::reg_cclass<NFGUID>::_reg(lw, "NFGUID")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("GetData", &NFGUID::GetData)
		.method("SetData", &NFGUID::SetData)
		.method("GetHead", &NFGUID::GetHead)
		.method("SetHead", &NFGUID::SetHead);
	luacpp::reg_cclass<NFIKernelModule>::_reg(lw, "NFIKernelModule")
		.property("strName", &NFIKernelModule::strName);

	luacpp::reg_cclass<NFIDataList>::_reg(lw, "NFIDataList");

	luacpp::reg_cclass<NFCDataList>::_reg(lw, "NFCDataList")
		.constructor<void>()
		.method("IsEmpty", &NFCDataList::IsEmpty)
		.method("GetCount", &NFCDataList::GetCount)
		.method("Type", &NFCDataList::Type)
		.method("AddInt", &NFCDataList::AddInt)
		.method("AddFloat", &NFCDataList::AddFloat)
		.method("AddString", &NFCDataList::AddStringFromChar)
		.method("AddObject", &NFCDataList::AddObject)
		.method("SetInt", &NFCDataList::SetInt)
		.method("SetFloat", &NFCDataList::SetFloat)
		.method("SetString", &NFCDataList::SetString)
		.method("SetObject", &NFCDataList::SetObject)
		.method("Int", &NFCDataList::Int)
		.method("Float", &NFCDataList::Float)
		.method("String", &NFCDataList::String)
		.method("Object", &NFCDataList::Object);

	luacpp::reg_cclass<NFCDataList::TData>::_reg(lw, "TData")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		.method("GetFloat", &NFCDataList::TData::GetFloat)
		.method("GetInt", &NFCDataList::TData::GetInt)
		.method("GetObjectA", &NFCDataList::TData::GetObjectA)
		.method("GetString", &NFCDataList::TData::GetCharArr)
		.method("GetType", &NFCDataList::TData::GetType)
		.method("IsNullValue", &NFCDataList::TData::IsNullValue)
		.method("SetFloat", &NFCDataList::TData::SetFloat)
		.method("SetInt", &NFCDataList::TData::SetInt)
		.method("SetObject", &NFCDataList::TData::SetObject)
		.method("SetString", &NFCDataList::TData::SetString)
		.method("StringValEx", &NFCDataList::TData::StringValEx)
		.property("GetData", &NFCDataList::TData::variantData);

	luacpp::reg_cfun(lw, "DoEvent", &KernelModule_DoEvent);
	luacpp::reg_cfun(lw, "ExistElement", &KernelModule_ExistElement);
	luacpp::reg_cfun(lw, "GetElementPropertyInt", &KernelModule_GetElementPropertyInt);
	luacpp::reg_cfun(lw, "GetElementPropertyFloat", &KernelModule_GetElementPropertyFloat);
	luacpp::reg_cfun(lw, "GetElementPropertyString", &KernelModule_GetElementPropertyString);
	luacpp::reg_cfun(lw, "AddPropertyCallBack", &KernelModule_AddPropertyCallBack);
	luacpp::reg_cfun(lw, "AddRecordCallBack", &KernelModule_AddRecordCallBack);
	luacpp::reg_cfun(lw, "AddEventCallBack", &KernelModule_AddEventCallBack);
	luacpp::reg_cfun(lw, "AddHeartBeat", &KernelModule_AddHeartBeat);
	luacpp::reg_cfun(lw, "FindHeartBeat", &KernelModule_FindHeartBeat);
	luacpp::reg_cfun(lw, "RemoveHeartBeat", &KernelModule_RemoveHeartBeat);
	luacpp::reg_cfun(lw, "ExistContainer", &KernelModule_ExistContainer);
	luacpp::reg_cfun(lw, "SetPropertyInt", &KernelModule_SetPropertyInt);
	luacpp::reg_cfun(lw, "SetPropertyFloat", &KernelModule_SetPropertyFloat);
	luacpp::reg_cfun(lw, "SetPropertyString", &KernelModule_SetPropertyString);
	luacpp::reg_cfun(lw, "SetPropertyObject", &KernelModule_SetPropertyObject);
	luacpp::reg_cfun(lw, "GetPropertyInt", &KernelModule_GetPropertyInt);
	luacpp::reg_cfun(lw, "GetPropertyFloat", &KernelModule_GetPropertyFloat);
	luacpp::reg_cfun(lw, "GetPropertyString", &KernelModule_GetPropertyString);
	luacpp::reg_cfun(lw, "GetPropertyObject", &KernelModule_GetPropertyObject);
	luacpp::reg_cfun(lw, "SetRecordInt", &KernelModule_SetRecordInt);
	luacpp::reg_cfun(lw, "SetRecordFloat", &KernelModule_SetRecordFloat);
	luacpp::reg_cfun(lw, "SetRecordString", &KernelModule_SetRecordString);
	luacpp::reg_cfun(lw, "SetRecordObject", &KernelModule_SetRecordObject);
	luacpp::reg_cfun(lw, "GetRecordInt", &KernelModule_GetRecordInt);
	luacpp::reg_cfun(lw, "GetRecordFloat", &KernelModule_GetRecordFloat);
	luacpp::reg_cfun(lw, "GetRecordString", &KernelModule_GetRecordString);
	luacpp::reg_cfun(lw, "GetRecordObject", &KernelModule_GetRecordObject);
	luacpp::reg_cfun(lw, "AddRow", &KernelModule_AddRow);

	return true;
}

int NFCLuaScriptModule::DoClassCommonScript(const NFGUID& self, const std::string& strComponentName, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule);
		luacpp::call<void>(lw, "onClassCommonEvent", (NFINT64)m_pKernelModule, self, strComponentName, strClassName, (int)eClassEvent);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 0;
}
<commit_msg>Update NFCLuaScriptModule.cpp<commit_after>// -------------------------------------------------------------------------
//    @FileName      :    NFCLuaScriptModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLuaScriptModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCLuaScriptModule.h"
#include "NFLuaScriptPlugin.h"
#include <assert.h>

#define TRY_RUN_GLOBAL_SCRIPT_FUN0(strFuncName)  try{luacpp::call<void>(lw, strFuncName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_RUN_GLOBAL_SCRIPT_FUN1(strFuncName, arg1)  try{luacpp::call<void>(lw, strFuncName, arg1);} catch (string &err){printf("%s\n", err.c_str());}

#define TRY_LOAD_SCRIPT_FLE(strFileName)  try{lw.dofile(strFileName);} catch (string &err){printf("%s\n", err.c_str());}
#define TRY_ADD_PACKAGE_PATH(strFilePath)  try{lw.addPackagePath(strFilePath);} catch (string &err){printf("%s\n", err.c_str());}

bool NFCLuaScriptModule::Init()
{
	mnTime = pPluginManager->GetNowTime();

	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>("NFCKernelModule");
	m_pLogicClassModule = pPluginManager->FindModule<NFILogicClassModule>("NFCLogicClassModule");
	m_pElementInfoModule = pPluginManager->FindModule<NFIElementInfoModule>("NFCElementInfoModule");

	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLogicClassModule);
	assert(NULL != m_pElementInfoModule);

	Regisger();
	TRY_ADD_PACKAGE_PATH("../../NFDataCfg/ScriptModule");
	TRY_LOAD_SCRIPT_FLE("script_init.lua");
	TRY_RUN_GLOBAL_SCRIPT_FUN1("init_script_system", m_pKernelModule);
	TRY_LOAD_SCRIPT_FLE("script_list.lua");

	TRY_RUN_GLOBAL_SCRIPT_FUN0("Init");

	return true;
}

bool NFCLuaScriptModule::AfterInit()
{
	//add all callback
	m_pKernelModule->ResgisterCommonPropertyEvent(this, &NFCLuaScriptModule::OnPropertyCommEvent);
	m_pKernelModule->ResgisterCommonRecordEvent(this, &NFCLuaScriptModule::OnRecordCommonEvent);
	m_pKernelModule->ResgisterCommonClassEvent(this, &NFCLuaScriptModule::OnClassCommonEvent);

	TRY_RUN_GLOBAL_SCRIPT_FUN0("AfterInit");

	return true;
}

bool NFCLuaScriptModule::Shut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("Shut");

	return true;
}

bool NFCLuaScriptModule::Execute()
{
	//10秒钟reload一次
	if (pPluginManager->GetNowTime() - mnTime > 5)
	{
		mnTime = pPluginManager->GetNowTime();

		TRY_RUN_GLOBAL_SCRIPT_FUN0("Execute");

		TRY_LOAD_SCRIPT_FLE("script_reload.lua")

	}

	return true;
}

bool NFCLuaScriptModule::BeforeShut()
{
	TRY_RUN_GLOBAL_SCRIPT_FUN0("BeforeShut");

	return true;
}

int NFCLuaScriptModule::OnPropertyCommEvent(const NFGUID& self, const std::string& strPropertyName, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoPropertyCommEvent(self, strPropertyName, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnRecordCommonEvent(const NFGUID& self, const RECORD_EVENT_DATA& xEventData, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	DoRecordCommonEvent(self, xEventData, oldVar, newVar);

	return 0;
}

int NFCLuaScriptModule::OnClassCommonEvent(const NFGUID& self, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent, const NFIDataList& var)
{
	DoClassCommonEvent(m_pLogicClassModule, self, strClassName, eClassEvent, var);

	return 0;
}

int NFCLuaScriptModule::DoScript(const NFGUID& self, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}

	return 1;
}

int NFCLuaScriptModule::DoEventScript(const NFGUID& self, const int nEventID, const std::string& strComponentName, const std::string& strFunction, const NFCDataList& arg)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, nEventID, &arg);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, nEventID, arg);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoHeartBeatScript(const NFGUID& self, const std::string& strHeartBeat, const float fTime, const int nCount, std::string& strComponentName, const std::string& strFunction)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strHeartBeat.c_str(), fTime, nCount);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strHeartBeat.c_str(), fTime, nCount);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptPropertyCallBack(const NFGUID& self, const std::string& strPropertyName, const std::string& strComponentName, const std::string& strFunction, const NFIDataList::TData& oldVar, const NFIDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strPropertyName.c_str(), &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strPropertyName.c_str(), oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

int NFCLuaScriptModule::DoScriptRecordCallBack(const NFGUID& self, const std::string& strRecordName, const std::string& strComponentName, const std::string& strFunction, const int nOpType, const int nRow, const int nCol, const NFCDataList::TData& oldVar, const NFCDataList::TData& newVar)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule, &self, strRecordName.c_str(), nOpType, nRow, nCol, &oldVar, &newVar);
		luacpp::call<void>(lw, strFunction.c_str(), (NFINT64)m_pKernelModule, self, strRecordName.c_str(), nOpType, nRow, nCol, oldVar, newVar);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 1;
}

bool NFCLuaScriptModule::Regisger()
{
	luacpp::reg_cclass<NFGUID>::_reg(lw, "NFGUID")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		//.constructor<const test_class_A&>()//Ò»¸ö²ÎÊý¹¹Ôì
		.method("GetData", &NFGUID::GetData)
		.method("SetData", &NFGUID::SetData)
		.method("GetHead", &NFGUID::GetHead)
		.method("SetHead", &NFGUID::SetHead);
	luacpp::reg_cclass<NFIKernelModule>::_reg(lw, "NFIKernelModule")
		.property("strName", &NFIKernelModule::strName);

	luacpp::reg_cclass<NFIDataList>::_reg(lw, "NFIDataList");

	luacpp::reg_cclass<NFCDataList>::_reg(lw, "NFCDataList")
		.constructor<void>()
		.method("IsEmpty", &NFCDataList::IsEmpty)
		.method("GetCount", &NFCDataList::GetCount)
		.method("Type", &NFCDataList::Type)
		.method("AddInt", &NFCDataList::AddInt)
		.method("AddFloat", &NFCDataList::AddFloat)
		.method("AddString", &NFCDataList::AddStringFromChar)
		.method("AddObject", &NFCDataList::AddObject)
		.method("SetInt", &NFCDataList::SetInt)
		.method("SetFloat", &NFCDataList::SetFloat)
		.method("SetString", &NFCDataList::SetString)
		.method("SetObject", &NFCDataList::SetObject)
		.method("Int", &NFCDataList::Int)
		.method("Float", &NFCDataList::Float)
		.method("String", &NFCDataList::String)
		.method("Object", &NFCDataList::Object);

	luacpp::reg_cclass<NFCDataList::TData>::_reg(lw, "TData")
		.constructor<void>()//ÎÞ²Î¹¹Ôì
		.method("GetFloat", &NFCDataList::TData::GetFloat)
		.method("GetInt", &NFCDataList::TData::GetInt)
		.method("GetObjectA", &NFCDataList::TData::GetObjectA)
		.method("GetString", &NFCDataList::TData::GetCharArr)
		.method("GetType", &NFCDataList::TData::GetType)
		.method("IsNullValue", &NFCDataList::TData::IsNullValue)
		.method("SetFloat", &NFCDataList::TData::SetFloat)
		.method("SetInt", &NFCDataList::TData::SetInt)
		.method("SetObject", &NFCDataList::TData::SetObject)
		.method("SetString", &NFCDataList::TData::SetString)
		.method("StringValEx", &NFCDataList::TData::StringValEx)
		.property("GetData", &NFCDataList::TData::variantData);

	luacpp::reg_cfun(lw, "DoEvent", &KernelModule_DoEvent);
	luacpp::reg_cfun(lw, "ExistElement", &KernelModule_ExistElement);
	luacpp::reg_cfun(lw, "GetElementPropertyInt", &KernelModule_GetElementPropertyInt);
	luacpp::reg_cfun(lw, "GetElementPropertyFloat", &KernelModule_GetElementPropertyFloat);
	luacpp::reg_cfun(lw, "GetElementPropertyString", &KernelModule_GetElementPropertyString);
	luacpp::reg_cfun(lw, "AddPropertyCallBack", &KernelModule_AddPropertyCallBack);
	luacpp::reg_cfun(lw, "AddRecordCallBack", &KernelModule_AddRecordCallBack);
	luacpp::reg_cfun(lw, "AddEventCallBack", &KernelModule_AddEventCallBack);
	luacpp::reg_cfun(lw, "AddHeartBeat", &KernelModule_AddHeartBeat);
	luacpp::reg_cfun(lw, "FindHeartBeat", &KernelModule_FindHeartBeat);
	luacpp::reg_cfun(lw, "RemoveHeartBeat", &KernelModule_RemoveHeartBeat);
	luacpp::reg_cfun(lw, "ExistContainer", &KernelModule_ExistContainer);
	luacpp::reg_cfun(lw, "SetPropertyInt", &KernelModule_SetPropertyInt);
	luacpp::reg_cfun(lw, "SetPropertyFloat", &KernelModule_SetPropertyFloat);
	luacpp::reg_cfun(lw, "SetPropertyString", &KernelModule_SetPropertyString);
	luacpp::reg_cfun(lw, "SetPropertyObject", &KernelModule_SetPropertyObject);
	luacpp::reg_cfun(lw, "GetPropertyInt", &KernelModule_GetPropertyInt);
	luacpp::reg_cfun(lw, "GetPropertyFloat", &KernelModule_GetPropertyFloat);
	luacpp::reg_cfun(lw, "GetPropertyString", &KernelModule_GetPropertyString);
	luacpp::reg_cfun(lw, "GetPropertyObject", &KernelModule_GetPropertyObject);
	luacpp::reg_cfun(lw, "SetRecordInt", &KernelModule_SetRecordInt);
	luacpp::reg_cfun(lw, "SetRecordFloat", &KernelModule_SetRecordFloat);
	luacpp::reg_cfun(lw, "SetRecordString", &KernelModule_SetRecordString);
	luacpp::reg_cfun(lw, "SetRecordObject", &KernelModule_SetRecordObject);
	luacpp::reg_cfun(lw, "GetRecordInt", &KernelModule_GetRecordInt);
	luacpp::reg_cfun(lw, "GetRecordFloat", &KernelModule_GetRecordFloat);
	luacpp::reg_cfun(lw, "GetRecordString", &KernelModule_GetRecordString);
	luacpp::reg_cfun(lw, "GetRecordObject", &KernelModule_GetRecordObject);
	luacpp::reg_cfun(lw, "AddRow", &KernelModule_AddRow);

	return true;
}

int NFCLuaScriptModule::DoClassCommonScript(const NFGUID& self, const std::string& strComponentName, const std::string& strClassName, const CLASS_OBJECT_EVENT eClassEvent)
{
	try
	{
		//fflua.call<void>(strFunction.c_str(), (NFINT64)m_pKernelModule);
		luacpp::call<void>(lw, "OnClassCommonEvent", (NFINT64)m_pKernelModule, self, strComponentName, strClassName, (int)eClassEvent);
	}
	catch (string &err)
	{
		printf("%s\n", err.c_str());
		return 0;
	}
	return 0;
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

//
// OpenFlight loader for OpenSceneGraph
//
//  Copyright (C) 2005-2007  Brede Johansen
//

#include "AttrData.h"

using namespace flt;

AttrData::AttrData() :
    texels_u(0),
    texels_v(0),
    direction_u(0),
    direction_v(0),
    x_up(0),
    y_up(0),
    fileFormat(-1),                //   -1 Not used
    minFilterMode(MIN_FILTER_NONE),
    magFilterMode(MAG_FILTER_POINT),
    wrapMode(WRAP_REPEAT),
    wrapMode_u(WRAP_REPEAT),
    wrapMode_v(WRAP_REPEAT),
    modifyFlag(0),
    pivot_x(0),
    pivot_y(0),
    texEnvMode(TEXENV_MODULATE),
    intensityAsAlpha(0),
    size_u(0),
    size_v(0),
    originCode(0),
    kernelVersion(0),
    intFormat(0),                  //    0 - Default
    extFormat(0),                  //    0 - Default

    useMips(0),

    useLodScale(0),
    lod0(0.0f),
    scale0(1.0f),
    lod1(0.0f),
    scale1(1.0f),
    lod2(0.0f),
    scale2(1.0f),
    lod3(0.0f),
    scale3(1.0f),
    lod4(0.0f),
    scale4(1.0f),
    lod5(0.0f),
    scale5(1.0f),
    lod6(0.0f),
    scale6(1.0f),
    lod7(0.0f),
    scale7(1.0f),

    clamp(0),
    magFilterAlpha(2),             //    2 = None
    magFilterColor(2),             //    2 = None
    lambertMeridian(0),
    lambertUpperLat(0),
    lambertlowerLat(0),
    useDetail(0),
    txDetail_j(0),
    txDetail_k(0),
    txDetail_m(0),
    txDetail_n(0),
    txDetail_s(0),
    useTile(0),
    txTile_ll_u(0),
    txTile_ll_v(0),
    txTile_ur_u(0),
    txTile_ur_v(0),
    projection(PROJECTION_UNDEFINED),
    earthModel(DATUM_WGS84),
    utmZone(0),
    imageOrigin(0),
    geoUnits(0),
    hemisphere(1),
    comments(""),
    attrVersion(0),
    controlPoints(0)
    // TODO:
{
    of_mips[0]=of_mips[1]=of_mips[2]=of_mips[3]=of_mips[4]=of_mips[5]=of_mips[6]=of_mips[7]=0.0f;
}
/*
AttrData::AttrData(const AttrData& attr, const osg::CopyOp& copyop) :
    osg::Object(attr,copyop)
{}
*/
<commit_msg>Added initializers<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

//
// OpenFlight loader for OpenSceneGraph
//
//  Copyright (C) 2005-2007  Brede Johansen
//

#include "AttrData.h"

using namespace flt;

AttrData::AttrData() :
    texels_u(0),
    texels_v(0),
    direction_u(0),
    direction_v(0),
    x_up(0),
    y_up(0),
    fileFormat(-1),                //   -1 Not used
    minFilterMode(MIN_FILTER_NONE),
    magFilterMode(MAG_FILTER_POINT),
    wrapMode(WRAP_REPEAT),
    wrapMode_u(WRAP_REPEAT),
    wrapMode_v(WRAP_REPEAT),
    modifyFlag(0),
    pivot_x(0),
    pivot_y(0),
    texEnvMode(TEXENV_MODULATE),
    intensityAsAlpha(0),
    size_u(0),
    size_v(0),
    originCode(0),
    kernelVersion(0),
    intFormat(0),                  //    0 - Default
    extFormat(0),                  //    0 - Default

    useMips(0),

    useLodScale(0),
    lod0(0.0f),
    scale0(1.0f),
    lod1(0.0f),
    scale1(1.0f),
    lod2(0.0f),
    scale2(1.0f),
    lod3(0.0f),
    scale3(1.0f),
    lod4(0.0f),
    scale4(1.0f),
    lod5(0.0f),
    scale5(1.0f),
    lod6(0.0f),
    scale6(1.0f),
    lod7(0.0f),
    scale7(1.0f),

    clamp(0),
    magFilterAlpha(2),             //    2 = None
    magFilterColor(2),             //    2 = None
    lambertMeridian(0),
    lambertUpperLat(0),
    lambertlowerLat(0),
    useDetail(0),
    txDetail_j(0),
    txDetail_k(0),
    txDetail_m(0),
    txDetail_n(0),
    txDetail_s(0),
    useTile(0),
    txTile_ll_u(0),
    txTile_ll_v(0),
    txTile_ur_u(0),
    txTile_ur_v(0),
    projection(PROJECTION_UNDEFINED),
    earthModel(DATUM_WGS84),
    utmZone(0),
    imageOrigin(0),
    geoUnits(0),
    hemisphere(1),
    comments(""),
    attrVersion(0),
    controlPoints(0),
    reserved10(0),
    numSubtextures(0)
{
    of_mips[0]=of_mips[1]=of_mips[2]=of_mips[3]=of_mips[4]=of_mips[5]=of_mips[6]=of_mips[7]=0.0f;
}

AttrData::AttrData(const AttrData& attr, const osg::CopyOp& copyop) :
    osg::Object(attr,copyop),
    texels_u(attr.texels_u),
    texels_v(attr.texels_v),
    direction_u(attr.direction_u),
    direction_v(attr.direction_v),
    x_up(attr.x_up),
    y_up(attr.y_up),
    fileFormat(attr.fileFormat),
    minFilterMode(attr.minFilterMode),
    magFilterMode(attr.magFilterMode),
    wrapMode(attr.wrapMode),
    wrapMode_u(attr.wrapMode_u),
    wrapMode_v(attr.wrapMode_v),
    modifyFlag(attr.modifyFlag),
    pivot_x(attr.pivot_x),
    pivot_y(attr.pivot_y),
    texEnvMode(attr.texEnvMode),
    intensityAsAlpha(attr.intensityAsAlpha),
    size_u(attr.size_u),
    size_v(attr.size_v),
    originCode(attr.originCode),
    kernelVersion(attr.kernelVersion),
    intFormat(attr.intFormat),
    extFormat(attr.extFormat),

    useMips(attr.useMips),

    useLodScale(attr.useLodScale),
    lod0(attr.lod0),
    scale0(attr.scale0),
    lod1(attr.lod1),
    scale1(attr.scale1),
    lod2(attr.lod2),
    scale2(attr.scale2),
    lod3(attr.lod3),
    scale3(attr.scale3),
    lod4(attr.lod4),
    scale4(attr.scale4),
    lod5(attr.lod5),
    scale5(attr.scale5),
    lod6(attr.lod6),
    scale6(attr.scale6),
    lod7(attr.lod7),
    scale7(attr.scale7),

    clamp(attr.clamp),
    magFilterAlpha(attr.magFilterAlpha),
    magFilterColor(attr.magFilterColor),
    lambertMeridian(attr.lambertMeridian),
    lambertUpperLat(attr.lambertUpperLat),
    lambertlowerLat(attr.lambertlowerLat),
    useDetail(attr.useDetail),
    txDetail_j(attr.txDetail_j),
    txDetail_k(attr.txDetail_k),
    txDetail_m(attr.txDetail_m),
    txDetail_n(attr.txDetail_n),
    txDetail_s(attr.txDetail_s),
    useTile(attr.useTile),
    txTile_ll_u(attr.txTile_ll_u),
    txTile_ll_v(attr.txTile_ll_v),
    txTile_ur_u(attr.txTile_ur_u),
    txTile_ur_v(attr.txTile_ur_v),
    projection(attr.projection),
    earthModel(attr.earthModel),
    utmZone(attr.utmZone),
    imageOrigin(attr.imageOrigin),
    geoUnits(attr.geoUnits),
    hemisphere(attr.hemisphere),
    comments(attr.comments),
    attrVersion(attr.attrVersion),
    controlPoints(attr.controlPoints),
    reserved10(attr.reserved10),
    numSubtextures(attr.numSubtextures)
{

}<|endoftext|>