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