// Copyright 2016 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_API_API_ARGUMENTS_H_ #define V8_API_API_ARGUMENTS_H_ #include "include/v8-template.h" #include "src/api/api.h" #include "src/debug/debug.h" #include "src/execution/isolate.h" #include "src/objects/slots.h" #include "src/objects/visitors.h" namespace v8 { namespace internal { // Custom arguments replicate a small segment of stack that can be // accessed through an Arguments object the same way the actual stack // can. class CustomArgumentsBase : public Relocatable { protected: explicit inline CustomArgumentsBase(Isolate* isolate); }; template class CustomArguments : public CustomArgumentsBase { public: static const int kReturnValueOffset = T::kReturnValueIndex; ~CustomArguments() override; inline void IterateInstance(RootVisitor* v) override { v->VisitRootPointers(Root::kRelocatable, nullptr, slot_at(0), slot_at(T::kArgsLength)); } protected: explicit inline CustomArguments(Isolate* isolate) : CustomArgumentsBase(isolate) {} template Handle GetReturnValue(Isolate* isolate); inline Isolate* isolate() { return reinterpret_cast((*slot_at(T::kIsolateIndex)).ptr()); } inline FullObjectSlot slot_at(int index) { // This allows index == T::kArgsLength so "one past the end" slots // can be retrieved for iterating purposes. DCHECK_LE(static_cast(index), static_cast(T::kArgsLength)); return FullObjectSlot(values_ + index); } Address values_[T::kArgsLength]; }; // Note: Calling args.Call() sets the return value on args. For multiple // Call()'s, a new args should be used every time. class PropertyCallbackArguments : public CustomArguments > { public: using T = PropertyCallbackInfo; using Super = CustomArguments; static const int kArgsLength = T::kArgsLength; static const int kThisIndex = T::kThisIndex; static const int kHolderIndex = T::kHolderIndex; static const int kDataIndex = T::kDataIndex; static const int kReturnValueDefaultValueIndex = T::kReturnValueDefaultValueIndex; static const int kIsolateIndex = T::kIsolateIndex; static const int kShouldThrowOnErrorIndex = T::kShouldThrowOnErrorIndex; PropertyCallbackArguments(Isolate* isolate, Object data, Object self, JSObject holder, Maybe should_throw); // Don't copy PropertyCallbackArguments, because they would both have the // same prev_ pointer. PropertyCallbackArguments(const PropertyCallbackArguments&) = delete; PropertyCallbackArguments& operator=(const PropertyCallbackArguments&) = delete; // ------------------------------------------------------------------------- // Accessor Callbacks // Also used for AccessorSetterCallback. inline Handle CallAccessorSetter(Handle info, Handle name, Handle value); // Also used for AccessorGetterCallback, AccessorNameGetterCallback. inline Handle CallAccessorGetter(Handle info, Handle name); // ------------------------------------------------------------------------- // Named Interceptor Callbacks inline Handle CallNamedQuery(Handle interceptor, Handle name); inline Handle CallNamedGetter(Handle interceptor, Handle name); inline Handle CallNamedSetter(Handle interceptor, Handle name, Handle value); inline Handle CallNamedDefiner(Handle interceptor, Handle name, const v8::PropertyDescriptor& desc); inline Handle CallNamedDeleter(Handle interceptor, Handle name); inline Handle CallNamedDescriptor(Handle interceptor, Handle name); inline Handle CallNamedEnumerator( Handle interceptor); // ------------------------------------------------------------------------- // Indexed Interceptor Callbacks inline Handle CallIndexedQuery(Handle interceptor, uint32_t index); inline Handle CallIndexedGetter(Handle interceptor, uint32_t index); inline Handle CallIndexedSetter(Handle interceptor, uint32_t index, Handle value); inline Handle CallIndexedDefiner(Handle interceptor, uint32_t index, const v8::PropertyDescriptor& desc); inline Handle CallIndexedDeleter(Handle interceptor, uint32_t index); inline Handle CallIndexedDescriptor( Handle interceptor, uint32_t index); inline Handle CallIndexedEnumerator( Handle interceptor); private: /* * The following Call functions wrap the calling of all callbacks to handle * calling either the old or the new style callbacks depending on which one * has been registered. * For old callbacks which return an empty handle, the ReturnValue is checked * and used if it's been set to anything inside the callback. * New style callbacks always use the return value. */ inline Handle CallPropertyEnumerator( Handle interceptor); inline Handle BasicCallIndexedGetterCallback( IndexedPropertyGetterCallback f, uint32_t index, Handle info); inline Handle BasicCallNamedGetterCallback( GenericNamedPropertyGetterCallback f, Handle name, Handle info, Handle receiver = Handle()); inline JSObject holder(); inline Object receiver(); }; class FunctionCallbackArguments : public CustomArguments > { public: using T = FunctionCallbackInfo; using Super = CustomArguments; static const int kArgsLength = T::kArgsLength; static const int kHolderIndex = T::kHolderIndex; static const int kDataIndex = T::kDataIndex; static const int kReturnValueDefaultValueIndex = T::kReturnValueDefaultValueIndex; static const int kIsolateIndex = T::kIsolateIndex; static const int kNewTargetIndex = T::kNewTargetIndex; FunctionCallbackArguments(Isolate* isolate, Object data, HeapObject callee, Object holder, HeapObject new_target, Address* argv, int argc); /* * The following Call function wraps the calling of all callbacks to handle * calling either the old or the new style callbacks depending on which one * has been registered. * For old callbacks which return an empty handle, the ReturnValue is checked * and used if it's been set to anything inside the callback. * New style callbacks always use the return value. */ inline Handle Call(CallHandlerInfo handler); private: inline JSReceiver holder(); internal::Address* argv_; int argc_; }; } // namespace internal } // namespace v8 #endif // V8_API_API_ARGUMENTS_H_