/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_
#define ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_

#include "base/macros.h"
#include "art_method.h"

#include <stdint.h>

namespace art {
namespace lambda {

class ArtLambdaMethod {
 public:
  // Construct an art lambda method.
  // The target method is the one invoked by invoke-lambda.
  // The type descriptor describes the types of variables captured, e.g. "ZFLObject;\FI;[Z"
  // The shorty drops the object name and treats arrays as objects, e.g. "ZFL\L"
  // Innate lambda means that the lambda was originally created via invoke-lambda.
  // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda.
  // (Ownership of strings is retained by the caller and the lifetime should exceed this class).
  ArtLambdaMethod(ArtMethod* target_method,
                  const char* captured_variables_type_descriptor,
                  const char* captured_variables_shorty,
                  bool innate_lambda = true);

  // Get the target method for this lambda that would be used by the invoke-lambda dex instruction.
  ArtMethod* GetArtMethod() const {
    return method_;
  }

  // Get the compile-time size of lambda closures for this method in bytes.
  // This is circular (that is, it includes the size of the ArtLambdaMethod pointer).
  // One should also check if the size is dynamic since nested lambdas have a runtime size.
  size_t GetStaticClosureSize() const {
    return closure_size_;
  }

  // Get the type descriptor for the list of captured variables.
  // e.g. "ZFLObject;\FI;[Z" means a captured int, float, class Object, lambda FI, array of ints
  const char* GetCapturedVariablesTypeDescriptor() const {
    return captured_variables_type_descriptor_;
  }

  // Get the shorty 'field' type descriptor list of captured variables.
  // This follows the same rules as a string of ShortyFieldType in the dex specification.
  // Every captured variable is represented by exactly one character.
  // - Objects become 'L'.
  // - Arrays become 'L'.
  // - Lambdas become '\'.
  const char* GetCapturedVariablesShortyTypeDescriptor() const {
    return captured_variables_shorty_;
  }

  // Will the size of this lambda change at runtime?
  // Only returns true if there is a nested lambda that we can't determine statically the size of.
  bool IsDynamicSize() const {
    return dynamic_size_;
  }

  // Will the size of this lambda always be constant at runtime?
  // This generally means there's no nested lambdas, or we were able to successfully determine
  // their size statically at compile time.
  bool IsStaticSize() const {
    return !IsDynamicSize();
  }
  // Is this a lambda that was originally created via invoke-lambda?
  // -- Non-innate lambdas (learned lambdas) come from a regular class that was boxed to lambda.
  bool IsInnateLambda() const {
    return innate_lambda_;
  }

  // How many variables were captured?
  // (Each nested lambda counts as 1 captured var regardless of how many captures it itself has).
  size_t GetNumberOfCapturedVariables() const {
    return strlen(captured_variables_shorty_);
  }

  // Return the offset in bytes from the start of ArtLambdaMethod to the method_.
  // -- Only should be used by assembly (stubs) support code and compiled code.
  static constexpr size_t GetArtMethodOffset() {
    return offsetof(ArtLambdaMethod, method_);
  }

  // Calculate how many vregs all the arguments will use when doing an invoke.
  // (Most primitives are 1 vregs, double/long are 2, reference is 1, lambda is 2).
  // -- This is used to know how big to set up shadow frame when invoking into the target method.
  size_t GetArgumentVRegCount() const SHARED_REQUIRES(Locks::mutator_lock_);

 private:
  // TODO: ArtMethod, or at least the entry points should be inlined into this struct
  // to avoid an extra indirect load when doing invokes.
  // Target method that invoke-lambda will jump to.
  ArtMethod* method_;
  // How big the closure is (in bytes). Only includes the constant size.
  size_t closure_size_;
  // The type descriptor for the captured variables, e.g. "IS" for [int, short]
  const char* captured_variables_type_descriptor_;
  // The shorty type descriptor for captured vars, (e.g. using 'L' instead of 'LObject;')
  const char* captured_variables_shorty_;
  // Whether or not the size is dynamic. If it is, copiers need to read the Closure size at runtime.
  bool dynamic_size_;
  // True if this lambda was originally made with create-lambda,
  // false if it came from a class instance (through new-instance and then unbox-lambda).
  bool innate_lambda_;

  DISALLOW_COPY_AND_ASSIGN(ArtLambdaMethod);
};

}  // namespace lambda
}  // namespace art

#endif  // ART_RUNTIME_LAMBDA_ART_LAMBDA_METHOD_H_
