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 
21 // The list of accessor descriptors. This is a second-order macro
22 // taking a macro to be applied to all accessor descriptor names.
23 #define ACCESSOR_INFO_LIST(V)     \
24   V(ArgumentsIterator)            \
25   V(ArrayLength)                  \
26   V(BoundFunctionLength)          \
27   V(BoundFunctionName)            \
28   V(ErrorStack)                   \
29   V(FunctionArguments)            \
30   V(FunctionCaller)               \
31   V(FunctionName)                 \
32   V(FunctionLength)               \
33   V(FunctionPrototype)            \
34   V(ScriptColumnOffset)           \
35   V(ScriptCompilationType)        \
36   V(ScriptContextData)            \
37   V(ScriptEvalFromScript)         \
38   V(ScriptEvalFromScriptPosition) \
39   V(ScriptEvalFromFunctionName)   \
40   V(ScriptId)                     \
41   V(ScriptLineOffset)             \
42   V(ScriptName)                   \
43   V(ScriptSource)                 \
44   V(ScriptType)                   \
45   V(ScriptSourceUrl)              \
46   V(ScriptSourceMappingUrl)       \
47   V(StringLength)
48 
49 #define ACCESSOR_SETTER_LIST(V) \
50   V(ArrayLengthSetter)          \
51   V(ErrorStackSetter)           \
52   V(FunctionPrototypeSetter)    \
53   V(ModuleNamespaceEntrySetter) \
54   V(ReconfigureToDataProperty)
55 
56 // Accessors contains all predefined proxy accessors.
57 
58 class Accessors : public AllStatic {
59  public:
60   // Accessor descriptors.
61 #define ACCESSOR_INFO_DECLARATION(name)                   \
62   static void name##Getter(                               \
63       v8::Local<v8::Name> name,                           \
64       const v8::PropertyCallbackInfo<v8::Value>& info);   \
65   static Handle<AccessorInfo> name##Info(                 \
66       Isolate* isolate,                                   \
67       PropertyAttributes attributes);
68   ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
69 #undef ACCESSOR_INFO_DECLARATION
70 
71 #define ACCESSOR_SETTER_DECLARATION(name)                                \
72   static void name(v8::Local<v8::Name> name, v8::Local<v8::Value> value, \
73                    const v8::PropertyCallbackInfo<v8::Boolean>& info);
74   ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
75 #undef ACCESSOR_SETTER_DECLARATION
76 
77   static void ModuleNamespaceEntryGetter(
78       v8::Local<v8::Name> name,
79       const v8::PropertyCallbackInfo<v8::Value>& info);
80   static Handle<AccessorInfo> ModuleNamespaceEntryInfo(
81       Isolate* isolate, Handle<String> name, PropertyAttributes attributes);
82 
83   enum DescriptorId {
84 #define ACCESSOR_INFO_DECLARATION(name) \
85     k##name##Getter, \
86     k##name##Setter,
87   ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
88 #undef ACCESSOR_INFO_DECLARATION
89     descriptorCount
90   };
91 
92   // Accessor functions called directly from the runtime system.
93   MUST_USE_RESULT static MaybeHandle<Object> FunctionSetPrototype(
94       Handle<JSFunction> object, Handle<Object> value);
95   static Handle<JSObject> FunctionGetArguments(Handle<JSFunction> object);
96 
97   // Returns true for properties that are accessors to object fields.
98   // If true, *object_offset contains offset of object field.
99   static bool IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
100                                       int* object_offset);
101 
102   // Create an AccessorInfo. The setter is optional (can be nullptr).
103   //
104   // Note that the type of setter is AccessorNameBooleanSetterCallback instead
105   // of v8::AccessorNameSetterCallback.  The difference is that the former can
106   // set a (boolean) return value. The setter should roughly follow the same
107   // conventions as many of the internal methods in objects.cc:
108   // - The return value is unset iff there was an exception.
109   // - If the ShouldThrow argument is true, the return value must not be false.
110   typedef void (*AccessorNameBooleanSetterCallback)(
111       Local<v8::Name> property, Local<v8::Value> value,
112       const PropertyCallbackInfo<v8::Boolean>& info);
113 
114   static Handle<AccessorInfo> MakeAccessor(
115       Isolate* isolate, Handle<Name> name, AccessorNameGetterCallback getter,
116       AccessorNameBooleanSetterCallback setter, PropertyAttributes attributes);
117 };
118 
119 }  // namespace internal
120 }  // namespace v8
121 
122 #endif  // V8_ACCESSORS_H_
123