diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 83b8b542b9..8ae8543472 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -24,8 +24,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include +#include #include #include @@ -35,6 +37,7 @@ ScriptFunction::ScriptFunction(const ScopeNode& body, Vector paramete : m_body(body) , m_parameters(move(parameters)) { + put_native_property("length", length_getter, length_setter); } ScriptFunction::~ScriptFunction() @@ -60,4 +63,18 @@ Value ScriptFunction::construct(Interpreter& interpreter) return call(interpreter); } +Value ScriptFunction::length_getter(Interpreter& interpreter) +{ + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; + if (!this_object->is_function()) + return interpreter.throw_exception("TypeError", "Not a function"); + return Value(static_cast(static_cast(this_object)->parameters().size())); +} + +void ScriptFunction::length_setter(Interpreter&, Value) +{ +} + } diff --git a/Libraries/LibJS/Runtime/ScriptFunction.h b/Libraries/LibJS/Runtime/ScriptFunction.h index 7691eedc42..8722dbcd60 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.h +++ b/Libraries/LibJS/Runtime/ScriptFunction.h @@ -45,6 +45,9 @@ private: virtual bool is_script_function() const final { return true; } virtual const char* class_name() const override { return "ScriptFunction"; } + static Value length_getter(Interpreter&); + static void length_setter(Interpreter&, Value); + NonnullRefPtr m_body; const Vector m_parameters; }; diff --git a/Libraries/LibJS/Tests/function-length.js b/Libraries/LibJS/Tests/function-length.js new file mode 100644 index 0000000000..e24f08e490 --- /dev/null +++ b/Libraries/LibJS/Tests/function-length.js @@ -0,0 +1,17 @@ +function assert(x) { if (!x) throw 1; } + +try { + function foo() { } + assert(foo.length === 0); + assert((foo.length = 5) === 5); + assert(foo.length === 0); + + function bar(a, b, c) {} + assert(bar.length === 3); + assert((bar.length = 5) === 5); + assert(bar.length === 3); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}