Skip to main content

ParamList

Struct ParamList 

Source
pub struct ParamList {
    pub params: Vec<Param>,
    pub ignore_extra: bool,
}
Expand description

The dynamic-call signature of a function or an import: what lets a dcall or dcall_shape pass named, spread, extra, missing, and by-reference arguments (specs/LSB.md §5.15).

The list describes the signature’s parameters in order. When any parameter has a default, the signature has one more parameter, an i64 presence mask: bit i is set when parameter i received an argument, so the callee computes the defaults of the others itself (PHP’s and Python’s defaults are expressions). A callee without a list binds as if it had one positional-only parameter per signature parameter: exact arity, positional arguments only.

§Examples

use bytecode_lang::{Param, ParamKind, ParamList, StrId};

// PHP: function f($a, &$b = null, ...$rest)
let list = ParamList::new(vec![
    Param::normal(StrId(0)),
    Param::normal(StrId(1)).by_ref().with_default(),
    Param::new(ParamKind::RestMap, Some(StrId(2))),
]);
assert!(list.validate().is_ok());
assert!(list.has_defaults());
assert_eq!(list.signature_len(), 4); // three parameters and the presence mask
assert!(list.positional_by_ref(1));
assert!(!list.positional_by_ref(7)); // a rest argument, by value

Fields§

§params: Vec<Param>

The parameters, in signature order.

§ignore_extra: bool

Extra positional arguments with no rest parameter to take them are dropped instead of raising ArgumentError (PHP user functions, which see them only through func_get_args).

Implementations§

Source§

impl ParamList

Source

pub fn new(params: Vec<Param>) -> Self

A list of these parameters that raises on extra arguments.

§Examples
use bytecode_lang::{Param, ParamList, StrId};

let list = ParamList::new(vec![Param::normal(StrId(0))]);
assert!(!list.ignore_extra);
Source

pub fn ignoring_extra(self) -> Self

This list, dropping extra positional arguments (PHP user functions).

§Examples
use bytecode_lang::ParamList;

assert!(ParamList::new(vec![]).ignoring_extra().ignore_extra);
Source

pub fn has_defaults(&self) -> bool

Whether any parameter has a default, so the signature ends with the presence mask.

§Examples
use bytecode_lang::{Param, ParamList, StrId};

assert!(!ParamList::new(vec![Param::normal(StrId(0))]).has_defaults());
Source

pub fn signature_len(&self) -> usize

The number of signature parameters the list describes: one per entry, plus the presence mask when a parameter has a default.

§Examples
use bytecode_lang::{Param, ParamList, StrId};

let list = ParamList::new(vec![Param::normal(StrId(0)).with_default()]);
assert_eq!(list.signature_len(), 2);
Source

pub fn validate(&self) -> Result<(), ParamError>

Checks the list’s own rules: at most 255 parameters (64 with defaults); kinds in order (positional-only, normal, one rest, named-only, one named rest); normal and named-only parameters named; names unique; no default on a rest parameter.

§Errors

The first rule broken, as a ParamError.

§Examples
use bytecode_lang::{Param, ParamError, ParamKind, ParamList, StrId};

let rest_first = ParamList::new(vec![
    Param::new(ParamKind::Rest, None),
    Param::normal(StrId(0)),
]);
assert_eq!(rest_first.validate(), Err(ParamError::OutOfOrder { index: 1 }));
Source

pub fn fits(&self, sig_params: &[ValType]) -> Result<(), ParamError>

Checks that the list fits a signature with parameter types sig_params: one parameter per entry plus a trailing i64 presence mask when an entry has a default; rest parameters dyn; by-reference parameters dyn or ref (the verifier checks that the ref is a cell dyn).

§Errors

ParamError::Signature naming the first parameter that does not fit.

§Examples
use bytecode_lang::{Param, ParamError, ParamKind, ParamList, StrId, ValType};

let list = ParamList::new(vec![Param::new(ParamKind::Rest, None)]);
assert!(list.fits(&[ValType::Dyn]).is_ok());
assert_eq!(list.fits(&[ValType::I64]), Err(ParamError::Signature { index: 0 }));
Source

pub fn positional_by_ref(&self, pos: u64) -> bool

Whether a positional argument at 0-based position pos would be taken by reference: the semantics of dparam_ref (PHP decides before evaluating each argument of a dynamic call whether to send a reference). Positions past the positional parameters belong to the rest parameter, if any; with none, false.

§Examples
use bytecode_lang::{Param, ParamKind, ParamList, StrId};

let list = ParamList::new(vec![
    Param::normal(StrId(0)),
    Param::new(ParamKind::RestMap, None).by_ref(),
]);
assert!(!list.positional_by_ref(0));
assert!(list.positional_by_ref(5));
Source

pub fn named_by_ref(&self, module: &Module, name: &[u8]) -> bool

Whether a named argument name would be taken by reference: the semantics of dparam_ref_named. Parameter names are strings of module, the callee’s module.

§Examples
use bytecode_lang::{ModuleBuilder, Param, ParamList};

let mut m = ModuleBuilder::new();
let x = m.string("x");
let module = m.finish().unwrap();
let list = ParamList::new(vec![Param::normal(x).by_ref()]);
assert!(list.named_by_ref(&module, b"x"));
assert!(!list.named_by_ref(&module, b"y"));
Source

pub fn bind( &self, module: &Module, items: &[ArgItem<'_>], ) -> Result<Binding, BindError>

Binds a dynamic call’s arguments to this list: the rule of specs/LSB.md §5.15, written once so every tier applies it alike.

items are the call’s arguments in order, after spreads were expanded (a spread array contributes positional items; a spread map’s integer keys positional items and its string keys named ones). Parameter names are strings of module, the callee’s module.

  1. Positional items fill the positional-only and normal parameters in order; extra ones go to the rest parameter, else are dropped under ignore_extra, else BindError::TooMany. A positional item after a named one is BindError::PositionalAfterNamed.
  2. A named item fills the normal or named-only parameter of that name (BindError::Duplicate if it is already filled); with none, it goes to the named rest, else to a RestMap (a repeated name there is Duplicate), else BindError::UnknownName.
  3. A parameter left empty takes its default (its presence bit is clear), or is BindError::Missing; a rest parameter is an empty collection.

The first violation in item order is reported, then the first missing parameter. Runs in O(items × params) with params ≤ 255, plus O(n log n) for duplicate names in a rest collection.

§Errors

A BindError; a VM raises ArgumentError (E0114) for every one.

§Examples
use bytecode_lang::{ArgItem, Bound, ModuleBuilder, Param, ParamKind, ParamList};

let mut m = ModuleBuilder::new();
let (a, b) = (m.string("a"), m.string("b"));
let module = m.finish().unwrap();
// function f($a, $b = 2, ...$rest)
let list = ParamList::new(vec![
    Param::normal(a),
    Param::normal(b).with_default(),
    Param::new(ParamKind::RestMap, None),
]);
// f(1, 2, 3, x: 4)
let items = [ArgItem::Positional, ArgItem::Positional, ArgItem::Positional, ArgItem::Named(b"x")];
let bound = list.bind(&module, &items).unwrap();
assert_eq!(bound.slots(), &[Bound::Arg(0), Bound::Arg(1), Bound::Collected(vec![2, 3])]);
assert_eq!(bound.presence(), 0b111);
// f(b: 5, a: 6)
let bound = list.bind(&module, &[ArgItem::Named(b"b"), ArgItem::Named(b"a")]).unwrap();
assert_eq!(bound.slots(), &[Bound::Arg(1), Bound::Arg(0), Bound::Collected(vec![])]);

Trait Implementations§

Source§

impl Clone for ParamList

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ParamList

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ParamList

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Display for ParamList

params (s0, &s1 = ?, ...s2) ignore_extra-style rendering for listings: each parameter as its kind marker, & when by reference, its name, and = ? when it has a default.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for ParamList

Source§

impl Hash for ParamList

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for ParamList

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for ParamList

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for ParamList

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl StructuralPartialEq for ParamList

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.