mirror of https://github.com/boa-dev/boa.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.5 KiB
112 lines
3.5 KiB
use crate::{ |
|
builtins::Array, |
|
string::common::StaticJsStrings, |
|
vm::{opcode::Operation, CompletionType}, |
|
Context, JsResult, JsValue, |
|
}; |
|
|
|
/// `PushNewArray` implements the Opcode Operation for `Opcode::PushNewArray` |
|
/// |
|
/// Operation: |
|
/// - Push an empty array value on the stack. |
|
#[derive(Debug, Clone, Copy)] |
|
pub(crate) struct PushNewArray; |
|
|
|
impl Operation for PushNewArray { |
|
const NAME: &'static str = "PushNewArray"; |
|
const INSTRUCTION: &'static str = "INST - PushNewArray"; |
|
const COST: u8 = 3; |
|
|
|
fn execute(context: &mut Context) -> JsResult<CompletionType> { |
|
let array = context |
|
.intrinsics() |
|
.templates() |
|
.array() |
|
.create(Array, vec![JsValue::new(0)]); |
|
context.vm.push(array); |
|
Ok(CompletionType::Normal) |
|
} |
|
} |
|
|
|
/// `PushValueToArray` implements the Opcode Operation for `Opcode::PushValueToArray` |
|
/// |
|
/// Operation: |
|
/// - Push a value to an array. |
|
#[derive(Debug, Clone, Copy)] |
|
pub(crate) struct PushValueToArray; |
|
|
|
impl Operation for PushValueToArray { |
|
const NAME: &'static str = "PushValueToArray"; |
|
const INSTRUCTION: &'static str = "INST - PushValueToArray"; |
|
const COST: u8 = 3; |
|
|
|
fn execute(context: &mut Context) -> JsResult<CompletionType> { |
|
let value = context.vm.pop(); |
|
let array = context.vm.pop(); |
|
let o = array.as_object().expect("should be an object"); |
|
let len = o |
|
.length_of_array_like(context) |
|
.expect("should have 'length' property"); |
|
o.create_data_property_or_throw(len, value, context) |
|
.expect("should be able to create new data property"); |
|
context.vm.push(array); |
|
Ok(CompletionType::Normal) |
|
} |
|
} |
|
|
|
/// `PushEllisionToArray` implements the Opcode Operation for `Opcode::PushEllisionToArray` |
|
/// |
|
/// Operation: |
|
/// - Push an empty element/hole to an array. |
|
#[derive(Debug, Clone, Copy)] |
|
pub(crate) struct PushElisionToArray; |
|
|
|
impl Operation for PushElisionToArray { |
|
const NAME: &'static str = "PushElisionToArray"; |
|
const INSTRUCTION: &'static str = "INST - PushElisionToArray"; |
|
const COST: u8 = 3; |
|
|
|
fn execute(context: &mut Context) -> JsResult<CompletionType> { |
|
let array = context.vm.pop(); |
|
let o = array.as_object().expect("should always be an object"); |
|
|
|
let len = o |
|
.length_of_array_like(context) |
|
.expect("arrays should always have a 'length' property"); |
|
|
|
o.set(StaticJsStrings::LENGTH, len + 1, true, context)?; |
|
context.vm.push(array); |
|
Ok(CompletionType::Normal) |
|
} |
|
} |
|
|
|
/// `PushIteratorToArray` implements the Opcode Operation for `Opcode::PushIteratorToArray` |
|
/// |
|
/// Operation: |
|
/// - Push all iterator values to an array. |
|
#[derive(Debug, Clone, Copy)] |
|
pub(crate) struct PushIteratorToArray; |
|
|
|
impl Operation for PushIteratorToArray { |
|
const NAME: &'static str = "PushIteratorToArray"; |
|
const INSTRUCTION: &'static str = "INST - PushIteratorToArray"; |
|
const COST: u8 = 8; |
|
|
|
fn execute(context: &mut Context) -> JsResult<CompletionType> { |
|
let mut iterator = context |
|
.vm |
|
.frame_mut() |
|
.iterators |
|
.pop() |
|
.expect("iterator stack should have at least an iterator"); |
|
let array = context.vm.pop(); |
|
|
|
while !iterator.step(context)? { |
|
let next = iterator.value(context)?; |
|
Array::push(&array, &[next], context)?; |
|
} |
|
|
|
context.vm.push(array); |
|
Ok(CompletionType::Normal) |
|
} |
|
}
|
|
|