boa/syntax/ast/node/block/
mod.rs1use super::{Node, StatementList};
4use crate::{
5 environment::declarative_environment_record::DeclarativeEnvironmentRecord,
6 exec::Executable,
7 exec::InterpreterState,
8 gc::{Finalize, Trace},
9 BoaProfiler, Context, JsResult, JsValue,
10};
11use std::fmt;
12
13#[cfg(feature = "deser")]
14use serde::{Deserialize, Serialize};
15
16#[cfg(test)]
17mod tests;
18
19#[cfg_attr(feature = "deser", derive(Serialize, Deserialize))]
35#[cfg_attr(feature = "deser", serde(transparent))]
36#[derive(Clone, Debug, Trace, Finalize, PartialEq)]
37pub struct Block {
38 #[cfg_attr(feature = "deser", serde(flatten))]
39 statements: StatementList,
40}
41
42impl Block {
43 pub(crate) fn items(&self) -> &[Node] {
45 self.statements.items()
46 }
47
48 pub(super) fn display(&self, f: &mut fmt::Formatter<'_>, indentation: usize) -> fmt::Result {
50 writeln!(f, "{{")?;
51 self.statements.display(f, indentation + 1)?;
52 write!(f, "{}}}", " ".repeat(indentation))
53 }
54}
55
56impl Executable for Block {
57 fn run(&self, context: &mut Context) -> JsResult<JsValue> {
58 let _timer = BoaProfiler::global().start_event("Block", "exec");
59 {
60 let env = context.get_current_environment();
61 context.push_environment(DeclarativeEnvironmentRecord::new(Some(env)));
62 }
63
64 let mut obj = JsValue::default();
67 for statement in self.items() {
68 obj = statement.run(context).map_err(|e| {
69 context.pop_environment();
72 e
73 })?;
74
75 match context.executor().get_current_state() {
76 InterpreterState::Return => {
77 break;
79 }
80 InterpreterState::Break(_label) => {
81 break;
85 }
86 InterpreterState::Continue(_label) => {
87 break;
89 }
90 InterpreterState::Executing => {
91 }
93 }
94 }
95
96 let _ = context.pop_environment();
98
99 Ok(obj)
100 }
101}
102
103impl<T> From<T> for Block
104where
105 T: Into<StatementList>,
106{
107 fn from(list: T) -> Self {
108 Self {
109 statements: list.into(),
110 }
111 }
112}
113
114impl fmt::Display for Block {
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 self.display(f, 0)
117 }
118}
119
120impl From<Block> for Node {
121 fn from(block: Block) -> Self {
122 Self::Block(block)
123 }
124}