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 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: 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 {