From ba734ee7b90647786782ad81dbb2f861cfb529c6 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 14 Nov 2016 20:07:37 +0200 Subject: [PATCH 1/3] Update Object.prototype.__proto__ testcase --- .../test-bi-object-proto-__proto__.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/ecmascript/test-bi-object-proto-__proto__.js b/tests/ecmascript/test-bi-object-proto-__proto__.js index 0f40faab..ed13376f 100644 --- a/tests/ecmascript/test-bi-object-proto-__proto__.js +++ b/tests/ecmascript/test-bi-object-proto-__proto__.js @@ -27,6 +27,9 @@ boolean undefined undefined number undefined undefined string undefined undefined object 123 321 +true +TypeError +TypeError ===*/ function test() { @@ -120,7 +123,30 @@ function test() { print('no setter'); } - // TODO: coercion order tests (side effect / error message if multiple errors) + // The __proto__ getter uses ToObject() coercion for its argument so that + // e.g. (123).__proto__ is allowed. This differs from Object.getPrototypeOf() + // in ES5. However, ES6 updates Object.getPrototypeOf() to use ToObject() + // coercion too. Null and undefined are rejected as base values. + + try { + print((123).__proto__ === Number.prototype); + } catch (e) { + print(e.stack || e); + } + + try { + print(null.__proto__ === Number.prototype); + } catch (e) { + print(e.name); + } + + try { + print((void 0).__proto__ === Number.prototype); + } catch (e) { + print(e.name); + } + + // XXX: coercion order tests (side effect / error message if multiple errors) } try { From 7dee4f22aef7c0c795f122a363f48a4d801f8224 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 14 Nov 2016 20:10:34 +0200 Subject: [PATCH 2/3] Fix Object.prototype.__proto__ ToObject() coercion --- src-input/duk_bi_object.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src-input/duk_bi_object.c b/src-input/duk_bi_object.c index 88dc74af..cbd1c735 100644 --- a/src-input/duk_bi_object.c +++ b/src-input/duk_bi_object.c @@ -379,11 +379,12 @@ DUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx) { duk_tval *tv; if (duk_get_current_magic(ctx) == 0) { + DUK_ASSERT_TOP(ctx, 0); + duk_push_this_coercible_to_object(ctx); tv = DUK_HTHREAD_THIS_PTR(thr); - } else { - DUK_ASSERT(duk_get_top(ctx) >= 1); - tv = DUK_GET_TVAL_POSIDX(ctx, 0); } + DUK_ASSERT(duk_get_top(ctx) >= 1); + tv = DUK_GET_TVAL_POSIDX(ctx, 0); switch (DUK_TVAL_GET_TAG(tv)) { case DUK_TAG_BUFFER: From 1e71750dece64c6927658be9b645bc5ad53fab32 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 14 Nov 2016 20:10:38 +0200 Subject: [PATCH 3/3] Releases: Object.prototype.__proto__ fix --- RELEASES.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/RELEASES.rst b/RELEASES.rst index c6c5567a..e7eeac7f 100644 --- a/RELEASES.rst +++ b/RELEASES.rst @@ -1958,6 +1958,10 @@ Planned ES6 and other engines; "\078" is now accepted and is the same as "\u00078", "\8" and "\9" are accepted as literal "8" and "9" (GH-1057) +* Fix Object.prototype.__proto__ handling to use ToObject() coercion rather + than requiring an object; this matches ES6 requirements and allows e.g. + the expression (123).__proto__ to work (GH-1080) + * Fix String.fromCharCode() behavior for non-BMP characters when standard behavior is enabled (DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT disabled): use ToUint16() + CESU-8 rather than ToUint32() + CESU-8 which produces