• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_ACCESSORS_H_
6 #define V8_ACCESSORS_H_
7 
8 #include "include/v8.h"
9 #include "src/allocation.h"
10 #include "src/globals.h"
11 #include "src/property-details.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 // Forward declarations.
17 class AccessorInfo;
18 template <typename T>
19 class Handle;
20 class FieldIndex;
21 class JavaScriptFrame;
22 
23 // The list of accessor descriptors. This is a second-order macro
24 // taking a macro to be applied to all accessor descriptor names.
25 #define ACCESSOR_INFO_LIST(V)                                       \
26   V(arguments_iterator, ArgumentsIterator)                          \
27   V(array_length, ArrayLength)                                      \
28   V(bound_function_length, BoundFunctionLength)                     \
29   V(bound_function_name, BoundFunctionName)                         \
30   V(error_stack, ErrorStack)                                        \
31   V(function_arguments, FunctionArguments)                          \
32   V(function_caller, FunctionCaller)                                \
33   V(function_name, FunctionName)                                    \
34   V(function_length, FunctionLength)                                \
35   V(function_prototype, FunctionPrototype)                          \
36   V(string_length, StringLength)
37 
38 #define SIDE_EFFECT_FREE_ACCESSOR_INFO_LIST(V) \
39   V(ArrayLength)                               \
40   V(BoundFunctionLength)                       \
41   V(BoundFunctionName)                         \
42   V(FunctionName)                              \
43   V(FunctionLength)                            \
44   V(FunctionPrototype)                         \
45   V(StringLength)
46 
47 #define ACCESSOR_SETTER_LIST(V) \
48   V(ArrayLengthSetter)          \
49   V(ErrorStackSetter)           \
50   V(FunctionPrototypeSetter)    \
51   V(ModuleNamespaceEntrySetter) \
52   V(ReconfigureToDataProperty)
53 
54 // Accessors contains all predefined proxy accessors.
55 
56 class Accessors : public AllStatic {
57  public:
58 #define ACCESSOR_GETTER_DECLARATION(accessor_name, AccessorName) \
59   static void AccessorName##Getter(                              \
60       v8::Local<v8::Name> name,                                  \
61       const v8::PropertyCallbackInfo<v8::Value>& info);
62   ACCESSOR_INFO_LIST(ACCESSOR_GETTER_DECLARATION)
63 #undef ACCESSOR_GETTER_DECLARATION
64 
65 #define ACCESSOR_SETTER_DECLARATION(accessor_name)          \
66   static void accessor_name(                                \
67       v8::Local<v8::Name> name, v8::Local<v8::Value> value, \
68       const v8::PropertyCallbackInfo<v8::Boolean>& info);
69   ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
70 #undef ACCESSOR_SETTER_DECLARATION
71 
72   static constexpr int kAccessorInfoCount =
73 #define COUNT_ACCESSOR(...) +1
74       ACCESSOR_INFO_LIST(COUNT_ACCESSOR);
75 #undef COUNT_ACCESSOR
76 
77   static constexpr int kAccessorSetterCount =
78 #define COUNT_ACCESSOR(...) +1
79       ACCESSOR_SETTER_LIST(COUNT_ACCESSOR);
80 #undef COUNT_ACCESSOR
81 
82   static void ModuleNamespaceEntryGetter(
83       v8::Local<v8::Name> name,
84       const v8::PropertyCallbackInfo<v8::Value>& info);
85   static Handle<AccessorInfo> MakeModuleNamespaceEntryInfo(Isolate* isolate,
86                                                            Handle<String> name);
87 
88   // Accessor function called directly from the runtime system. Returns the
89   // newly materialized arguments object for the given {frame}. Note that for
90   // optimized frames it is possible to specify an {inlined_jsframe_index}.
91   static Handle<JSObject> FunctionGetArguments(JavaScriptFrame* frame,
92                                                int inlined_jsframe_index);
93 
94   // Returns true for properties that are accessors to object fields.
95   // If true, the matching FieldIndex is returned through |field_index|.
96   static bool IsJSObjectFieldAccessor(Isolate* isolate, Handle<Map> map,
97                                       Handle<Name> name,
98                                       FieldIndex* field_index);
99 
100   static MaybeHandle<Object> ReplaceAccessorWithDataProperty(
101       Handle<Object> receiver, Handle<JSObject> holder, Handle<Name> name,
102       Handle<Object> value);
103 
104   // Create an AccessorInfo. The setter is optional (can be nullptr).
105   //
106   // Note that the type of setter is AccessorNameBooleanSetterCallback instead
107   // of v8::AccessorNameSetterCallback.  The difference is that the former can
108   // set a (boolean) return value. The setter should roughly follow the same
109   // conventions as many of the internal methods in objects.cc:
110   // - The return value is unset iff there was an exception.
111   // - If the ShouldThrow argument is true, the return value must not be false.
112   typedef void (*AccessorNameBooleanSetterCallback)(
113       Local<v8::Name> property, Local<v8::Value> value,
114       const PropertyCallbackInfo<v8::Boolean>& info);
115 
116   static Handle<AccessorInfo> MakeAccessor(
117       Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter,
118       AccessorNameBooleanSetterCallback setter);
119 
120  private:
121 #define ACCESSOR_INFO_DECLARATION(accessor_name, AccessorName) \
122   static Handle<AccessorInfo> Make##AccessorName##Info(Isolate* isolate);
123   ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
124 #undef ACCESSOR_INFO_DECLARATION
125 
126   friend class Heap;
127 };
128 
129 }  // namespace internal
130 }  // namespace v8
131 
132 #endif  // V8_ACCESSORS_H_
133