From 202f8550555502b16e07f48d5b4ed6740a8c6fe8 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 14 Mar 2021 19:10:07 +0100 Subject: [PATCH] LibJS: Change non-ScriptFunction source string to "[native code]" https://tc39.es/ecma262/#sec-function.prototype.tostring - this is how the spec wants us to do it. :^) Also change the function name behaviour to only provide a name for NativeFunctions, which matches other engines - presumably to not expose Proxy objects, and to prevent "function bound foo() { [native code] }". --- .../Libraries/LibJS/Runtime/FunctionPrototype.cpp | 15 +++++++++++---- .../Function/Function.prototype.toString.js | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp index 4cdc25964f..6319363a6f 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionPrototype.cpp @@ -142,8 +142,8 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string) vm.throw_exception(global_object, ErrorType::NotA, "Function"); return {}; } - String function_name = static_cast(this_object)->name(); - String function_parameters = ""; + String function_name; + String function_parameters; String function_body; if (is(this_object)) { @@ -160,18 +160,25 @@ JS_DEFINE_NATIVE_FUNCTION(FunctionPrototype::to_string) parameters_builder.append(" = TODO"); } } + function_name = script_function.name(); function_parameters = parameters_builder.build(); // FIXME: ASTNodes should be able to dump themselves to source strings - something like this: // auto& body = static_cast(this_object)->body(); // function_body = body.to_source(); function_body = " ???"; } else { - function_body = String::formatted(" [{}]", this_object->class_name()); + // This is "implementation-defined" - other engines don't include a name for + // ProxyObject and BoundFunction, only NativeFunction - let's do the same here. + if (is(this_object)) + function_name = static_cast(*this_object).name(); + function_body = " [native code]"; } auto function_source = String::formatted( "function {}({}) {{\n{}\n}}", - function_name.is_null() ? "" : function_name, function_parameters, function_body); + function_name.is_null() ? "" : function_name, + function_parameters.is_null() ? "" : function_parameters, + function_body); return js_string(vm, function_source); } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Function/Function.prototype.toString.js b/Userland/Libraries/LibJS/Tests/builtins/Function/Function.prototype.toString.js index a8ed197930..73246ee909 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Function/Function.prototype.toString.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Function/Function.prototype.toString.js @@ -12,6 +12,6 @@ test("basic functionality", () => { return bar + 42; }.toString() ).toBe("function (foo, bar, baz) {\n ???\n}"); - expect(console.debug.toString()).toBe("function debug() {\n [NativeFunction]\n}"); - expect(Function.toString()).toBe("function Function() {\n [FunctionConstructor]\n}"); + expect(console.debug.toString()).toBe("function debug() {\n [native code]\n}"); + expect(Function.toString()).toBe("function Function() {\n [native code]\n}"); });