LibJS: Make typeof return undefined for undefined variables

This makes `typeof i_dont_exist` return `undefined` instead of 
throwing an error.
This commit is contained in:
Marcin Gasperowicz 2020-06-02 23:26:39 +02:00 committed by Andreas Kling
parent b0932b0aec
commit 0b74ea3d6a
Notes: sideshowbarker 2024-07-19 05:52:25 +09:00
2 changed files with 32 additions and 3 deletions

View file

@ -585,9 +585,25 @@ Value UnaryExpression::execute(Interpreter& interpreter) const
return base_object->delete_property(reference.name());
}
auto lhs_result = m_lhs->execute(interpreter);
if (interpreter.exception())
return {};
Value lhs_result;
if (m_op == UnaryOp::Typeof && m_lhs->is_identifier()) {
auto reference = m_lhs->to_reference(interpreter);
if (interpreter.exception()) {
return {};
}
// FIXME: standard recommends checking with is_unresolvable but it ALWAYS return false here
if (reference.is_local_variable() || reference.is_global_variable()) {
auto name = reference.name();
lhs_result = interpreter.get_variable(name.to_string()).value_or(js_undefined());
if (interpreter.exception())
return {};
}
} else {
lhs_result = m_lhs->execute(interpreter);
if (interpreter.exception())
return {};
}
switch (m_op) {
case UnaryOp::BitwiseNot:
return bitwise_not(interpreter, lhs_result);

View file

@ -8,6 +8,19 @@ try {
assert(typeof null === "object");
assert(typeof undefined === "undefined");
var iExist = 1;
assert(typeof iExist === "number");
assert(typeof iDontExist === "undefined");
var calls = 0;
Object.defineProperty(globalThis, "foo", {
get() {
calls++;
},
});
assert(typeof foo === "undefined");
assert(calls === 1);
console.log("PASS");
} catch (e) {
console.log("FAIL: " + e);