// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
#define V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_

#include "src/base/flags.h"
#include "src/compiler/graph-reducer.h"
#include "src/deoptimize-reason.h"
#include "src/objects/map.h"

namespace v8 {
namespace internal {

// Forward declarations.
class CompilationDependencies;
class Factory;
class FeedbackNexus;

namespace compiler {

// Forward declarations.
enum class AccessMode;
class CommonOperatorBuilder;
class ElementAccessInfo;
class JSGraph;
class JSOperatorBuilder;
class MachineOperatorBuilder;
class PropertyAccessInfo;
class SimplifiedOperatorBuilder;
class TypeCache;

// Specializes a given JSGraph to a given native context, potentially constant
// folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
// nodes.  And also specializes {LoadNamed} and {StoreNamed} nodes according
// to type feedback (if available).
class JSNativeContextSpecialization final : public AdvancedReducer {
 public:
  // Flags that control the mode of operation.
  enum Flag {
    kNoFlags = 0u,
    kAccessorInliningEnabled = 1u << 0,
    kBailoutOnUninitialized = 1u << 1
  };
  typedef base::Flags<Flag> Flags;

  JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
                                Handle<Context> native_context,
                                CompilationDependencies* dependencies,
                                Zone* zone);

  const char* reducer_name() const override {
    return "JSNativeContextSpecialization";
  }

  Reduction Reduce(Node* node) final;

 private:
  Reduction ReduceJSAdd(Node* node);
  Reduction ReduceJSGetSuperConstructor(Node* node);
  Reduction ReduceJSInstanceOf(Node* node);
  Reduction ReduceJSHasInPrototypeChain(Node* node);
  Reduction ReduceJSOrdinaryHasInstance(Node* node);
  Reduction ReduceJSLoadContext(Node* node);
  Reduction ReduceJSLoadGlobal(Node* node);
  Reduction ReduceJSStoreGlobal(Node* node);
  Reduction ReduceJSLoadNamed(Node* node);
  Reduction ReduceJSStoreNamed(Node* node);
  Reduction ReduceJSLoadProperty(Node* node);
  Reduction ReduceJSStoreProperty(Node* node);
  Reduction ReduceJSStoreNamedOwn(Node* node);
  Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);

  Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
                                MapHandles const& receiver_maps,
                                AccessMode access_mode,
                                KeyedAccessLoadMode load_mode,
                                KeyedAccessStoreMode store_mode);
  template <typename KeyedICNexus>
  Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
                              KeyedICNexus const& nexus, AccessMode access_mode,
                              KeyedAccessLoadMode load_mode,
                              KeyedAccessStoreMode store_mode);
  Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
                                       FeedbackNexus const& nexus,
                                       Handle<Name> name,
                                       AccessMode access_mode);
  Reduction ReduceNamedAccess(Node* node, Node* value,
                              MapHandles const& receiver_maps,
                              Handle<Name> name, AccessMode access_mode,
                              Node* index = nullptr);
  Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
                               Handle<Name> name, AccessMode access_mode,
                               Node* index = nullptr);

  Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);

  // A triple of nodes that represents a continuation.
  class ValueEffectControl final {
   public:
    ValueEffectControl()
        : value_(nullptr), effect_(nullptr), control_(nullptr) {}
    ValueEffectControl(Node* value, Node* effect, Node* control)
        : value_(value), effect_(effect), control_(control) {}

    Node* value() const { return value_; }
    Node* effect() const { return effect_; }
    Node* control() const { return control_; }

   private:
    Node* value_;
    Node* effect_;
    Node* control_;
  };

  // Construct the appropriate subgraph for property access.
  ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
                                         Node* context, Node* frame_state,
                                         Node* effect, Node* control,
                                         Handle<Name> name,
                                         ZoneVector<Node*>* if_exceptions,
                                         PropertyAccessInfo const& access_info,
                                         AccessMode access_mode);
  ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context,
                                       Node* frame_state, Node* effect,
                                       Node* control, Handle<Name> name,
                                       ZoneVector<Node*>* if_exceptions,
                                       PropertyAccessInfo const& access_info);

  ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
                                        Node* context, Node* frame_state,
                                        Node* effect, Node* control,
                                        Handle<Name> name,
                                        ZoneVector<Node*>* if_exceptions,
                                        PropertyAccessInfo const& access_info,
                                        AccessMode access_mode);

  // Helpers for accessor inlining.
  Node* InlinePropertyGetterCall(Node* receiver, Node* context,
                                 Node* frame_state, Node** effect,
                                 Node** control,
                                 ZoneVector<Node*>* if_exceptions,
                                 PropertyAccessInfo const& access_info);
  void InlinePropertySetterCall(Node* receiver, Node* value, Node* context,
                                Node* frame_state, Node** effect,
                                Node** control,
                                ZoneVector<Node*>* if_exceptions,
                                PropertyAccessInfo const& access_info);
  Node* InlineApiCall(Node* receiver, Node* holder, Node* frame_state,
                      Node* value, Node** effect, Node** control,
                      Handle<SharedFunctionInfo> shared_info,
                      Handle<FunctionTemplateInfo> function_template_info);

  // Construct the appropriate subgraph for element access.
  ValueEffectControl BuildElementAccess(
      Node* receiver, Node* index, Node* value, Node* effect, Node* control,
      ElementAccessInfo const& access_info, AccessMode access_mode,
      KeyedAccessLoadMode load_mode, KeyedAccessStoreMode store_mode);

  // Construct appropriate subgraph to load from a String.
  Node* BuildIndexedStringLoad(Node* receiver, Node* index, Node* length,
                               Node** effect, Node** control,
                               KeyedAccessLoadMode load_mode);

  // Construct appropriate subgraph to extend properties backing store.
  Node* BuildExtendPropertiesBackingStore(Handle<Map> map, Node* properties,
                                          Node* effect, Node* control);

  // Construct appropriate subgraph to check that the {value} matches
  // the previously recorded {name} feedback.
  Node* BuildCheckEqualsName(Handle<Name> name, Node* value, Node* effect,
                             Node* control);

  // Checks if we can turn the hole into undefined when loading an element
  // from an object with one of the {receiver_maps}; sets up appropriate
  // code dependencies and might use the array protector cell.
  bool CanTreatHoleAsUndefined(MapHandles const& receiver_maps);

  // Extract receiver maps from {nexus} and filter based on {receiver} if
  // possible.
  bool ExtractReceiverMaps(Node* receiver, Node* effect,
                           FeedbackNexus const& nexus,
                           MapHandles* receiver_maps);

  // Try to infer maps for the given {receiver} at the current {effect}.
  // If maps are returned then you can be sure that the {receiver} definitely
  // has one of the returned maps at this point in the program (identified
  // by {effect}).
  bool InferReceiverMaps(Node* receiver, Node* effect,
                         MapHandles* receiver_maps);
  // Try to infer a root map for the {receiver} independent of the current
  // program location.
  MaybeHandle<Map> InferReceiverRootMap(Node* receiver);

  // Checks if we know at compile time that the {receiver} either definitely
  // has the {prototype} in it's prototype chain, or the {receiver} definitely
  // doesn't have the {prototype} in it's prototype chain.
  enum InferHasInPrototypeChainResult {
    kIsInPrototypeChain,
    kIsNotInPrototypeChain,
    kMayBeInPrototypeChain
  };
  InferHasInPrototypeChainResult InferHasInPrototypeChain(
      Node* receiver, Node* effect, Handle<HeapObject> prototype);

  // Script context lookup logic.
  struct ScriptContextTableLookupResult;
  bool LookupInScriptContextTable(Handle<Name> name,
                                  ScriptContextTableLookupResult* result);

  Graph* graph() const;
  JSGraph* jsgraph() const { return jsgraph_; }
  Isolate* isolate() const;
  Factory* factory() const;
  CommonOperatorBuilder* common() const;
  JSOperatorBuilder* javascript() const;
  SimplifiedOperatorBuilder* simplified() const;
  Flags flags() const { return flags_; }
  Handle<JSGlobalObject> global_object() const { return global_object_; }
  Handle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
  Handle<Context> native_context() const { return native_context_; }
  CompilationDependencies* dependencies() const { return dependencies_; }
  Zone* zone() const { return zone_; }

  JSGraph* const jsgraph_;
  Flags const flags_;
  Handle<JSGlobalObject> global_object_;
  Handle<JSGlobalProxy> global_proxy_;
  Handle<Context> native_context_;
  CompilationDependencies* const dependencies_;
  Zone* const zone_;
  TypeCache const& type_cache_;

  DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
};

DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)

}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
