LibJS: Make Value() default-construct the undefined value

The special empty value (that we use for array holes, Optional<Value>
when empty and a few other other placeholder/sentinel tasks) still
exists, but you now create one via JS::js_special_empty_value() and
check for it with Value::is_special_empty_value().

The main idea here is to make it very unlikely to accidentally create an
unexpected special empty value.
This commit is contained in:
Andreas Kling 2025-04-04 23:16:34 +02:00 committed by Andreas Kling
parent 0d91363742
commit 3cf50539ec
Notes: github-actions[bot] 2025-04-05 09:21:31 +00:00
43 changed files with 165 additions and 122 deletions

View file

@ -1201,7 +1201,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ArrayExpression::genera
// If all elements are constant primitives, we can just emit a single instruction to initialize the array,
// instead of emitting instructions to manually evaluate them one-by-one
Vector<Value> values;
values.resize(m_elements.size());
values.resize_with_default_value(m_elements.size(), js_special_empty_value());
for (auto i = 0u; i < m_elements.size(); ++i) {
if (!m_elements[i])
continue;
@ -1221,7 +1221,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ArrayExpression::genera
auto value = TRY((*it)->generate_bytecode(generator)).value();
args.append(generator.copy_if_needed_to_preserve_evaluation_order(value));
} else {
args.append(generator.add_constant(Value()));
args.append(generator.add_constant(js_special_empty_value()));
}
}
@ -1235,7 +1235,7 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> ArrayExpression::genera
if (first_spread != m_elements.end()) {
for (auto it = first_spread; it != m_elements.end(); ++it) {
if (!*it) {
generator.emit<Bytecode::Op::ArrayAppend>(dst, generator.add_constant(Value()), false);
generator.emit<Bytecode::Op::ArrayAppend>(dst, generator.add_constant(js_special_empty_value()), false);
} else {
auto value = TRY((*it)->generate_bytecode(generator)).value();
generator.emit<Bytecode::Op::ArrayAppend>(dst, value, *it && is<SpreadExpression>(**it));