From fb0401871cdd5613500a45493ea697adaf6fa1df Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Mon, 30 Mar 2020 13:41:17 +0100 Subject: [PATCH] LibJS: Throw TypeError when calling non-function object We now have "undefined is not a function" :^) --- Libraries/LibJS/AST.cpp | 5 ++-- Libraries/LibJS/Tests/function-TypeError.js | 31 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 Libraries/LibJS/Tests/function-TypeError.js diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index b3daa4eb3b..a20b90d028 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -66,8 +66,9 @@ Value CallExpression::execute(Interpreter& interpreter) const if (interpreter.exception()) return {}; - ASSERT(callee.is_object()); - ASSERT(callee.as_object()->is_function()); + if (!callee.is_object() || !callee.as_object()->is_function()) + return interpreter.throw_exception("TypeError", String::format("%s is not a function", callee.to_string().characters())); + auto* function = static_cast(callee.as_object()); auto& call_frame = interpreter.push_call_frame(); diff --git a/Libraries/LibJS/Tests/function-TypeError.js b/Libraries/LibJS/Tests/function-TypeError.js new file mode 100644 index 0000000000..90cae589a4 --- /dev/null +++ b/Libraries/LibJS/Tests/function-TypeError.js @@ -0,0 +1,31 @@ +function assert(x) { if (!x) throw 1; } + +try { + try { + var b = true; + b(); + } catch(e) { + assert(e.name === "TypeError"); + assert(e.message === "true is not a function"); + } + + try { + var n = 100 + 20 + 3; + n(); + } catch(e) { + assert(e.name === "TypeError"); + assert(e.message === "123 is not a function"); + } + + try { + var o = {}; + o.a(); + } catch(e) { + assert(e.name === "TypeError"); + assert(e.message === "undefined is not a function"); + } + + console.log("PASS"); +} catch(e) { + console.log("FAIL: " + e); +}