Skip to content

Commit 81a3f59

Browse files
committed
fix: opcode enum
Signed-off-by: Abhinav Sharma <abhinavs1920bpl@gmail.com>
1 parent 992583f commit 81a3f59

File tree

5 files changed

+213
-33
lines changed

5 files changed

+213
-33
lines changed

core/engine/src/vm/code_block.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,24 @@ impl CodeBlock {
396396
| Instruction::CreateUnmappedArgumentsObject { dst }
397397
| Instruction::RestParameterInit { dst }
398398
| Instruction::StoreNewArray { dst } => format!("dst:{dst}"),
399+
Instruction::HasRestrictedGlobalProperty { dst, index }
400+
| Instruction::CanDeclareGlobalFunction { dst, index }
401+
| Instruction::CanDeclareGlobalVar { dst, index } => {
402+
format!("dst: {dst}, index: {index}")
403+
}
404+
Instruction::CreateGlobalFunctionBinding {
405+
src,
406+
configurable,
407+
name_index,
408+
} => {
409+
format!("src: {src}, configurable: {configurable}, name_index: {name_index}")
410+
}
411+
Instruction::CreateGlobalVarBinding {
412+
configurable,
413+
name_index,
414+
} => {
415+
format!("configurable: {configurable}, name_index: {name_index}")
416+
}
399417
Instruction::Add { lhs, rhs, dst }
400418
| Instruction::Sub { lhs, rhs, dst }
401419
| Instruction::Div { lhs, rhs, dst }
@@ -931,12 +949,7 @@ impl CodeBlock {
931949
| Instruction::Reserved52
932950
| Instruction::Reserved53
933951
| Instruction::Reserved54
934-
| Instruction::Reserved55
935-
| Instruction::Reserved56
936-
| Instruction::Reserved57
937-
| Instruction::Reserved58
938-
| Instruction::Reserved59
939-
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unreachable"),
952+
| Instruction::Reserved55 => unreachable!("Reserved opcodes are unreachable"),
940953
}
941954
}
942955
}

core/engine/src/vm/flowgraph/mod.rs

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -367,17 +367,39 @@ impl CodeBlock {
367367
| Instruction::CheckReturn
368368
| Instruction::BindThisValue { .. }
369369
| Instruction::CreateMappedArgumentsObject { .. }
370-
| Instruction::CreateUnmappedArgumentsObject { .. } => {
370+
| Instruction::CreateUnmappedArgumentsObject { .. }
371+
| Instruction::HasRestrictedGlobalProperty { .. }
372+
| Instruction::CanDeclareGlobalFunction { .. }
373+
| Instruction::CanDeclareGlobalVar { .. }
374+
| Instruction::CreateGlobalFunctionBinding { .. }
375+
| Instruction::CreateGlobalVarBinding { .. } => {
371376
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
372377
graph.add_edge(previous_pc, pc, None, Color::None, EdgeStyle::Line);
373378
}
374379
Instruction::Return => {
375380
graph.add_node(previous_pc, NodeShape::Diamond, label.into(), Color::Red);
376381
}
377-
Instruction::Reserved1
378-
| Instruction::Reserved2
379-
| Instruction::Reserved3
380-
| Instruction::Reserved4
382+
Instruction::AddDisposableResource { value } => {
383+
let label = format!("AddDisposableResource value: {value}");
384+
graph.add_node(previous_pc, NodeShape::None, label.into(), Color::None);
385+
}
386+
Instruction::DisposeResources => {
387+
graph.add_node(
388+
previous_pc,
389+
NodeShape::None,
390+
"DisposeResources".into(),
391+
Color::None,
392+
);
393+
}
394+
Instruction::PushDisposalScope => {
395+
graph.add_node(
396+
previous_pc,
397+
NodeShape::None,
398+
"PushDisposalScope".into(),
399+
Color::None,
400+
);
401+
}
402+
Instruction::Reserved4
381403
| Instruction::Reserved5
382404
| Instruction::Reserved6
383405
| Instruction::Reserved7
@@ -428,12 +450,7 @@ impl CodeBlock {
428450
| Instruction::Reserved52
429451
| Instruction::Reserved53
430452
| Instruction::Reserved54
431-
| Instruction::Reserved55
432-
| Instruction::Reserved56
433-
| Instruction::Reserved57
434-
| Instruction::Reserved58
435-
| Instruction::Reserved59
436-
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unreachable"),
453+
| Instruction::Reserved55 => unreachable!("Reserved opcodes are unreachable"),
437454
}
438455
}
439456

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
use crate::{
2+
vm::opcode::{Operation, RegisterOperand, IndexOperand},
3+
Context, JsResult,
4+
};
5+
6+
/// `HasRestrictedGlobalProperty` implements the Opcode Operation for `Opcode::HasRestrictedGlobalProperty`
7+
///
8+
/// Operation:
9+
/// - Performs [`HasRestrictedGlobalProperty ( N )`][spec]
10+
///
11+
/// [spec]: https://tc39.es/ecma262/#sec-hasrestrictedglobalproperty
12+
pub(crate) struct HasRestrictedGlobalProperty;
13+
14+
impl HasRestrictedGlobalProperty {
15+
pub(crate) fn operation(
16+
(dst, index): (RegisterOperand, IndexOperand),
17+
context: &mut Context,
18+
) -> JsResult<()> {
19+
let code_block = context.vm.frame().code_block();
20+
let name = code_block.constant_string(index.into());
21+
let result = context.has_restricted_global_property(&name)?;
22+
context.vm.set_register(dst.into(), result.into());
23+
Ok(())
24+
}
25+
}
26+
27+
impl Operation for HasRestrictedGlobalProperty {
28+
const NAME: &'static str = "HasRestrictedGlobalProperty";
29+
const INSTRUCTION: &'static str = "INST - HasRestrictedGlobalProperty";
30+
const COST: u8 = 4;
31+
}
32+
33+
/// `CanDeclareGlobalFunction` implements the Opcode Operation for `Opcode::CanDeclareGlobalFunction`
34+
///
35+
/// Operation:
36+
/// - Performs [`CanDeclareGlobalFunction ( N )`][spec]
37+
///
38+
/// [spec]: https://tc39.es/ecma262/#sec-candeclareglobalfunction
39+
pub(crate) struct CanDeclareGlobalFunction;
40+
41+
impl CanDeclareGlobalFunction {
42+
pub(crate) fn operation(
43+
(dst, index): (RegisterOperand, IndexOperand),
44+
context: &mut Context,
45+
) -> JsResult<()> {
46+
let code_block = context.vm.frame().code_block();
47+
let name = code_block.constant_string(index.into());
48+
let result = context.can_declare_global_function(&name)?;
49+
context.vm.set_register(dst.into(), result.into());
50+
Ok(())
51+
}
52+
}
53+
54+
impl Operation for CanDeclareGlobalFunction {
55+
const NAME: &'static str = "CanDeclareGlobalFunction";
56+
const INSTRUCTION: &'static str = "INST - CanDeclareGlobalFunction";
57+
const COST: u8 = 4;
58+
}
59+
60+
/// `CanDeclareGlobalVar` implements the Opcode Operation for `Opcode::CanDeclareGlobalVar`
61+
///
62+
/// Operation:
63+
/// - Performs [`CanDeclareGlobalVar ( N )`][spec]
64+
///
65+
/// [spec]: https://tc39.es/ecma262/#sec-candeclareglobalvar
66+
pub(crate) struct CanDeclareGlobalVar;
67+
68+
impl CanDeclareGlobalVar {
69+
pub(crate) fn operation(
70+
(dst, index): (RegisterOperand, IndexOperand),
71+
context: &mut Context,
72+
) -> JsResult<()> {
73+
let code_block = context.vm.frame().code_block();
74+
let name = code_block.constant_string(index.into());
75+
let result = context.can_declare_global_var(&name)?;
76+
context.vm.set_register(dst.into(), result.into());
77+
Ok(())
78+
}
79+
}
80+
81+
impl Operation for CanDeclareGlobalVar {
82+
const NAME: &'static str = "CanDeclareGlobalVar";
83+
const INSTRUCTION: &'static str = "INST - CanDeclareGlobalVar";
84+
const COST: u8 = 4;
85+
}
86+
87+
/// `CreateGlobalFunctionBinding` implements the Opcode Operation for `Opcode::CreateGlobalFunctionBinding`
88+
///
89+
/// Operation:
90+
/// - Performs [`CreateGlobalFunctionBinding ( N, V, D )`][spec]
91+
///
92+
/// [spec]: https://tc39.es/ecma262/#sec-createglobalfunctionbinding
93+
pub(crate) struct CreateGlobalFunctionBinding;
94+
95+
impl CreateGlobalFunctionBinding {
96+
pub(crate) fn operation(
97+
(src, configurable, name_index): (RegisterOperand, IndexOperand, IndexOperand),
98+
context: &mut Context,
99+
) -> JsResult<()> {
100+
let code_block = context.vm.frame().code_block();
101+
let name = code_block.constant_string(name_index.into());
102+
let value = context.vm.get_register(src.into()).clone();
103+
let configurable = u32::from(configurable) != 0;
104+
105+
// Convert JsValue to JsObject
106+
let function = value
107+
.as_object()
108+
.ok_or_else(|| {
109+
crate::JsNativeError::typ()
110+
.with_message("value is not an object")
111+
})?
112+
.clone();
113+
114+
context.create_global_function_binding(name, function, configurable)?;
115+
Ok(())
116+
}
117+
}
118+
119+
impl Operation for CreateGlobalFunctionBinding {
120+
const NAME: &'static str = "CreateGlobalFunctionBinding";
121+
const INSTRUCTION: &'static str = "INST - CreateGlobalFunctionBinding";
122+
const COST: u8 = 4;
123+
}
124+
125+
/// `CreateGlobalVarBinding` implements the Opcode Operation for `Opcode::CreateGlobalVarBinding`
126+
///
127+
/// Operation:
128+
/// - Performs [`CreateGlobalVarBinding ( N, D )`][spec]
129+
///
130+
/// [spec]: https://tc39.es/ecma262/#sec-createglobalvarbinding
131+
pub(crate) struct CreateGlobalVarBinding;
132+
133+
impl CreateGlobalVarBinding {
134+
pub(crate) fn operation(
135+
(configurable, name_index): (IndexOperand, IndexOperand),
136+
context: &mut Context,
137+
) -> JsResult<()> {
138+
let code_block = context.vm.frame().code_block();
139+
let name = code_block.constant_string(name_index.into());
140+
let configurable = u32::from(configurable) != 0;
141+
context.create_global_var_binding(name, configurable)?;
142+
Ok(())
143+
}
144+
}
145+
146+
impl Operation for CreateGlobalVarBinding {
147+
const NAME: &'static str = "CreateGlobalVarBinding";
148+
const INSTRUCTION: &'static str = "INST - CreateGlobalVarBinding";
149+
const COST: u8 = 4;
150+
}

core/engine/src/vm/opcode/mod.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod environment;
2525
mod function;
2626
mod generator;
2727
mod get;
28+
mod global;
2829
mod iteration;
2930
mod meta;
3031
mod new;
@@ -70,6 +71,8 @@ pub(crate) use generator::*;
7071
#[doc(inline)]
7172
pub(crate) use get::*;
7273
#[doc(inline)]
74+
pub(crate) use global::*;
75+
#[doc(inline)]
7376
pub(crate) use iteration::*;
7477
#[doc(inline)]
7578
pub(crate) use meta::*;
@@ -2150,7 +2153,7 @@ generate_opcodes! {
21502153
/// - Output: dst
21512154
///
21522155
/// [spec]: https://tc39.es/ecma262/#sec-hasrestrictedglobalproperty
2153-
HasRestrictedGlobalProperty { dst: RegisterOperand, index: VaryingOperand },
2156+
HasRestrictedGlobalProperty { dst: RegisterOperand, index: IndexOperand },
21542157

21552158
/// Performs [`CanDeclareGlobalFunction ( N )`][spec]
21562159
///
@@ -2160,7 +2163,7 @@ generate_opcodes! {
21602163
/// - Output: dst
21612164
///
21622165
/// [spec]: https://tc39.es/ecma262/#sec-candeclareglobalfunction
2163-
CanDeclareGlobalFunction { dst: RegisterOperand, index: VaryingOperand },
2166+
CanDeclareGlobalFunction { dst: RegisterOperand, index: IndexOperand },
21642167

21652168
/// Performs [`CanDeclareGlobalVar ( N )`][spec]
21662169
///
@@ -2170,7 +2173,7 @@ generate_opcodes! {
21702173
/// - Output: dst
21712174
///
21722175
/// [spec]: https://tc39.es/ecma262/#sec-candeclareglobalvar
2173-
CanDeclareGlobalVar { dst: RegisterOperand, index: VaryingOperand },
2176+
CanDeclareGlobalVar { dst: RegisterOperand, index: IndexOperand },
21742177

21752178
/// Performs [`CreateGlobalFunctionBinding ( N, V, D )`][spec]
21762179
///
@@ -2181,7 +2184,7 @@ generate_opcodes! {
21812184
/// - Input: src
21822185
///
21832186
/// [spec]: https://tc39.es/ecma262/#sec-createglobalfunctionbinding
2184-
CreateGlobalFunctionBinding { src: RegisterOperand, configurable: VaryingOperand, name_index: VaryingOperand },
2187+
CreateGlobalFunctionBinding { src: RegisterOperand, configurable: IndexOperand, name_index: IndexOperand },
21852188

21862189
/// Performs [`CreateGlobalVarBinding ( N, V, D )`][spec]
21872190
///
@@ -2190,7 +2193,7 @@ generate_opcodes! {
21902193
/// - name_index: `VaryingOperand`
21912194
///
21922195
/// [spec]: https://tc39.es/ecma262/#sec-createglobalvarbinding
2193-
CreateGlobalVarBinding { configurable: VaryingOperand, name_index: VaryingOperand },
2196+
CreateGlobalVarBinding { configurable: IndexOperand, name_index: IndexOperand },
21942197

21952198
/// Add a disposable resource to the disposal stack.
21962199
///
@@ -2320,14 +2323,4 @@ generate_opcodes! {
23202323
Reserved54 => Reserved,
23212324
/// Reserved [`Opcode`].
23222325
Reserved55 => Reserved,
2323-
/// Reserved [`Opcode`].
2324-
Reserved56 => Reserved,
2325-
/// Reserved [`Opcode`].
2326-
Reserved57 => Reserved,
2327-
/// Reserved [`Opcode`].
2328-
Reserved58 => Reserved,
2329-
/// Reserved [`Opcode`].
2330-
Reserved59 => Reserved,
2331-
/// Reserved [`Opcode`].
2332-
Reserved60 => Reserved,
23332326
}

core/engine/tests/disposal.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
use boa_engine::{Context, JsResult, JsValue, Source};
1+
//! Tests for explicit resource management (using declarations).
2+
//!
3+
//! This module tests the core disposal mechanism for `using` declarations,
4+
//! verifying that resources are properly disposed when scopes exit.
5+
6+
#![allow(unused_crate_dependencies)]
7+
8+
use boa_engine::{Context, JsValue, Source};
29

310
#[test]
411
fn basic_disposal() {

0 commit comments

Comments
 (0)