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