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