feat: 对象字面量 spread({...obj} 展开可枚举自有属性)
This commit is contained in:
@@ -266,6 +266,11 @@ impl Inst {
|
||||
OpCode::FOR_IN_NEXT | OpCode::FOR_IN_DONE | OpCode::FOR_OF_NEXT | OpCode::FOR_OF_DONE => {}
|
||||
// REST_OBJECT:读 a(ext 是 excluded_idx 常量)
|
||||
OpCode::REST_OBJECT => push_operand(&mut uses, &self.a),
|
||||
// SPREAD_OBJECT:原地改目标对象,读目标(rd)与源(a)
|
||||
OpCode::SPREAD_OBJECT => {
|
||||
push_operand(&mut uses, &self.rd);
|
||||
push_operand(&mut uses, &self.a);
|
||||
}
|
||||
// TEMPLATE_STR:解析 ext,跳过 ext[0],后续 seg>>31==1 则低 8 位是 expr_reg
|
||||
OpCode::TEMPLATE_STR => {
|
||||
for seg in self.ext.iter().skip(1) {
|
||||
@@ -567,6 +572,16 @@ mod tests {
|
||||
assert_eq!(inst.use_regs().as_slice(), &[1]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spread_object_def_rd_uses_rd_and_a() {
|
||||
// SPREAD_OBJECT 原地改目标对象:def=rd,use=[rd, a],不可删除(有观察副作用)
|
||||
let inst = Inst::spread_object(Operand::Reg(3), Operand::Reg(7));
|
||||
assert_eq!(inst.def_reg(), Some(3));
|
||||
assert_eq!(inst.use_regs().as_slice(), &[3, 7]);
|
||||
let f = IRFunction::new();
|
||||
assert!(!inst.is_pure(&f));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn create_arguments_defs_rd_no_register_use_impure() {
|
||||
// CREATE_ARGUMENTS 写 rd;实参从 spill 栈读取,无寄存器 use;
|
||||
|
||||
@@ -153,6 +153,13 @@ impl Inst {
|
||||
Self::with_ext(OpCode::REST_OBJECT, rest, src, Operand::None, &[excluded_idx])
|
||||
}
|
||||
|
||||
/// 对象字面量 spread 展开:把源 `src` 的可枚举自有属性写入目标对象 `rd`(原地改)。
|
||||
/// 语义 = CopyDataProperties 的"非 null/undefined 源":null/undefined 合法(空展开),
|
||||
/// 与 REST_OBJECT(对 null/undefined 抛 TypeError)不同。
|
||||
pub fn spread_object(target: Operand, src: Operand) -> Self {
|
||||
Self::new(OpCode::SPREAD_OBJECT, target, src, Operand::None)
|
||||
}
|
||||
|
||||
/// TEMPLATE_STR:变长 ext。首字打包 `(segment_count<<16) | total_len_hint`,
|
||||
/// 后续每 quasi 一项 `quasi_const_idx & 0x7FFF_FFFF`,其后若跟表达式再一项 `0x8000_0000 | expr_reg`。
|
||||
pub fn template_str(dst: Operand, segment_count: u32, total_len_hint: u16, parts: &[u32]) -> Self {
|
||||
@@ -311,6 +318,13 @@ mod tests {
|
||||
|
||||
let rest = Inst::rest_object(Operand::Reg(0), Operand::Reg(1), 7);
|
||||
assert_eq!(rest.ext.as_slice(), &[7]);
|
||||
|
||||
let spread = Inst::spread_object(Operand::Reg(0), Operand::Reg(1));
|
||||
assert_eq!(spread.op, OpCode::SPREAD_OBJECT);
|
||||
assert_eq!(spread.rd, Operand::Reg(0));
|
||||
assert_eq!(spread.a, Operand::Reg(1));
|
||||
assert_eq!(spread.b, Operand::None);
|
||||
assert!(spread.ext.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user