// Copyright (c) 2017-2022 Cloudflare, Inc. // Licensed under the Apache 2.0 license found in the LICENSE file or at: // https://opensource.org/licenses/Apache-2.0 #pragma once // INTERNAL IMPLEMENTATION FILE #include #include namespace workerd::jsg { class Lock; template struct ArgumentIndexes_; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_&, Args...)> { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_&, Args...) const> { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_ { using Indexes = kj::_::MakeIndexes; }; template struct ArgumentIndexes_&, Args...)> { using Indexes = kj::_::MakeIndexes; }; template using ArgumentIndexes = ArgumentIndexes_::Indexes; // ArgumentIndexes expands to kj::_::Indexes<0, 1, 2, 3, ..., n-1>, where n is the // number of arguments to the method, not counting the magic Lock or FunctionCallbackInfo parameter // (if any). // ======================================================================================= // requiredArgumentCount — counts leading required JS-visible arguments. // // Used by resource.h to set the Web IDL .length property on functions. // // Argument filtering is split across two layers for dependency reasons: // // 1. StripMagicParam_ (here in meta.h) removes the leading Lock& or // FunctionCallbackInfo& parameter. These are C++/V8 plumbing that always // appear first and are never JS-visible. meta.h can handle them because // it only needs the v8 forward declarations it already includes. // // 2. RequiredArgCount_ (in type-wrapper.h) skips all "injected" parameter // types that don't consume a JS argument. It uses the ValueLessParameter // concept to automatically detect types like TypeHandler and // InjectConfiguration types (e.g. CompatibilityFlags::Reader), plus // isArguments<>() for variadic Arguments. The TypeWrapper template // parameter is required because ValueLessParameter checks whether the // wrapper has a 3-arg unwrap(js, context, T*) overload for the type. // Lightweight type list; kj::Tuple is an alias template and cannot be partially specialized. template struct TypeList {}; namespace detail { // Phase 1: Normalize member-function-pointer or free-function type to Ret(Args...). template struct NormalizeFunc_; template struct NormalizeFunc_ { using type = R(A...); }; template struct NormalizeFunc_ { using type = R(A...); }; template struct NormalizeFunc_ { using type = R(A...); }; // Phase 2: Strip leading Lock& / FunctionCallbackInfo& and yield the JS-visible args. // See the comment above for why this is separate from RequiredArgCount_. template struct StripMagicParam_; template struct StripMagicParam_ { using Args = TypeList; }; template struct StripMagicParam_ { using Args = TypeList; }; template struct StripMagicParam_&, A...)> { using Args = TypeList; }; template using MethodArgs = StripMagicParam_::type>; // Forward declaration — specialized in type-wrapper.h where ValueLessParameter is visible. template struct RequiredArgCount_; } // namespace detail // Per Web IDL, the .length of a function is the number of leading required arguments. // The actual counting logic lives in type-wrapper.h (needs the ValueLessParameter concept). template inline constexpr int requiredArgumentCount = detail::RequiredArgCount_::Args>::value; } // namespace workerd::jsg