Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 26 additions & 22 deletions core/engine/src/bytecompiler/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,28 @@ impl ByteCompiler<'_> {
Expression::PropertyAccess(access) => self.access_get(Access::Property { access }, dst),
Expression::Conditional(op) => self.compile_conditional(op, dst),
Expression::ArrayLiteral(literal) => {
let value = self.register_allocator.alloc();

self.bytecode.emit_store_new_array(dst.variable());
let dst_op = dst.variable();
self.bytecode.emit_store_new_array(dst_op);

for element in literal.as_ref() {
if let Some(element) = element {
self.compile_expr(element, &value);
if let Expression::Spread(_) = element {
match element {
Some(Expression::Spread(spread)) => {
let value = self.register_allocator.alloc();
self.compile_expr(spread.target(), &value);
self.bytecode.emit_get_iterator(value.variable());
self.bytecode.emit_push_iterator_to_array(dst.variable());
} else {
self.bytecode
.emit_push_value_to_array(value.variable(), dst.variable());
self.bytecode.emit_push_iterator_to_array(dst_op);
self.register_allocator.dealloc(value);
}
Some(elem) => {
self.compile_expr_operand(elem, |this, op| {
this.bytecode.emit_push_value_to_array(op, dst_op);
});
}
None => {
self.bytecode.emit_push_elision_to_array(dst_op);
}
} else {
self.bytecode.emit_push_elision_to_array(dst.variable());
}
}
self.register_allocator.dealloc(value);
}
Expression::This(_this) => self.access_get(Access::This, dst),
Expression::Spread(spread) => self.compile_expr(spread.target(), dst),
Expand Down Expand Up @@ -354,24 +357,25 @@ impl ByteCompiler<'_> {

if contains_spread {
let array = self.register_allocator.alloc();
let value = self.register_allocator.alloc();
let array_op = array.variable();

self.bytecode.emit_store_new_array(array.variable());
self.bytecode.emit_store_new_array(array_op);

for arg in super_call.arguments() {
self.compile_expr(arg, &value);
if let Expression::Spread(_) = arg {
if let Expression::Spread(spread) = arg {
let value = self.register_allocator.alloc();
self.compile_expr(spread.target(), &value);
self.bytecode.emit_get_iterator(value.variable());
self.bytecode.emit_push_iterator_to_array(array.variable());
self.bytecode.emit_push_iterator_to_array(array_op);
self.register_allocator.dealloc(value);
} else {
self.bytecode
.emit_push_value_to_array(value.variable(), array.variable());
self.compile_expr_operand(arg, |this, op| {
this.bytecode.emit_push_value_to_array(op, array_op);
});
}
}

self.push_from_register(&array);

self.register_allocator.dealloc(value);
self.register_allocator.dealloc(array);
} else {
for arg in super_call.arguments() {
Expand Down
52 changes: 26 additions & 26 deletions core/engine/src/bytecompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1730,7 +1730,9 @@ impl<'ctx> ByteCompiler<'ctx> {
/// Compile an expression and leave the result on the stack.
///
/// For call/new expressions, this avoids the `PopIntoRegister` + `PushFromRegister`
/// round-trip by leaving the call result directly on the stack.
/// round-trip by leaving the call result directly on the stack. For identifier
/// expressions resolving to a local or const-cached register, this pushes from
/// that register directly, avoiding a `Move` into a temporary.
pub(crate) fn compile_expr_to_stack(&mut self, expr: &Expression) {
match expr {
Expression::Call(call) => {
Expand All @@ -1743,10 +1745,9 @@ impl<'ctx> ByteCompiler<'ctx> {
self.compile_expr_to_stack(parenthesized.expression());
}
_ => {
let tmp = self.register_allocator.alloc();
self.compile_expr(expr, &tmp);
self.push_from_register(&tmp);
self.register_allocator.dealloc(tmp);
self.compile_expr_operand(expr, |this, op| {
this.bytecode.emit_push_from_register(op);
});
}
}
}
Expand Down Expand Up @@ -2079,24 +2080,25 @@ impl<'ctx> ByteCompiler<'ctx> {

if contains_spread {
let array = self.register_allocator.alloc();
let value = self.register_allocator.alloc();
let array_op = array.variable();

self.bytecode.emit_store_new_array(array.variable());
self.bytecode.emit_store_new_array(array_op);

for arg in args {
self.compile_expr(arg, &value);
if let Expression::Spread(_) = arg {
if let Expression::Spread(spread) = arg {
let value = self.register_allocator.alloc();
self.compile_expr(spread.target(), &value);
self.bytecode.emit_get_iterator(value.variable());
self.bytecode.emit_push_iterator_to_array(array.variable());
self.bytecode.emit_push_iterator_to_array(array_op);
self.register_allocator.dealloc(value);
} else {
self.bytecode
.emit_push_value_to_array(value.variable(), array.variable());
self.compile_expr_operand(arg, |this, op| {
this.bytecode.emit_push_value_to_array(op, array_op);
});
}
}

self.push_from_register(&array);

self.register_allocator.dealloc(value);
self.register_allocator.dealloc(array);

self.bytecode.emit_call_spread();
Expand Down Expand Up @@ -2649,28 +2651,26 @@ impl<'ctx> ByteCompiler<'ctx> {

if contains_spread {
let array = compiler.register_allocator.alloc();
let value = compiler.register_allocator.alloc();
let array_op = array.variable();

compiler.bytecode.emit_store_new_array(array.variable());
compiler.bytecode.emit_store_new_array(array_op);

for arg in call.args() {
compiler.compile_expr(arg, &value);
if let Expression::Spread(_) = arg {
if let Expression::Spread(spread) = arg {
let value = compiler.register_allocator.alloc();
compiler.compile_expr(spread.target(), &value);
compiler.bytecode.emit_get_iterator(value.variable());
compiler
.bytecode
.emit_push_iterator_to_array(array.variable());
compiler.bytecode.emit_push_iterator_to_array(array_op);
compiler.register_allocator.dealloc(value);
} else {
compiler
.bytecode
.emit_push_value_to_array(value.variable(), array.variable());
compiler.compile_expr_operand(arg, |this, op| {
this.bytecode.emit_push_value_to_array(op, array_op);
});
}
}

compiler.push_from_register(&array);

compiler.register_allocator.dealloc(array);
compiler.register_allocator.dealloc(value);
} else {
for arg in call.args() {
compiler.compile_expr_to_stack(arg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,25 @@ Location Handler Opcode Operands
00000b Jump address:00001a
000010 IncrementLoopIteration
000011 Inc src:r02, dst:r02
00001a JumpIfNotLessThan lhs:r02, rhs:r03, address:000083
00001a JumpIfNotLessThan lhs:r02, rhs:r03, address:00007a
000027 StoreZero dst:r05
00002c StoreInt8 value:50, dst:r06
000032 Jump address:000041
000037 IncrementLoopIteration
000038 Inc src:r05, dst:r05
000041 JumpIfNotLessThan lhs:r05, rhs:r06, address:00007e
000041 JumpIfNotLessThan lhs:r05, rhs:r06, address:000075
00004e PushFromRegister src:r00
000053 GetNameGlobal dst:r07, binding_index:0, ic_index:0
000060 PushFromRegister src:r07
000065 Move src:r05, dst:r07
00006e PushFromRegister src:r07
000073 Call argument_count:1
000078 Pop
000079 Jump address:000037
00007e Jump address:000010
000083 GetNameGlobal dst:r03, binding_index:1, ic_index:1
000090 SetAccumulator src:r03
000095 CheckReturn
000096 Return
000065 PushFromRegister src:r05
00006a Call argument_count:1
00006f Pop
000070 Jump address:000037
000075 Jump address:000010
00007a GetNameGlobal dst:r03, binding_index:1, ic_index:1
000087 SetAccumulator src:r03
00008c CheckReturn
00008d Return

Register Count: 8, Flags: CodeBlockFlags(HAS_PROTOTYPE_PROPERTY)
Constants:
Expand All @@ -42,4 +41,4 @@ Handlers: <empty>
Source Map:
0000: 17..56: (5, 25)
0001: 56..101: (6, 27)
0002: 101..121: (7, 6)
0002: 101..112: (7, 6)
Loading