diff --git a/harness/nativeFunctionMatcher.js b/harness/nativeFunctionMatcher.js
new file mode 100644
index 0000000000000000000000000000000000000000..812c9a90417c9c3831c911671ac6d8114e942a16
--- /dev/null
+++ b/harness/nativeFunctionMatcher.js
@@ -0,0 +1 @@
+const NATIVE_FUNCTION_RE = /\bfunction\b[\s\S]+\b\w+\b[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
diff --git a/test/built-ins/Function/prototype/toString/Function.js b/test/built-ins/Function/prototype/toString/Function.js
new file mode 100644
index 0000000000000000000000000000000000000000..04f9248e523e077f098165c6183bf61266fbe14b
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/Function.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: Function.prototype.toString on a function created with the Function constructor
+---*/
+
+let f = /* before */Function("a", " /* a */ b, c /* b */ //", "/* c */ ; /* d */ //")/* after */;
+
+assert.sameValue(f.toString(), "function anonymous(a, /* a */ b, c /* b */ //\n) {/* c */ ; /* d */ //\n}");
diff --git a/test/built-ins/Function/prototype/toString/GeneratorFunction.js b/test/built-ins/Function/prototype/toString/GeneratorFunction.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4bd606f3dc3b99d1c5a0f8cf61098c19e76bf62
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/GeneratorFunction.js
@@ -0,0 +1,12 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-createdynamicfunction
+description: Function.prototype.toString on a generator function created with the GeneratorFunction constructor
+---*/
+
+let GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor;
+let g = /* before */GeneratorFunction("a", " /* a */ b, c /* b */ //", "/* c */ yield yield; /* d */ //")/* after */;
+
+assert.sameValue(g.toString(), "function* anonymous(a, /* a */ b, c /* b */ //\n) {/* c */ yield yield; /* d */ //\n}");
diff --git a/test/built-ins/Function/prototype/toString/S15.3.4.2_A12.js b/test/built-ins/Function/prototype/toString/S15.3.4.2_A12.js
index 16ae665b0a624a4bf4bed2d6994cf62413423408..1bb1b584fe84170003ad205a787adf8b37fb3a4a 100644
--- a/test/built-ins/Function/prototype/toString/S15.3.4.2_A12.js
+++ b/test/built-ins/Function/prototype/toString/S15.3.4.2_A12.js
@@ -5,7 +5,7 @@
 es5id: 15.3.4.2_A12
 description: >
     The Function.prototype.toString function is not generic; it throws
-    a TypeError exception if its this value is not a Function object.
+    a TypeError exception if its this value is not a callable object.
 ---*/
 
 assert.throws(TypeError, function() {
diff --git a/test/built-ins/Function/prototype/toString/S15.3.4.2_A13.js b/test/built-ins/Function/prototype/toString/S15.3.4.2_A13.js
index 3eea9c60e491b83ed990c27555e05621a704bc38..5cab3aaf2d82de9f53efaf0911accfa8b0dca5c5 100644
--- a/test/built-ins/Function/prototype/toString/S15.3.4.2_A13.js
+++ b/test/built-ins/Function/prototype/toString/S15.3.4.2_A13.js
@@ -5,7 +5,7 @@
 es5id: 15.3.4.2_A13
 description: >
     The toString function is not generic; it throws a TypeError
-    exception if its this value is not a Function object.
+    exception if its this value is not a callable object.
 ---*/
 
 assert.throws(TypeError, function() {
diff --git a/test/built-ins/Function/prototype/toString/S15.3.4.2_A14.js b/test/built-ins/Function/prototype/toString/S15.3.4.2_A14.js
index 52367b6accaf8e6ffffddf10e8d9b9a606df94c8..20fc46662b867db38b47f4630cba6e0576d8deb2 100644
--- a/test/built-ins/Function/prototype/toString/S15.3.4.2_A14.js
+++ b/test/built-ins/Function/prototype/toString/S15.3.4.2_A14.js
@@ -5,7 +5,7 @@
 es5id: 15.3.4.2_A14
 description: >
     The toString function is not generic; it throws a TypeError
-    exception if its this value is not a Function object.
+    exception if its this value is not a callable object.
 ---*/
 
 assert.throws(TypeError, function() {
diff --git a/test/built-ins/Function/prototype/toString/S15.3.4.2_A15.js b/test/built-ins/Function/prototype/toString/S15.3.4.2_A15.js
deleted file mode 100644
index f6d41b1baee6e8baf9c4761ce83f01bd4e665c2f..0000000000000000000000000000000000000000
--- a/test/built-ins/Function/prototype/toString/S15.3.4.2_A15.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2011 the Sputnik authors.  All rights reserved.
-// This code is governed by the BSD license found in the LICENSE file.
-
-/*---
-info: >
-    The toString function is not generic; it throws a TypeError exception if
-    its this value is not a Function object.
-es5id: 15.3.4.2_A15
-description: >
-    Whether or not they are callable, RegExp objects are not Function
-    objects, so toString should throw a TypeError.
----*/
-
-assert.throws(TypeError, function() {
-  Function.prototype.toString.call(/x/);
-});
diff --git a/test/built-ins/Function/prototype/toString/S15.3.4.2_A16.js b/test/built-ins/Function/prototype/toString/S15.3.4.2_A16.js
index f9032dd9000c121b5cf5d8f13b588de66ba4e717..246d3cf10575a158fbdfc1620656a59a03871395 100644
--- a/test/built-ins/Function/prototype/toString/S15.3.4.2_A16.js
+++ b/test/built-ins/Function/prototype/toString/S15.3.4.2_A16.js
@@ -4,7 +4,7 @@
 /*---
 info: >
     The toString function is not generic; it throws a TypeError exception if
-    its this value is not a Function object.
+    its this value is not a callable object.
 es5id: 15.3.4.2_A16
 description: >
     The String constructor, given an object, should invoke that
diff --git a/test/built-ins/Function/prototype/toString/arrow-function.js b/test/built-ins/Function/prototype/toString/arrow-function.js
new file mode 100644
index 0000000000000000000000000000000000000000..06990b14c5d027d27126848dbe18862f4ec6e4c9
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/arrow-function.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-arrow-function-definitions-runtime-semantics-evaluation
+description: Function.prototype.toString on an arrow function
+---*/
+
+let f = /* before */( /* a */ a /* b */ , /* c */ b /* d */ ) /* e */ => /* f */ { /* g */ ; /* h */ }/* after */;
+let g = /* before */( /* a */ ) /* b */ => /* c */ 0/* after */;
+let h = /* before */a /* a */ => /* b */ 0/* after */;
+
+assert.sameValue(f.toString(), "( /* a */ a /* b */ , /* c */ b /* d */ ) /* e */ => /* f */ { /* g */ ; /* h */ }");
+assert.sameValue(g.toString(), "( /* a */ ) /* b */ => /* c */ 0");
+assert.sameValue(h.toString(), "a /* a */ => /* b */ 0");
diff --git a/test/built-ins/Function/prototype/toString/bound-function.js b/test/built-ins/Function/prototype/toString/bound-function.js
new file mode 100644
index 0000000000000000000000000000000000000000..b6ceb116ef580e2e2c32e2412a44dcc77ac36c23
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/bound-function.js
@@ -0,0 +1,12 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function.prototype.tostring
+description: Function.prototype.toString on bound function exotic objects
+includes: [nativeFunctionMatcher.js]
+---*/
+
+let f = function(){}.bind(null);
+
+assert(NATIVE_FUNCTION_RE.test("" + f), "looks pretty much like a NativeFunction");
diff --git a/test/built-ins/Function/prototype/toString/class-declaration-complex-heritage.js b/test/built-ins/Function/prototype/toString/class-declaration-complex-heritage.js
new file mode 100644
index 0000000000000000000000000000000000000000..dbf60ee83a311155bbcb68726b0417299d8ffc43
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/class-declaration-complex-heritage.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-bindingclassdeclarationevaluation
+description: Function.prototype.toString on a class declaration (with complex heritage)
+---*/
+
+/* before */class /* a */ A /* b */ extends /* c */ class /* d */ B /* e */ { /* f */ } /* g */ { /* h */ }/* after */
+
+assert.sameValue(A.toString(), "class /* a */ A /* b */ extends /* c */ class /* d */ B /* e */ { /* f */ } /* g */ { /* h */ }");
diff --git a/test/built-ins/Function/prototype/toString/class-declaration-explicit-ctor.js b/test/built-ins/Function/prototype/toString/class-declaration-explicit-ctor.js
new file mode 100644
index 0000000000000000000000000000000000000000..c3b4b264f6f82b5a61bee4cf7c94bb05b4aca095
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/class-declaration-explicit-ctor.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-bindingclassdeclarationevaluation
+description: Function.prototype.toString on a class declaration (explicit constructor)
+---*/
+
+/* before */class /* a */ A /* b */ extends /* c */ B /* d */ { /* e */ constructor /* f */ ( /* g */ ) /* h */ { /* i */ ; /* j */ } /* k */ m /* l */ ( /* m */ ) /* n */ { /* o */ } /* p */ }/* after */
+
+assert.sameValue(A.toString(), "class /* a */ A /* b */ extends /* c */ B /* d */ { /* e */ constructor /* f */ ( /* g */ ) /* h */ { /* i */ ; /* j */ } /* k */ m /* l */ ( /* m */ ) /* n */ { /* o */ } /* p */ }");
+
+function B(){}
diff --git a/test/built-ins/Function/prototype/toString/class-declaration-implicit-ctor.js b/test/built-ins/Function/prototype/toString/class-declaration-implicit-ctor.js
new file mode 100644
index 0000000000000000000000000000000000000000..9dea84bb61cd8513650596e6127bfc62b0affde0
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/class-declaration-implicit-ctor.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-bindingclassdeclarationevaluation
+description: Function.prototype.toString on a class declaration (implicit constructor)
+---*/
+
+/* before */class /* a */ A /* b */ { /* c */ }/* after */
+/* before */class /* a */ B /* b */ extends /* c */ A /* d */ { /* e */ }/* after */
+/* before */class /* a */ C /* b */ extends /* c */ B /* d */ { /* e */ m /* f */ ( /* g */ ) /* h */ { /* i */ } /* j */ }/* after */
+
+assert.sameValue(A.toString(), "class /* a */ A /* b */ { /* c */ }");
+assert.sameValue(B.toString(), "class /* a */ B /* b */ extends /* c */ A /* d */ { /* e */ }");
+assert.sameValue(C.toString(), "class /* a */ C /* b */ extends /* c */ B /* d */ { /* e */ m /* f */ ( /* g */ ) /* h */ { /* i */ } /* j */ }");
diff --git a/test/built-ins/Function/prototype/toString/class-expression-explicit-ctor.js b/test/built-ins/Function/prototype/toString/class-expression-explicit-ctor.js
new file mode 100644
index 0000000000000000000000000000000000000000..93d74484796e2d4dbee23899b9a575301d95d2e9
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/class-expression-explicit-ctor.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-class-definitions-runtime-semantics-evaluation
+description: Function.prototype.toString on a class expression (explicit constructor)
+---*/
+
+let A = /* before */class /* a */ A /* b */ extends /* c */ B /* d */ { /* e */ constructor /* f */ ( /* g */ ) /* h */ { /* i */ ; /* j */ } /* k */ m /* l */ ( /* m */ ) /* n */ { /* o */ } /* p */ }/* after */;
+
+assert.sameValue(A.toString(), "class /* a */ A /* b */ extends /* c */ B /* d */ { /* e */ constructor /* f */ ( /* g */ ) /* h */ { /* i */ ; /* j */ } /* k */ m /* l */ ( /* m */ ) /* n */ { /* o */ } /* p */ }");
+
+function B(){}
diff --git a/test/built-ins/Function/prototype/toString/class-expression-implicit-ctor.js b/test/built-ins/Function/prototype/toString/class-expression-implicit-ctor.js
new file mode 100644
index 0000000000000000000000000000000000000000..91ab621341f380eadc8da033cfc09714cd464f79
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/class-expression-implicit-ctor.js
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-class-definitions-runtime-semantics-evaluation
+description: Function.prototype.toString on a class expression (implicit constructor)
+---*/
+
+let A = /* before */class /* a */ A /* b */ { /* c */ }/* after */;
+let B = /* before */class /* a */ B /* b */ extends /* c */ A /* d */ { /* e */ }/* after */;
+let C = /* before */class /* a */ C /* b */ extends /* c */ B /* d */ { /* e */ m /* f */ ( /* g */ ) /* h */ { /* i */ } /* j */ }/* after */;
+
+assert.sameValue(A.toString(), "class /* a */ A /* b */ { /* c */ }");
+assert.sameValue(B.toString(), "class /* a */ B /* b */ extends /* c */ A /* d */ { /* e */ }");
+assert.sameValue(C.toString(), "class /* a */ C /* b */ extends /* c */ B /* d */ { /* e */ m /* f */ ( /* g */ ) /* h */ { /* i */ } /* j */ }");
diff --git a/test/built-ins/Function/prototype/toString/function-declaration-non-simple-parameter-list.js b/test/built-ins/Function/prototype/toString/function-declaration-non-simple-parameter-list.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ff7971e01f61b672f9cd148764b39b4ee74076b
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/function-declaration-non-simple-parameter-list.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
+description: Function.prototype.toString on a function with a non-simple parameter list
+---*/
+
+/* before */function /* a */ f /* b */ ( /* c */ a /* d */ = /* e */ 0 /* f */ , /* g */ { /* h */ b /* i */ = /* j */ 0 /* k */ } /* l */ ) /* m */ { /* n */ }/* after */
+
+assert.sameValue(f.toString(), "function /* a */ f /* b */ ( /* c */ a /* d */ = /* e */ 0 /* f */ , /* g */ { /* h */ b /* i */ = /* j */ 0 /* k */ } /* l */ ) /* m */ { /* n */ }");
diff --git a/test/built-ins/Function/prototype/toString/function-declaration.js b/test/built-ins/Function/prototype/toString/function-declaration.js
new file mode 100644
index 0000000000000000000000000000000000000000..a0446ba712c5f25989ed01531a0dd074f966de60
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/function-declaration.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
+description: Function.prototype.toString on a function declaration
+---*/
+
+/* before */function /* a */ f /* b */ ( /* c */ x /* d */ , /* e */ y /* f */ ) /* g */ { /* h */ ; /* i */ ; /* j */ }/* after */
+
+assert.sameValue(f.toString(), "function /* a */ f /* b */ ( /* c */ x /* d */ , /* e */ y /* f */ ) /* g */ { /* h */ ; /* i */ ; /* j */ }");
diff --git a/test/built-ins/Function/prototype/toString/function-expression.js b/test/built-ins/Function/prototype/toString/function-expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..7ff4503f57f1e280a74142a9d7bd7ecdbc087a1b
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/function-expression.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function-definitions-runtime-semantics-evaluation
+description: Function.prototype.toString on a function expression
+---*/
+
+let f = /* before */function /* a */ f /* b */ ( /* c */ x /* d */ , /* e */ y /* f */ ) /* g */ { /* h */ ; /* i */ ; /* j */ }/* after */;
+
+assert.sameValue(f.toString(), "function /* a */ f /* b */ ( /* c */ x /* d */ , /* e */ y /* f */ ) /* g */ { /* h */ ; /* i */ ; /* j */ }");
diff --git a/test/built-ins/Function/prototype/toString/generator-function-declaration.js b/test/built-ins/Function/prototype/toString/generator-function-declaration.js
new file mode 100644
index 0000000000000000000000000000000000000000..133f9af8cb0490d6e9bfb0daa8fab1df3cafbd1e
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/generator-function-declaration.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-instantiatefunctionobject
+description: Function.prototype.toString on a generator function declaration
+---*/
+
+/* before */function /* a */ * /* b */ g /* c */ ( /* d */ x /* e */ , /* f */ y /* g */ ) /* h */ { /* i */ ; /* j */ ; /* k */ }/* after */
+
+assert.sameValue(g.toString(), "function /* a */ * /* b */ g /* c */ ( /* d */ x /* e */ , /* f */ y /* g */ ) /* h */ { /* i */ ; /* j */ ; /* k */ }");
diff --git a/test/built-ins/Function/prototype/toString/generator-function-expression.js b/test/built-ins/Function/prototype/toString/generator-function-expression.js
new file mode 100644
index 0000000000000000000000000000000000000000..012d98d6a8b390120943b332564bdb50056d49bb
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/generator-function-expression.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-evaluation
+description: Function.prototype.toString on a generator function expression
+---*/
+
+let g = /* before */function /* a */ * /* b */ name /* c */ ( /* d */ x /* e */ , /* f */ y /* g */ ) /* h */ { /* i */ ; /* j */ ; /* k */ }/* after */
+
+assert.sameValue(g.toString(), "function /* a */ * /* b */ name /* c */ ( /* d */ x /* e */ , /* f */ y /* g */ ) /* h */ { /* i */ ; /* j */ ; /* k */ }");
diff --git a/test/built-ins/Function/prototype/toString/generator-method.js b/test/built-ins/Function/prototype/toString/generator-method.js
new file mode 100644
index 0000000000000000000000000000000000000000..60f6ceff34860fcfc17327a158640c46aaa628c7
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/generator-method.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-generator-function-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a generator method
+---*/
+
+let f = { /* before */* /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }/* after */ }.f;
+let g = { /* before */* /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }/* after */ }.g;
+
+assert.sameValue(f.toString(), "* /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }");
+assert.sameValue(g.toString(), "* /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }");
diff --git a/test/built-ins/Function/prototype/toString/getter-class-static.js b/test/built-ins/Function/prototype/toString/getter-class-static.js
new file mode 100644
index 0000000000000000000000000000000000000000..27a41a3b9e10ad2ff3c93efde89a9058d9456a26
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/getter-class-static.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a getter (class; static)
+---*/
+
+let f = Object.getOwnPropertyDescriptor(class { static /* before */get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }/* after */ }, "f").get;
+let g = Object.getOwnPropertyDescriptor(class { static /* before */get /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }/* after */ }, "g").get;
+
+assert.sameValue(f.toString(), "get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }");
+assert.sameValue(g.toString(), "get /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }");
diff --git a/test/built-ins/Function/prototype/toString/getter-class.js b/test/built-ins/Function/prototype/toString/getter-class.js
new file mode 100644
index 0000000000000000000000000000000000000000..91d584a6dcce14df06872407e62d37c304f3b712
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/getter-class.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a getter (class)
+---*/
+
+let f = Object.getOwnPropertyDescriptor(class { /* before */get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }/* after */ }.prototype, "f").get;
+let g = Object.getOwnPropertyDescriptor(class { /* before */get /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }/* after */ }.prototype, "g").get;
+
+assert.sameValue(f.toString(), "get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }");
+assert.sameValue(g.toString(), "get /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }");
diff --git a/test/built-ins/Function/prototype/toString/getter-object.js b/test/built-ins/Function/prototype/toString/getter-object.js
new file mode 100644
index 0000000000000000000000000000000000000000..e2859484ee085aebb338dd275e98aff162701c46
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/getter-object.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a getter (object)
+---*/
+
+let f = Object.getOwnPropertyDescriptor({ /* before */get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }/* after */ }, "f").get;
+let g = Object.getOwnPropertyDescriptor({ /* before */get /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }/* after */ }, "g").get;
+
+assert.sameValue(f.toString(), "get /* a */ f /* b */ ( /* c */ ) /* d */ { /* e */ }");
+assert.sameValue(g.toString(), "get /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ ) /* f */ { /* g */ }");
diff --git a/test/built-ins/Function/prototype/toString/intrinsics.js b/test/built-ins/Function/prototype/toString/intrinsics.js
new file mode 100644
index 0000000000000000000000000000000000000000..dc13195961869b906bee4af89bf12f5da86f807c
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/intrinsics.js
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function.prototype.tostring
+description: Function.prototype.toString on well-known intrinsic function objects
+includes: [nativeFunctionMatcher.js]
+---*/
+
+let intrinsics = {
+  Array, ArrayBuffer, Boolean, DataView, Date, decodeURI, decodeURIComponent, encodeURI,
+  encodeURIComponent, Error, eval, EvalError, Float32Array, Float64Array, Function, Int8Array,
+  Int16Array, Int32Array, isFinite, isNaN, Map, Number, Object, parseFloat, parseInt, Promise,
+  Proxy, RangeError, ReferenceError, RegExp, Set, String, Symbol, SyntaxError, TypeError,
+  Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array, URIError, WeakMap, WeakSet,
+};
+
+for (let intrinsicName in intrinsics) {
+  let intrinsic = intrinsics[intrinsicName];
+  let str = Function.prototype.toString.call(intrinsic);
+  assert.sameValue(typeof str, "string");
+  assert(RegExp('\\b' + intrinsicName + '\\b').test(str), "contains its name");
+  assert(NATIVE_FUNCTION_RE.test(str), "looks pretty much like a NativeFunction");
+}
diff --git a/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js
new file mode 100644
index 0000000000000000000000000000000000000000..4ba923e2c56d9952a10efed3a316aab623ec7d33
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR-LF.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
+description: Function.prototype.toString line terminator normalisation (CR-LF)
+info: >
+  Function.prototype.toString should normalise line terminator sequences to Line Feed characters.
+  This file uses (Carriage Return, Line Feed) sequences as line terminators.
+---*/
+
+// before
+function
+// a
+f
+// b
+(
+// c
+x
+// d
+,
+// e
+y
+// f
+)
+// g
+{
+// h
+;
+// i
+;
+// j
+}
+// after
+
+assert.sameValue(f.toString(), "function\n// a\nf\n// b\n(\n// c\nx\n// d\n,\n// e\ny\n// f\n)\n// g\n{\n// h\n;\n// i\n;\n// j\n}");
diff --git a/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js
new file mode 100644
index 0000000000000000000000000000000000000000..c5ac08262861a73135ec409d7c6461cdc86a1ebf
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-CR.js
@@ -0,0 +1 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
description: Function.prototype.toString line terminator normalisation (CR)
info: >
  Function.prototype.toString should normalise line terminator sequences to Line Feed characters.
  This file uses Carriage Return characters as line terminators.
---*/

// before
function
// a
f
// b
(
// c
x
// d
,
// e
y
// f
)
// g
{
// h
;
// i
;
// j
}
// after

assert.sameValue(f.toString(), "function\n// a\nf\n// b\n(\n// c\nx\n// d\n,\n// e\ny\n// f\n)\n// g\n{\n// h\n;\n// i\n;\n// j\n}");
\ No newline at end of file
diff --git a/test/built-ins/Function/prototype/toString/line-terminator-normalisation-LF.js b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-LF.js
new file mode 100644
index 0000000000000000000000000000000000000000..1984e451ad1cb5627c1bf200cf29164028c3f318
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/line-terminator-normalisation-LF.js
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function-definitions-runtime-semantics-instantiatefunctionobject
+description: Function.prototype.toString line terminator normalisation (LF)
+info: >
+  Function.prototype.toString should normalise line terminator sequences to Line Feed characters.
+  This file uses Line Feed characters as line terminators.
+---*/
+
+// before
+function
+// a
+f
+// b
+(
+// c
+x
+// d
+,
+// e
+y
+// f
+)
+// g
+{
+// h
+;
+// i
+;
+// j
+}
+// after
+
+assert.sameValue(f.toString(), "function\n// a\nf\n// b\n(\n// c\nx\n// d\n,\n// e\ny\n// f\n)\n// g\n{\n// h\n;\n// i\n;\n// j\n}");
diff --git a/test/built-ins/Function/prototype/toString/method-class-static.js b/test/built-ins/Function/prototype/toString/method-class-static.js
new file mode 100644
index 0000000000000000000000000000000000000000..5ebb90c7442917fd3cb5f6b84ec7da85a9a004b3
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/method-class-static.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-definemethod
+description: Function.prototype.toString on a method (class; static)
+---*/
+
+let f = class { static /* before */f /* a */ ( /* b */ ) /* c */ { /* d */ }/* after */ }.f;
+let g = class { static /* before */[ /* a */ "g" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }/* after */ }.g;
+
+assert.sameValue(f.toString(), "f /* a */ ( /* b */ ) /* c */ { /* d */ }");
+assert.sameValue(g.toString(), "[ /* a */ \"g\" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }");
diff --git a/test/built-ins/Function/prototype/toString/method-class.js b/test/built-ins/Function/prototype/toString/method-class.js
new file mode 100644
index 0000000000000000000000000000000000000000..76b43a852feece217eb13e5ab4e0947827bed802
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/method-class.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-definemethod
+description: Function.prototype.toString on a method (class)
+---*/
+
+let f = class { /* before */f /* a */ ( /* b */ ) /* c */ { /* d */ }/* after */ }.prototype.f;
+let g = class { /* before */[ /* a */ "g" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }/* after */ }.prototype.g;
+
+assert.sameValue(f.toString(), "f /* a */ ( /* b */ ) /* c */ { /* d */ }");
+assert.sameValue(g.toString(), "[ /* a */ \"g\" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }");
diff --git a/test/built-ins/Function/prototype/toString/method-computed-property-name.js b/test/built-ins/Function/prototype/toString/method-computed-property-name.js
new file mode 100644
index 0000000000000000000000000000000000000000..dcf692d23d7c6a813592020062178de131edcc57
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/method-computed-property-name.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-definemethod
+description: Function.prototype.toString on a method (object)
+---*/
+
+let f = { /* before */[ /* a */ "f" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }/* after */ }.f;
+let g = { [ { a(){} }.a ](){ } }["a(){}"];
+
+assert.sameValue(f.toString(), "[ /* a */ \"f\" /* b */ ] /* c */ ( /* d */ ) /* e */ { /* f */ }");
+assert.sameValue("" + g, "[ { a(){} }.a ](){ }");
diff --git a/test/built-ins/Function/prototype/toString/method-object.js b/test/built-ins/Function/prototype/toString/method-object.js
new file mode 100644
index 0000000000000000000000000000000000000000..6930964ed15c24d541fb0ef4894b5d93b6f56252
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/method-object.js
@@ -0,0 +1,11 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-runtime-semantics-definemethod
+description: Function.prototype.toString on a method (object)
+---*/
+
+let f = { /* before */f /* a */ ( /* b */ ) /* c */ { /* d */ }/* after */ }.f;
+
+assert.sameValue(f.toString(), "f /* a */ ( /* b */ ) /* c */ { /* d */ }");
diff --git a/test/built-ins/Function/prototype/toString/name.js b/test/built-ins/Function/prototype/toString/name.js
old mode 100755
new mode 100644
diff --git a/test/built-ins/Function/prototype/toString/setter-class-static.js b/test/built-ins/Function/prototype/toString/setter-class-static.js
new file mode 100644
index 0000000000000000000000000000000000000000..0a3041a95d3fe9fd2e057997c274eabd82c13ee4
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/setter-class-static.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a setter (class; static)
+---*/
+
+let f = Object.getOwnPropertyDescriptor(class { static /* before */set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }/* after */ }, "f").set;
+let g = Object.getOwnPropertyDescriptor(class { static /* before */set /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }/* after */ }, "g").set;
+
+assert.sameValue(f.toString(), "set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }");
+assert.sameValue(g.toString(), "set /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }");
diff --git a/test/built-ins/Function/prototype/toString/setter-class.js b/test/built-ins/Function/prototype/toString/setter-class.js
new file mode 100644
index 0000000000000000000000000000000000000000..e83f478bc4926ae6ab1814351500dbb73fc9211f
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/setter-class.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a setter (class)
+---*/
+
+let f = Object.getOwnPropertyDescriptor(class { /* before */set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }/* after */ }.prototype, "f").set;
+let g = Object.getOwnPropertyDescriptor(class { /* before */set /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }/* after */ }.prototype, "g").set;
+
+assert.sameValue(f.toString(), "set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }");
+assert.sameValue(g.toString(), "set /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }");
diff --git a/test/built-ins/Function/prototype/toString/setter-object.js b/test/built-ins/Function/prototype/toString/setter-object.js
new file mode 100644
index 0000000000000000000000000000000000000000..8432d5ca6c1bc4e5dcae3dde81a176de62023ef6
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/setter-object.js
@@ -0,0 +1,13 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-method-definitions-runtime-semantics-propertydefinitionevaluation
+description: Function.prototype.toString on a setter (object)
+---*/
+
+let f = Object.getOwnPropertyDescriptor({ /* before */set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }/* after */ }, "f").set;
+let g = Object.getOwnPropertyDescriptor({ /* before */set /* a */ [ /* b */ "g" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }/* after */ }, "g").set;
+
+assert.sameValue(f.toString(), "set /* a */ f /* b */ ( /* c */ a /* d */ ) /* e */ { /* f */ }");
+assert.sameValue(g.toString(), "set /* a */ [ /* b */ \"g\" /* c */ ] /* d */ ( /* e */ a /* f */ ) /* g */ { /* h */ }");
diff --git a/test/built-ins/Function/prototype/toString/unicode.js b/test/built-ins/Function/prototype/toString/unicode.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd1b42f8154427eacaba904e8994d117cfd16355
--- /dev/null
+++ b/test/built-ins/Function/prototype/toString/unicode.js
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-function.prototype.tostring
+description: Function.prototype.toString on a function with Unicode escape sequences
+info: >
+  Function.prototype.toString returns a slice of the source text before
+  any potential Unicode escape sequence substitution in identifiers
+---*/
+
+function \u0061(\u{62}, \u0063) { \u0062 = \u{00063}; return b; }
+
+assert.sameValue(a.toString(), "function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }");
diff --git a/test/harness/nativeFunctionMatcher.js b/test/harness/nativeFunctionMatcher.js
new file mode 100644
index 0000000000000000000000000000000000000000..6bd51fc357d7621ad6a0d29a6964444f1d25e999
--- /dev/null
+++ b/test/harness/nativeFunctionMatcher.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 Michael Ficarra. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+description: >
+    Provides a regex that makes a best-effort determination that the tested
+    string matches the NativeFunction grammar production without requiring a
+    correct tokeniser
+includes: [nativeFunctionHelper.js]
+---*/
+
+if (!(
+  NATIVE_FUNCTION_RE.test('function(){[native function]}') &&
+  NATIVE_FUNCTION_RE.test('function(){ [native function] }') &&
+  NATIVE_FUNCTION_RE.test('function ( ) { [ native function ] }') &&
+  NATIVE_FUNCTION_RE.test('function a(){ [native function] }') &&
+  NATIVE_FUNCTION_RE.test('function a(){ /* } */ [native function] }') &&
+  !NATIVE_FUNCTION_RE.test('') &&
+  !NATIVE_FUNCTION_RE.test('native function') &&
+  !NATIVE_FUNCTION_RE.test('function(){}') &&
+  !NATIVE_FUNCTION_RE.test('function(){ "native function" }') &&
+  !NATIVE_FUNCTION_RE.test('function(){ [] native function }')
+)) $ERROR('NATIVE_FUNCTION_RE failed');