Browse Source

Merge pull request #1177 from svaarala/builtin-function-length-configurable

Make built-in function .length and .name configurable
pull/1183/head
Sami Vaarala 8 years ago
committed by GitHub
parent
commit
5222fb5116
  1. 2
      RELEASES.rst
  2. 3
      extras/console/duk_console.c
  3. 3
      extras/logging/duk_logging.c
  4. 30
      src-input/duk_hthread_builtins.c
  5. 10
      tests/api/test-bug-set-cfunc-name.c
  6. 6
      tests/api/test-def-prop.c
  7. 6
      tests/api/test-dev-cfunc-name.c
  8. 3
      tests/api/test-inspect-callstack-entry.c
  9. 56
      tests/ecmascript/test-bi-duktape.js
  10. 12
      tests/ecmascript/test-bi-error-instance-custom.js
  11. 3
      tests/ecmascript/test-bi-function-constructor.js
  12. 23
      tests/ecmascript/test-bi-function-instance.js
  13. 8
      tests/ecmascript/test-bi-function-prototype.js
  14. 68
      tests/ecmascript/test-bi-properties.js
  15. 55
      tests/ecmascript/test-dev-es6-builtin-func-props.js
  16. 8
      tools/genbuiltins.py

2
RELEASES.rst

@ -2088,7 +2088,7 @@ Planned
* Make function instance .name and .length properties configurable (but
non-writable and non-enumerable) to match ES6 requirements; also change
.fileName to follow the same attribute convention (GH-1153)
.fileName to follow the same attribute convention (GH-1153, GH-1177)
* Make Error instance .fileName and .lineNumber properties configurable
but non-writable and non-enumerable to match function instance property

3
extras/console/duk_console.c

@ -100,8 +100,9 @@ static duk_ret_t duk__console_dir(duk_context *ctx) {
static void duk__console_reg_vararg_func(duk_context *ctx, duk_c_function func, const char *name) {
duk_push_c_function(ctx, func, DUK_VARARGS);
duk_push_string(ctx, "name");
duk_push_string(ctx, name);
duk_put_prop_string(ctx, -2, "name"); /* Improve stacktraces by displaying function name */
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE); /* Improve stacktraces by displaying function name */
duk_put_prop_string(ctx, -2, name);
}

3
extras/logging/duk_logging.c

@ -334,8 +334,9 @@ void duk_logging_init(duk_context *ctx, duk_uint_t flags) {
/* [ ... func Duktape.Logger Duktape.Logger.prototype ] */
duk_push_string(ctx, "name");
duk_push_string(ctx, "Logger");
duk_put_prop_string(ctx, -3, "name");
duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);
duk_dup_top(ctx);
duk_put_prop_string(ctx, -2, "constructor");

30
src-input/duk_hthread_builtins.c

@ -264,17 +264,12 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/* XXX: function properties */
/* Built-in 'name' is not writable by default. Function '.name'
* is writable to allow user code to set a '.name' on a native
* function.
*/
duk__push_stridx_or_string(ctx, bd);
#if defined(DUK_USE_FUNC_NAME_PROPERTY)
duk_xdef_prop_stridx_short(ctx,
-2,
DUK_STRIDX_NAME,
(i == DUK_BIDX_FUNCTION_PROTOTYPE) ?
DUK_PROPDESC_FLAGS_W : DUK_PROPDESC_FLAGS_NONE);
DUK_PROPDESC_FLAGS_C);
#else
duk_pop(ctx); /* Not very ideal but good enough for now. */
#endif
@ -310,17 +305,14 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
}
if (len >= 0) {
/*
* For top-level objects, 'length' property has the following
* default attributes: non-writable, non-enumerable, non-configurable
* (E5 Section 15).
*
* However, 'length' property for Array.prototype has attributes
* expected of an Array instance which are different: writable,
* non-enumerable, non-configurable (E5 Section 15.4.5.2).
/* In ES2015+ built-in function object .length property
* has property attributes C (configurable only):
* http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects
*
* Because Array .length is virtual, it's not encoded in the init
* data separately.
* Array.prototype remains an Array instance in ES2015+
* and its length has attributes W (writable only).
* Because .length is now virtual for duk_harray, it is
* not encoded explicitly in init data.
*/
DUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY); /* .length is virtual */
@ -328,7 +320,7 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
duk_xdef_prop_stridx_short(ctx,
-2,
DUK_STRIDX_LENGTH,
DUK_PROPDESC_FLAGS_NONE); /* XXX */
DUK_PROPDESC_FLAGS_C);
}
/* enable exotic behaviors last */
@ -608,10 +600,10 @@ DUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {
/* [ (builtin objects) name func ] */
duk_push_int(ctx, c_length);
duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE); /* XXX */
duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);
duk_dup_m2(ctx);
duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);
duk_xdef_prop_stridx_short(ctx, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);
/* XXX: other properties of function instances; 'arguments', 'caller'. */

10
tests/api/test-bug-set-cfunc-name.c

@ -13,13 +13,16 @@
* while simultaneously allowing a Function instance's 'name' property
* to be set - but Ecmascript cannot express such an access control
* policy.
*
* Duktape 2.x follows ES6 where .name is again non-writable, but is
* configurable. So duk_def_prop() can be used to set the name.
*/
/*===
*** test_1 (duk_safe_call)
writable: true
writable: false
enumerable: false
configurable: false
configurable: true
MyFunc.name: my_func_name
final top: 0
==> rc=0, result='undefined'
@ -41,8 +44,9 @@ static duk_ret_t test_1(duk_context *ctx, void *udata) {
"print('configurable:', pd.configurable);\n");
duk_push_c_function(ctx, my_func, 0);
duk_push_string(ctx, "name");
duk_push_string(ctx, "my_func_name");
duk_put_prop_string(ctx, -2, "name");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
duk_put_global_string(ctx, "MyFunc");
duk_eval_string_noresult(ctx,

6
tests/api/test-def-prop.c

@ -243,8 +243,9 @@ static duk_ret_t my_setter(duk_context *ctx) {
static void push_getter(duk_context *ctx) {
duk_push_c_function(ctx, my_getter, 0 /*nargs*/);
duk_push_string(ctx, "name");
duk_push_string(ctx, "getter");
duk_put_prop_string(ctx, -2, "name");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
}
static void push_getter_lightfunc(duk_context *ctx) {
@ -253,8 +254,9 @@ static void push_getter_lightfunc(duk_context *ctx) {
static void push_setter(duk_context *ctx) {
duk_push_c_function(ctx, my_setter, 1 /*nargs*/);
duk_push_string(ctx, "name");
duk_push_string(ctx, "setter");
duk_put_prop_string(ctx, -2, "name");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
}
static void push_setter_lightfunc(duk_context *ctx) {

6
tests/api/test-dev-cfunc-name.c

@ -3,6 +3,9 @@
* You can set it yourself in Duktape 1.1 to get nicer tracebacks.
* In Duktape 1.0 Function.prototype.name is not writable so you can't
* do this.
*
* In Duktape 2.x .name is non-writable but configurable to match ES6
* requirements; duk_def_prop() can be used to set it.
*/
/*===
@ -51,8 +54,9 @@ static duk_ret_t test_with_name(duk_context *ctx, void *udata) {
(void) udata;
duk_get_global_string(ctx, "MyFunc");
duk_push_string(ctx, "name");
duk_push_string(ctx, "my_func");
duk_put_prop_string(ctx, -2, "name");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
duk_pop(ctx);
duk_eval_string_noresult(ctx,

3
tests/api/test-inspect-callstack-entry.c

@ -80,8 +80,9 @@ static duk_ret_t test_basic(duk_context *ctx, void *udata) {
" print('exited func');\n"
"})");
duk_push_c_function(ctx, my_func, 0 /*nargs*/);
duk_push_string(ctx, "name");
duk_push_string(ctx, "my_func");
duk_put_prop_string(ctx, -2, "name");
duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);
duk_call(ctx, 1);
duk_pop(ctx);

56
tests/ecmascript/test-bi-duktape.js

@ -26,43 +26,43 @@ Duktape.dec function wc
Duktape.compact function wc
Duktape.env string wc
Duktape.modLoaded object wc
Duktape.Pointer.name string none
Duktape.Pointer.length number none
Duktape.Pointer.name string c
Duktape.Pointer.length number c
Duktape.Pointer.prototype object none
Duktape.Pointer.prototype.constructor function wc
Duktape.Pointer.prototype.toString function wc
Duktape.Pointer.prototype.valueOf function wc
Duktape.Pointer.prototype.toString.length number none
Duktape.Pointer.prototype.toString.name string none
Duktape.Pointer.prototype.valueOf.length number none
Duktape.Pointer.prototype.valueOf.name string none
Duktape.Thread.name string none
Duktape.Thread.length number none
Duktape.Pointer.prototype.toString.length number c
Duktape.Pointer.prototype.toString.name string c
Duktape.Pointer.prototype.valueOf.length number c
Duktape.Pointer.prototype.valueOf.name string c
Duktape.Thread.name string c
Duktape.Thread.length number c
Duktape.Thread.prototype object none
Duktape.Thread.yield function wc
Duktape.Thread.resume function wc
Duktape.Thread.current function wc
Duktape.Thread.prototype.constructor function wc
Duktape.Thread.yield.length number none
Duktape.Thread.yield.name string none
Duktape.Thread.resume.length number none
Duktape.Thread.resume.name string none
Duktape.Thread.current.length number none
Duktape.Thread.current.name string none
Duktape.info.length number none
Duktape.info.name string none
Duktape.act.length number none
Duktape.act.name string none
Duktape.gc.length number none
Duktape.gc.name string none
Duktape.fin.length number none
Duktape.fin.name string none
Duktape.enc.length number none
Duktape.enc.name string none
Duktape.dec.length number none
Duktape.dec.name string none
Duktape.compact.length number none
Duktape.compact.name string none
Duktape.Thread.yield.length number c
Duktape.Thread.yield.name string c
Duktape.Thread.resume.length number c
Duktape.Thread.resume.name string c
Duktape.Thread.current.length number c
Duktape.Thread.current.name string c
Duktape.info.length number c
Duktape.info.name string c
Duktape.act.length number c
Duktape.act.name string c
Duktape.gc.length number c
Duktape.gc.name string c
Duktape.fin.length number c
Duktape.fin.name string c
Duktape.enc.length number c
Duktape.enc.name string c
Duktape.dec.length number c
Duktape.dec.name string c
Duktape.compact.length number c
Duktape.compact.name string c
===*/
function propsTest() {

12
tests/ecmascript/test-bi-error-instance-custom.js

@ -40,12 +40,16 @@ all properties (including non-enumerable and inherited)
"isPrototypeOf"
"propertyIsEnumerable"
---
function function false true
function function false true
function function false true
===*/
function test() {
var err;
var k;
var obj;
var pd;
err = new Error('my message');
@ -77,6 +81,14 @@ function test() {
obj = Object.getPrototypeOf(obj);
}
print('---');
// Check a few Duktape 2.x property attributes.
pd = Object.getOwnPropertyDescriptor(Error.prototype, 'fileName');
print(typeof pd.get, typeof pd.set, pd.enumerable, pd.configurable);
pd = Object.getOwnPropertyDescriptor(Error.prototype, 'lineNumber');
print(typeof pd.get, typeof pd.set, pd.enumerable, pd.configurable);
pd = Object.getOwnPropertyDescriptor(Error.prototype, 'stack');
print(typeof pd.get, typeof pd.set, pd.enumerable, pd.configurable);
}
try {

3
tests/ecmascript/test-bi-function-constructor.js

@ -7,6 +7,7 @@ constructor
true true
false false false
true 1
false false true
no args
no args
one arg foo
@ -31,7 +32,7 @@ function functionConstructorTest() {
print(pd.writable, pd.enumerable, pd.configurable);
print('length' in Function, Function.length);
pd = Object.getOwnPropertyDescriptor(Function, 'length');
// print(pd.writable, pd.enumerable, pd.configurable);
print(pd.writable, pd.enumerable, pd.configurable);
/* Test Function() called both as a function and as a constructor. */

23
tests/ecmascript/test-bi-function-instance.js

@ -14,6 +14,12 @@ true 3
false false true
true test
false false true
""
true true
""
true true
"forcedName2"
true true
===*/
function functionInstanceTest() {
@ -36,6 +42,23 @@ function functionInstanceTest() {
print('name' in f, f.name);
pd = Object.getOwnPropertyDescriptor(f, 'name');
print(pd.writable, pd.enumerable, pd.configurable);
// Anonymous functions don't have an 'own' .name property but inherit
// an empty string name from Function.prototype. The property .name in
// Function.prototype is not writable, but it is configurable, so that
// Object.defineProperty() can be used to add a name later on.
// XXX: not yet implemented, expect string for having a .name.
var anon = (1, 2, 3, function () {});
print(JSON.stringify(anon.name)); // inherited
print('name' in anon, anon.hasOwnProperty('name'));
anon.name = 'forcedName'; // ineffective, not configurable
print(JSON.stringify(anon.name));
print('name' in anon, anon.hasOwnProperty('name'));
Object.defineProperty(anon, 'name', { value: 'forcedName2' });
print(JSON.stringify(anon.name));
print('name' in anon, anon.hasOwnProperty('name'));
}
try {

8
tests/ecmascript/test-bi-function-prototype.js

@ -10,10 +10,12 @@ true
true 0
true true
undefined undefined
string "" false false true
===*/
function functionPrototypeTest() {
var ret;
var pd;
print(Object.prototype.toString.call(Function.prototype));
print(Object.getPrototypeOf(Function.prototype) === Object.prototype);
@ -23,6 +25,12 @@ function functionPrototypeTest() {
ret = Function.prototype('foo', 'bar');
print(typeof ret, ret);
// ES6 added '.name'. Function.prototype provides an empty default name.
// It is not writable, but it is configurable so that Object.defineProperty()
// can be used to set the name of an anonymous function.
pd = Object.getOwnPropertyDescriptor(Function.prototype, 'name');
print(typeof pd.value, JSON.stringify(pd.value), pd.writable, pd.enumerable, pd.configurable);
}
try {

68
tests/ecmascript/test-bi-properties.js

@ -99,7 +99,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', attrs: '' },
{ key: 'getPrototypeOf', attrs: 'wc' },
{ key: 'getOwnPropertyDescriptor', attrs: 'wc' },
@ -141,9 +141,8 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'prototype', 'attrs': '' },
{ key: 'length', 'attrs': '' },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', 'attrs': '' }
],
noprops: [
],
@ -154,7 +153,7 @@ var obj_data = [
proto: 'Object.prototype',
class: 'Function', // E5 Section 15.3.4
props: [
{ key: 'length', 'attrs': '', value: 0 }, // E5 Section 15.3.4
{ key: 'length', 'attrs': 'c', value: 0 },
{ key: 'constructor', 'attrs': 'wc' },
{ key: 'toString', 'attrs': 'wc' },
{ key: 'apply', 'attrs': 'wc' },
@ -170,7 +169,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
{ key: 'isArray', 'attrs': 'wc' },
],
@ -217,7 +216,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
{ key: 'fromCharCode', 'attrs': 'wc' },
],
@ -262,7 +261,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -288,7 +287,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 1 },
{ key: 'length', attrs: 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
{ key: 'MAX_VALUE', 'attrs': '' },
{ key: 'MIN_VALUE', 'attrs': '' },
@ -360,7 +359,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 7 }, // E5 Section 15.9.4
{ key: 'length', attrs: 'c', value: 7 }, // E5 Section 15.9.4
{ key: 'prototype', 'attrs': '' },
{ key: 'parse', 'attrs': 'wc' },
{ key: 'UTC', 'attrs': 'wc' },
@ -429,7 +428,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', attrs: '', value: 2 }, // E5 Section 15.10.5
{ key: 'length', attrs: 'c', value: 2 }, // E5 Section 15.10.5
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -456,7 +455,7 @@ var obj_data = [
proto: 'Function.prototype',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -483,7 +482,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -509,7 +508,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -535,7 +534,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -561,7 +560,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -587,7 +586,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -613,7 +612,7 @@ var obj_data = [
proto: 'Error',
class: 'Function',
props: [
{ key: 'length', 'attrs': '', value: 1 },
{ key: 'length', 'attrs': 'c', value: 1 },
{ key: 'prototype', 'attrs': '' },
],
noprops: [
@ -841,7 +840,7 @@ NOPROPERTY: "length"
OBJECT: "Object" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "getPrototypeOf" writable !enumerable configurable
PROPERTY: "getOwnPropertyDescriptor" writable !enumerable configurable
@ -871,14 +870,13 @@ NOPROPERTY: "length"
OBJECT: "Function" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable !configurable
OBJECT: "Function.prototype" !sealed !frozen extensible
PROTOTYPE: "Object.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "constructor" writable !enumerable configurable
PROPERTY: "toString" writable !enumerable configurable
PROPERTY: "apply" writable !enumerable configurable
@ -888,7 +886,7 @@ PROPERTY: "bind" writable !enumerable configurable
OBJECT: "Array" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "isArray" writable !enumerable configurable
@ -922,7 +920,7 @@ PROPERTY: "reduceRight" writable !enumerable configurable
OBJECT: "String" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "fromCharCode" writable !enumerable configurable
@ -954,7 +952,7 @@ PROPERTY: "trim" writable !enumerable configurable
OBJECT: "Boolean" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "Boolean.prototype" !sealed !frozen extensible
@ -968,7 +966,7 @@ NOPROPERTY: "length"
OBJECT: "Number" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "MAX_VALUE" !writable !enumerable !configurable
PROPERTY: "MIN_VALUE" !writable !enumerable !configurable
@ -1022,7 +1020,7 @@ NOPROPERTY: "length"
OBJECT: "Date" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
PROPERTY: "parse" writable !enumerable configurable
PROPERTY: "UTC" writable !enumerable configurable
@ -1079,7 +1077,7 @@ NOPROPERTY: "length"
OBJECT: "RegExp" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "RegExp.prototype" !sealed !frozen extensible
@ -1094,7 +1092,7 @@ NOPROPERTY: "length"
OBJECT: "Error" !sealed !frozen extensible
PROTOTYPE: "Function.prototype"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "Error.prototype" !sealed !frozen extensible
@ -1109,7 +1107,7 @@ NOPROPERTY: "length"
OBJECT: "EvalError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "EvalError.prototype" !sealed !frozen extensible
@ -1123,7 +1121,7 @@ NOPROPERTY: "length"
OBJECT: "RangeError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "RangeError.prototype" !sealed !frozen extensible
@ -1137,7 +1135,7 @@ NOPROPERTY: "length"
OBJECT: "ReferenceError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "ReferenceError.prototype" !sealed !frozen extensible
@ -1151,7 +1149,7 @@ NOPROPERTY: "length"
OBJECT: "SyntaxError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "SyntaxError.prototype" !sealed !frozen extensible
@ -1165,7 +1163,7 @@ NOPROPERTY: "length"
OBJECT: "TypeError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "TypeError.prototype" !sealed !frozen extensible
@ -1179,7 +1177,7 @@ NOPROPERTY: "length"
OBJECT: "URIError" !sealed !frozen extensible
PROTOTYPE: "Error"
CLASS: Function
PROPERTY: "length" !writable !enumerable !configurable
PROPERTY: "length" !writable !enumerable configurable
PROPERTY: "prototype" !writable !enumerable !configurable
OBJECT: "URIError.prototype" !sealed !frozen extensible

55
tests/ecmascript/test-dev-es6-builtin-func-props.js

@ -0,0 +1,55 @@
/*
* Some ES6 built-in .length and .name spot checks
*/
/*===
function
.name string cos false false true
.length number 1 false false true
function
.name string stringify false false true
.length number 3 false false true
function
.name string hasOwnProperty false false true
.length number 1 false false true
function
.name none
.length none
===*/
function test() {
var pd;
function dump(f) {
print(typeof f);
var pd = Object.getOwnPropertyDescriptor(f, 'name');
if (pd) {
print('.name', typeof pd.value, pd.value, pd.writable, pd.enumerable, pd.configurable);
} else {
print('.name', 'none');
}
var pd = Object.getOwnPropertyDescriptor(f, 'length');
if (pd) {
print('.length', typeof pd.value, pd.value, pd.writable, pd.enumerable, pd.configurable);
} else {
print('.length', 'none');
}
}
// In ES6 function .name and .length are non-writable, non-enumerable,
// but configurable. This also applies to built-ins. Spot check a few.
dump(Math.cos);
dump(JSON.stringify);
dump(Object.prototype.hasOwnProperty);
// Currently missing .name and .length: https://github.com/svaarala/duktape/issues/1187
pd = Object.getOwnPropertyDescriptor(RegExp.prototype, 'source'); // getter in ES6
dump(pd.get);
}
try {
test();
} catch (e) {
print(e.stack || e);
}

8
tools/genbuiltins.py

@ -391,8 +391,8 @@ def metadata_normalize_shorthand(meta):
obj['class'] = 'Function'
obj['callable'] = True
obj['constructable'] = val.get('constructable', False)
props.append({ 'key': 'length', 'value': val['length'], 'attributes': '' })
props.append({ 'key': 'name', 'value': funprop['key'], 'attributes': '' })
props.append({ 'key': 'length', 'value': val['length'], 'attributes': 'c' }) # Configurable in ES6
props.append({ 'key': 'name', 'value': funprop['key'], 'attributes': 'c' }) # Configurable in ES6
return obj
def addAccessor(funprop, magic, nargs, length, name, native_func):
@ -409,8 +409,8 @@ def metadata_normalize_shorthand(meta):
obj['constructable'] = False
# Shorthand accessors are minimal and have no .length or .name
# right now. Use longhand if these matter.
#props.append({ 'key': 'length', 'value': length, 'attributes': '' })
#props.append({ 'key': 'name', 'value': name, 'attributes': '' })
#props.append({ 'key': 'length', 'value': length, 'attributes': 'c' })
#props.append({ 'key': 'name', 'value': name, 'attributes': 'c' })
return obj
def decodeGetterShorthand(key, funprop):

Loading…
Cancel
Save