Skip to content

Function.prototype.toString: return source text for ECMAScript functions (ES2016 §19.2.5) #310

Description

@dowdiness

Summary

Function.prototype.toString currently returns a native-code placeholder for all ECMAScript functions instead of their original source text. ES2016 §19.2.5 (and the 2019 revision) requires user-defined functions to return their exact source text as written, including whitespace and comments.

~108 test262 failures (54 strict / 54 non-strict).

Current vs expected behavior

function /* a */ f /* b */ (x) { return x; }
f.toString();
// Expected: "function /* a */ f /* b */ (x) { return x; }"
// Actual:   "function f() { [native code] }"

Failure categories

1. Source text not preserved (majority)

Tests verify that comments within the function signature are included in toString() output. The engine currently treats all functions — user-defined or native — as native functions in toString.

Test262Error: Conforms to NativeFunction Syntax: "function f() { [native code] }"
  (function /* a */ f /* b */ ( ...expected...)

Affected: function declarations/expressions, generators, async functions, arrow functions, class declarations/expressions, method definitions, getters/setters. Includes line-terminator normalization (CR, LF, CR+LF) tests.

2. Class method names stripped (16 failures)

Getter/setter/method definitions inside a class body should produce get f() {...} / set f() {...} / f() {...}, but the engine returns function () { [native code] } — losing the method name and accessor prefix.

Test262Error: Conforms to NativeFunction Syntax: "function () { [native code] }"
  (f /* a */ ( /* b */ ) /* c */ { /* d */ } expected)

3. Proxy targets return "[object Object]" (8 failures)

When a function is wrapped in a Proxy, Function.prototype.toString should return the source text of the underlying target (or throw if target has no [[SourceText]]), not stringify the Proxy object.

Test262Error: Conforms to NativeFunction Syntax: "[object Object]"

4. Parser failure on new Function/new AsyncFunction source (3 failures)

Function.js, AsyncFunction.js, GeneratorFunction.js dynamically construct functions via new Function(...). The engine fails to parse the resulting source text on re-inspection:

SyntaxError: Expected RParen, got Semicolon at line 2, col 9
SyntaxError: Expected RParen, got Yield at line 2, col 9

Spec reference

  • ES2016 §19.2.5.2: If func has a [[SourceText]] internal slot with a string, return that string.
  • ES2016 §19.2.5.2: If func is a built-in or bound function, return the NativeFunction form.
  • The 2019 revision formalized that [[SourceText]] must be set during parsing, and must include surrounding whitespace/comments within the function production.

Implementation notes

This requires:

  1. Store [[SourceText]] during parsing — capture the source span (start/end byte offset or character range) for each function production in the parser, attach to the FunctionValue at construction time.
  2. Return stored text from Function.prototype.toString — instead of always returning the native-code format.
  3. Class method name reconstruction — getter/setter/method need the accessor keyword + name prepended to the source span.
  4. Proxy passthroughFunction.prototype.toString should extract the Proxy's target and call through.

The source-text storage change touches the parser and FunctionValue AST/runtime representation — it is an architectural change, not a local fix.

Verification

NEW_MOON_MOD=0 make test262-filter FILTER=Function/prototype/toString

Expected recovery: ~108 tests (54 strict / 54 non-strict).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions