Skip to content

Commit fee4048

Browse files
authored
Merge CodeBlock constant pools (#3413)
* Merge `CodeBlock` constant pools * Apply review
1 parent e681685 commit fee4048

File tree

28 files changed

+264
-162
lines changed

28 files changed

+264
-162
lines changed

boa_engine/src/bytecompiler/class.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ impl ByteCompiler<'_, '_> {
8181
compiler.emit_opcode(Opcode::SetReturnValue);
8282

8383
let code = Gc::new(compiler.finish());
84-
let index = self.functions.len() as u32;
85-
self.functions.push(code);
84+
let index = self.push_function_to_constants(code);
8685
self.emit(
8786
Opcode::GetFunction,
8887
&[Operand::Varying(index), Operand::Bool(false)],
@@ -294,10 +293,8 @@ impl ByteCompiler<'_, '_> {
294293

295294
field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER;
296295

297-
let code = field_compiler.finish();
298-
let code = Gc::new(code);
299-
let index = self.functions.len() as u32;
300-
self.functions.push(code);
296+
let code = Gc::new(field_compiler.finish());
297+
let index = self.push_function_to_constants(code);
301298
self.emit(
302299
Opcode::GetFunction,
303300
&[Operand::Varying(index), Operand::Bool(false)],
@@ -325,10 +322,8 @@ impl ByteCompiler<'_, '_> {
325322

326323
field_compiler.code_block_flags |= CodeBlockFlags::IN_CLASS_FIELD_INITIALIZER;
327324

328-
let code = field_compiler.finish();
329-
let code = Gc::new(code);
330-
let index = self.functions.len() as u32;
331-
self.functions.push(code);
325+
let code = Gc::new(field_compiler.finish());
326+
let index = self.push_function_to_constants(code);
332327
self.emit(
333328
Opcode::GetFunction,
334329
&[Operand::Varying(index), Operand::Bool(false)],
@@ -552,8 +547,7 @@ impl ByteCompiler<'_, '_> {
552547
match element {
553548
StaticElement::StaticBlock(code) => {
554549
self.emit_opcode(Opcode::Dup);
555-
let index = self.functions.len() as u32;
556-
self.functions.push(code);
550+
let index = self.push_function_to_constants(code);
557551
self.emit(
558552
Opcode::GetFunction,
559553
&[Operand::Varying(index), Operand::Bool(false)],
@@ -565,8 +559,7 @@ impl ByteCompiler<'_, '_> {
565559
StaticElement::StaticField((code, name_index)) => {
566560
self.emit_opcode(Opcode::Dup);
567561
self.emit_opcode(Opcode::Dup);
568-
let index = self.functions.len() as u32;
569-
self.functions.push(code);
562+
let index = self.push_function_to_constants(code);
570563
self.emit(
571564
Opcode::GetFunction,
572565
&[Operand::Varying(index), Operand::Bool(false)],

boa_engine/src/bytecompiler/declarations.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ impl ByteCompiler<'_, '_> {
282282
);
283283

284284
// Ensures global functions are printed when generating the global flowgraph.
285-
self.functions.push(code.clone());
285+
let _ = self.push_function_to_constants(code.clone());
286286

287287
// b. Let fo be InstantiateFunctionObject of f with arguments env and privateEnv.
288288
let function = if generator {
@@ -733,7 +733,7 @@ impl ByteCompiler<'_, '_> {
733733
// c. If varEnv is a Global Environment Record, then
734734
if var_env.is_global() {
735735
// Ensures global functions are printed when generating the global flowgraph.
736-
self.functions.push(code.clone());
736+
let _ = self.push_function_to_constants(code.clone());
737737

738738
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
739739
let function = if generator {
@@ -749,8 +749,7 @@ impl ByteCompiler<'_, '_> {
749749
// d. Else,
750750
else {
751751
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
752-
let index = self.functions.len() as u32;
753-
self.functions.push(code);
752+
let index = self.push_function_to_constants(code);
754753
if r#async && generator {
755754
self.emit_with_varying_operand(Opcode::GetGeneratorAsync, index);
756755
} else if generator {
@@ -1034,7 +1033,7 @@ impl ByteCompiler<'_, '_> {
10341033
}
10351034

10361035
if generator {
1037-
self.emit(Opcode::Generator, &[Operand::U8(self.in_async().into())]);
1036+
self.emit(Opcode::Generator, &[Operand::Bool(self.in_async())]);
10381037
self.emit_opcode(Opcode::Pop);
10391038
}
10401039

boa_engine/src/bytecompiler/env.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ impl ByteCompiler<'_, '_> {
1313
function_scope,
1414
));
1515

16-
let index = self.compile_environments.len() as u32;
17-
self.compile_environments.push(env.clone());
16+
let index = self.constants.len() as u32;
17+
self.constants
18+
.push(crate::vm::Constant::CompileTimeEnvironment(env.clone()));
1819

1920
if function_scope {
2021
self.variable_environment = env.clone();

boa_engine/src/bytecompiler/mod.rs

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ use crate::{
1818
environments::{BindingLocator, BindingLocatorError, CompileTimeEnvironment},
1919
js_string,
2020
vm::{
21-
BindingOpcode, CodeBlock, CodeBlockFlags, GeneratorResumeKind, Handler, Opcode,
21+
BindingOpcode, CodeBlock, CodeBlockFlags, Constant, GeneratorResumeKind, Handler, Opcode,
2222
VaryingOperandKind,
2323
},
24-
Context, JsBigInt, JsString, JsValue,
24+
Context, JsBigInt, JsString,
2525
};
2626
use boa_ast::{
2727
declaration::{Binding, LexicalDeclaration, VarDeclaration},
@@ -248,21 +248,11 @@ pub struct ByteCompiler<'ctx, 'host> {
248248
/// Bytecode
249249
pub(crate) bytecode: Vec<u8>,
250250

251-
/// Literals
252-
pub(crate) literals: Vec<JsValue>,
253-
254-
/// Property field names and private name `[[Description]]`s.
255-
pub(crate) names: Vec<JsString>,
251+
pub(crate) constants: ThinVec<Constant>,
256252

257253
/// Locators for all bindings in the codeblock.
258254
pub(crate) bindings: Vec<BindingLocator>,
259255

260-
/// Functions inside this function
261-
pub(crate) functions: Vec<Gc<CodeBlock>>,
262-
263-
/// Compile time environments in this function.
264-
pub(crate) compile_environments: Vec<Rc<CompileTimeEnvironment>>,
265-
266256
/// The current variable environment.
267257
pub(crate) variable_environment: Rc<CompileTimeEnvironment>,
268258

@@ -315,13 +305,10 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
315305
function_name: name,
316306
length: 0,
317307
bytecode: Vec::default(),
318-
literals: Vec::default(),
319-
names: Vec::default(),
308+
constants: ThinVec::default(),
320309
bindings: Vec::default(),
321-
functions: Vec::default(),
322310
this_mode: ThisMode::Global,
323311
params: FormalParameterList::default(),
324-
compile_environments: Vec::default(),
325312
current_open_environments_count: 0,
326313

327314
// This starts at two because the first value is the `this` value, then function object.
@@ -372,12 +359,12 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
372359
}
373360

374361
let value = match literal.clone() {
375-
Literal::String(value) => JsValue::new(value),
376-
Literal::BigInt(value) => JsValue::new(value),
362+
Literal::String(value) => Constant::String(value),
363+
Literal::BigInt(value) => Constant::BigInt(value),
377364
};
378365

379-
let index = self.literals.len() as u32;
380-
self.literals.push(value);
366+
let index = self.constants.len() as u32;
367+
self.constants.push(value);
381368
self.literals_map.insert(literal, index);
382369
index
383370
}
@@ -388,8 +375,8 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
388375
}
389376

390377
let string = self.interner().resolve_expect(name.sym()).utf16();
391-
let index = self.names.len() as u32;
392-
self.names.push(js_string!(string));
378+
let index = self.constants.len() as u32;
379+
self.constants.push(Constant::String(js_string!(string)));
393380
self.names_map.insert(name, index);
394381
index
395382
}
@@ -411,6 +398,14 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
411398
index
412399
}
413400

401+
#[inline]
402+
#[must_use]
403+
pub(crate) fn push_function_to_constants(&mut self, function: Gc<CodeBlock>) -> u32 {
404+
let index = self.constants.len() as u32;
405+
self.constants.push(Constant::Function(function));
406+
index
407+
}
408+
414409
fn emit_binding(&mut self, opcode: BindingOpcode, name: Identifier) {
415410
match opcode {
416411
BindingOpcode::Var => {
@@ -1250,10 +1245,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
12501245
self.context,
12511246
);
12521247

1253-
let index = self.functions.len() as u32;
1254-
self.functions.push(code);
1255-
1256-
index
1248+
self.push_function_to_constants(code)
12571249
}
12581250

12591251
/// Compiles a function AST Node into bytecode, setting its corresponding binding or
@@ -1348,8 +1340,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
13481340
self.context,
13491341
);
13501342

1351-
let index = self.functions.len() as u32;
1352-
self.functions.push(code);
1343+
let index = self.push_function_to_constants(code);
13531344

13541345
if r#async && generator {
13551346
self.emit_with_varying_operand(Opcode::GetGeneratorAsync, index);
@@ -1412,8 +1403,7 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
14121403
self.context,
14131404
);
14141405

1415-
let index = self.functions.len() as u32;
1416-
self.functions.push(code);
1406+
let index = self.push_function_to_constants(code);
14171407

14181408
if r#async && generator {
14191409
self.emit_with_varying_operand(Opcode::GetGeneratorAsync, index);
@@ -1535,11 +1525,8 @@ impl<'ctx, 'host> ByteCompiler<'ctx, 'host> {
15351525
this_mode: self.this_mode,
15361526
params: self.params,
15371527
bytecode: self.bytecode.into_boxed_slice(),
1538-
literals: self.literals.into_boxed_slice(),
1539-
names: self.names.into_boxed_slice(),
1528+
constants: self.constants,
15401529
bindings: self.bindings.into_boxed_slice(),
1541-
functions: self.functions.into_boxed_slice(),
1542-
compile_environments: self.compile_environments.into_boxed_slice(),
15431530
handlers: self.handlers,
15441531
flags: Cell::new(self.code_block_flags),
15451532
}

boa_engine/src/environments/runtime/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,11 @@ impl Context<'_> {
672672
}
673673
}
674674

675-
/// Return the environment at the given index. Panics if the index is out of range.
675+
/// Return the environment at the given index.
676+
///
677+
/// # Panics
678+
///
679+
/// Panics if the `index` is out of range.
676680
pub(crate) fn environment_expect(&self, index: u32) -> &Environment {
677681
self.vm
678682
.environments

boa_engine/src/module/source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ impl SourceTextModule {
16571657

16581658
// deferred initialization of function exports
16591659
for (index, locator, kind) in functions {
1660-
let code = codeblock.functions[index as usize].clone();
1660+
let code = codeblock.constant_function(index as usize);
16611661

16621662
let function = if kind.is_generator() {
16631663
create_generator_function_object(code, kind.is_async(), None, context)

boa_engine/src/object/internal_methods/function.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ pub(crate) fn function_call(
9898
let index = context
9999
.vm
100100
.environments
101-
.push_lexical(code.compile_environments[last_env].clone());
101+
.push_lexical(code.constant_compile_time_environment(last_env));
102102
context
103103
.vm
104104
.environments
@@ -107,7 +107,7 @@ pub(crate) fn function_call(
107107
}
108108

109109
context.vm.environments.push_function(
110-
code.compile_environments[last_env].clone(),
110+
code.constant_compile_time_environment(last_env),
111111
FunctionSlots::new(this, function_object.clone(), None),
112112
);
113113

@@ -116,7 +116,7 @@ pub(crate) fn function_call(
116116
context
117117
.vm
118118
.environments
119-
.push_lexical(code.compile_environments[last_env].clone());
119+
.push_lexical(code.constant_compile_time_environment(last_env));
120120
}
121121

122122
// Taken from: `FunctionDeclarationInstantiation` abstract function.
@@ -226,7 +226,7 @@ fn function_construct(
226226
let index = context
227227
.vm
228228
.environments
229-
.push_lexical(code.compile_environments[last_env].clone());
229+
.push_lexical(code.constant_compile_time_environment(last_env));
230230
context
231231
.vm
232232
.environments
@@ -235,7 +235,7 @@ fn function_construct(
235235
}
236236

237237
context.vm.environments.push_function(
238-
code.compile_environments[last_env].clone(),
238+
code.constant_compile_time_environment(last_env),
239239
FunctionSlots::new(
240240
this.clone().map_or(ThisBindingStatus::Uninitialized, |o| {
241241
ThisBindingStatus::Initialized(o.into())
@@ -255,7 +255,7 @@ fn function_construct(
255255
context
256256
.vm
257257
.environments
258-
.push_lexical(code.compile_environments[last_env].clone());
258+
.push_lexical(code.constant_compile_time_environment(last_env));
259259
}
260260

261261
// Taken from: `FunctionDeclarationInstantiation` abstract function.

0 commit comments

Comments
 (0)