| // Copyright 2018 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. |
| |
| @export |
| struct Arguments { |
| const frame: FrameWithArguments; |
| const base: RawPtr; |
| const length: intptr; |
| } |
| |
| extern operator '[]' macro GetArgumentValue(Arguments, intptr): JSAny; |
| extern macro GetFrameArguments(FrameWithArguments, intptr): Arguments; |
| const kNoArgumentsAdaptor: |
| constexpr bool generates 'kNoArgumentsAdaptor'; |
| |
| struct ArgumentsIterator { |
| macro Next(): Object labels NoMore { |
| if (this.current == this.arguments.length) goto NoMore; |
| return this.arguments[this.current++]; |
| } |
| const arguments: Arguments; |
| current: intptr; |
| } |
| |
| struct FrameWithArgumentsInfo { |
| const frame: FrameWithArguments; |
| const argument_count: bint; |
| const formal_parameter_count: bint; |
| } |
| |
| // Calculates and returns the frame pointer, argument count and formal |
| // parameter count to be used to access a function's parameters, taking |
| // argument adapter frames into account. |
| // |
| // TODO(danno): |
| // This macro is should only be used in builtins that can be called from |
| // interpreted or JITted code, not from CSA/Torque builtins (the number of |
| // returned formal parameters would be wrong). |
| // It is difficult to actually check/assert this, since interpreted or JITted |
| // frames are StandardFrames, but so are hand-written builtins. Doing that |
| // more refined check would be prohibitively expensive. |
| macro GetFrameWithArgumentsInfo(implicit context: Context)(): |
| FrameWithArgumentsInfo { |
| const frame = |
| Cast<StandardFrame>(LoadParentFramePointer()) otherwise unreachable; |
| const f: JSFunction = frame.function; |
| |
| const shared: SharedFunctionInfo = f.shared_function_info; |
| const formalParameterCount: bint = |
| Convert<bint>(Convert<int32>(shared.formal_parameter_count)); |
| if constexpr (kNoArgumentsAdaptor) { |
| // TODO(victorgomes): When removing the v8_disable_arguments_adaptor flag, |
| // FrameWithArgumentsInfo can be simplified, since the frame field already |
| // contains the argument count. |
| const argumentCount: bint = Convert<bint>(frame.argument_count); |
| return FrameWithArgumentsInfo{ |
| frame, |
| argument_count: argumentCount, |
| formal_parameter_count: formalParameterCount |
| }; |
| } else { |
| const argumentCount: bint = formalParameterCount; |
| |
| const adaptor = Cast<ArgumentsAdaptorFrame>(frame.caller) |
| otherwise return FrameWithArgumentsInfo{ |
| frame, |
| argument_count: argumentCount, |
| formal_parameter_count: formalParameterCount |
| }; |
| |
| return FrameWithArgumentsInfo{ |
| frame: adaptor, |
| argument_count: Convert<bint>(adaptor.length), |
| formal_parameter_count: formalParameterCount |
| }; |
| } |
| } |