// Copyright 2012 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_ACCESSORS_H_
#define V8_ACCESSORS_H_

#include "include/v8.h"
#include "src/allocation.h"
#include "src/globals.h"
#include "src/property-details.h"

namespace v8 {
namespace internal {

// Forward declarations.
class AccessorInfo;
template <typename T>
class Handle;
class FieldIndex;
class JavaScriptFrame;

// The list of accessor descriptors. This is a second-order macro
// taking a macro to be applied to all accessor descriptor names.
#define ACCESSOR_INFO_LIST(V)                                       \
  V(arguments_iterator, ArgumentsIterator)                          \
  V(array_length, ArrayLength)                                      \
  V(bound_function_length, BoundFunctionLength)                     \
  V(bound_function_name, BoundFunctionName)                         \
  V(error_stack, ErrorStack)                                        \
  V(function_arguments, FunctionArguments)                          \
  V(function_caller, FunctionCaller)                                \
  V(function_name, FunctionName)                                    \
  V(function_length, FunctionLength)                                \
  V(function_prototype, FunctionPrototype)                          \
  V(reconfigure_to_data_property, ReconfigureToDataProperty)        \
  V(script_column_offset, ScriptColumnOffset)                       \
  V(script_compilation_type, ScriptCompilationType)                 \
  V(script_context_data, ScriptContextData)                         \
  V(script_eval_from_script, ScriptEvalFromScript)                  \
  V(script_eval_from_script_position, ScriptEvalFromScriptPosition) \
  V(script_eval_from_function_name, ScriptEvalFromFunctionName)     \
  V(script_id, ScriptId)                                            \
  V(script_line_offset, ScriptLineOffset)                           \
  V(script_name, ScriptName)                                        \
  V(script_source, ScriptSource)                                    \
  V(script_type, ScriptType)                                        \
  V(script_source_url, ScriptSourceUrl)                             \
  V(script_source_mapping_url, ScriptSourceMappingUrl)              \
  V(string_length, StringLength)

#define SIDE_EFFECT_FREE_ACCESSOR_INFO_LIST(V) \
  V(ArrayLength)                               \
  V(BoundFunctionLength)                       \
  V(BoundFunctionName)                         \
  V(FunctionName)                              \
  V(FunctionLength)                            \
  V(StringLength)

#define ACCESSOR_SETTER_LIST(V) \
  V(ArrayLengthSetter)          \
  V(ErrorStackSetter)           \
  V(FunctionPrototypeSetter)    \
  V(ModuleNamespaceEntrySetter) \
  V(ReconfigureToDataProperty)

// Accessors contains all predefined proxy accessors.

class Accessors : public AllStatic {
 public:
#define ACCESSOR_GETTER_DECLARATION(accessor_name, AccessorName) \
  static void AccessorName##Getter(                              \
      v8::Local<v8::Name> name,                                  \
      const v8::PropertyCallbackInfo<v8::Value>& info);
  ACCESSOR_INFO_LIST(ACCESSOR_GETTER_DECLARATION)
#undef ACCESSOR_GETTER_DECLARATION

#define ACCESSOR_SETTER_DECLARATION(accessor_name)          \
  static void accessor_name(                                \
      v8::Local<v8::Name> name, v8::Local<v8::Value> value, \
      const v8::PropertyCallbackInfo<v8::Boolean>& info);
  ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
#undef ACCESSOR_SETTER_DECLARATION

  static void ModuleNamespaceEntryGetter(
      v8::Local<v8::Name> name,
      const v8::PropertyCallbackInfo<v8::Value>& info);
  static Handle<AccessorInfo> MakeModuleNamespaceEntryInfo(Isolate* isolate,
                                                           Handle<String> name);

  // Accessor function called directly from the runtime system. Returns the
  // newly materialized arguments object for the given {frame}. Note that for
  // optimized frames it is possible to specify an {inlined_jsframe_index}.
  static Handle<JSObject> FunctionGetArguments(JavaScriptFrame* frame,
                                               int inlined_jsframe_index);

  // Returns true for properties that are accessors to object fields.
  // If true, the matching FieldIndex is returned through |field_index|.
  static bool IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
                                      FieldIndex* field_index);

  // Create an AccessorInfo. The setter is optional (can be nullptr).
  //
  // Note that the type of setter is AccessorNameBooleanSetterCallback instead
  // of v8::AccessorNameSetterCallback.  The difference is that the former can
  // set a (boolean) return value. The setter should roughly follow the same
  // conventions as many of the internal methods in objects.cc:
  // - The return value is unset iff there was an exception.
  // - If the ShouldThrow argument is true, the return value must not be false.
  typedef void (*AccessorNameBooleanSetterCallback)(
      Local<v8::Name> property, Local<v8::Value> value,
      const PropertyCallbackInfo<v8::Boolean>& info);

  static Handle<AccessorInfo> MakeAccessor(
      Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter,
      AccessorNameBooleanSetterCallback setter);

 private:
#define ACCESSOR_INFO_DECLARATION(accessor_name, AccessorName) \
  static Handle<AccessorInfo> Make##AccessorName##Info(Isolate* isolate);
  ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
#undef ACCESSOR_INFO_DECLARATION

  friend class Heap;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_ACCESSORS_H_
