From fc00f4c2a426a9cb5ea7d2ba7a371b61e200813f Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Thu, 15 Dec 2016 02:04:25 +0200 Subject: [PATCH 1/4] Typedarray ES6 inheritance changes --- src-input/builtins.yaml | 241 ++++++++++++++++++++++------------------ 1 file changed, 131 insertions(+), 110 deletions(-) diff --git a/src-input/builtins.yaml b/src-input/builtins.yaml index 525e3d6c..a5ad8857 100644 --- a/src-input/builtins.yaml +++ b/src-input/builtins.yaml @@ -485,7 +485,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -493,7 +493,7 @@ objects: attributes: "" - key: "name" value: "Object" - attributes: "" + attributes: "c" - key: "getPrototypeOf" value: @@ -672,7 +672,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -680,7 +680,7 @@ objects: attributes: "" - key: "name" value: "Function" - attributes: "" + attributes: "c" # Note, unlike other prototype objects, Function.prototype is itself # a Function and callable. When invoked, it accepts any arguments @@ -699,7 +699,7 @@ objects: properties: - key: "length" value: 0 - attributes: "" + attributes: "c" present_if: DUK_USE_FUNCTION_BUILTIN - key: "constructor" value: @@ -708,16 +708,10 @@ objects: attributes: "wc" present_if: DUK_USE_FUNCTION_BUILTIN - # Each built-in of class Function has a "name" which is - # non-writable (the empty string above). Function.prototype - # is a special case: it is a function but we want it's name - # to be writable so that user code can set a "name" property - # for Duktape/C functions. If the Function.prototype.name - # property were non-writable, that would be prevented due to - # standard Ecmascript property write semantics. + # In ES6 Function.prototype.name is not writable, but is configurable. - key: "name" value: "" - attributes: "w" + attributes: "c" #present_if: DUK_USE_FUNCTION_BUILTIN # Kept even when prototype is otherwise empty to guarantee a .name for functions # test262 ch15/15.3/15.3.4/15.3.4.2/S15.3.4.2_A11 checks that Function.prototype.toString.length @@ -763,7 +757,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -771,7 +765,7 @@ objects: attributes: "" - key: "name" value: "Array" - attributes: "" + attributes: "c" - key: "isArray" value: type: function @@ -974,7 +968,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -982,7 +976,7 @@ objects: attributes: "" - key: "name" value: "String" - attributes: "" + attributes: "c" - key: "fromCharCode" value: @@ -1203,7 +1197,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -1211,7 +1205,7 @@ objects: attributes: "" - key: "name" value: "Boolean" - attributes: "" + attributes: "c" - id: bi_boolean_prototype class: Boolean @@ -1264,7 +1258,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -1272,7 +1266,7 @@ objects: attributes: "" - key: "name" value: "Number" - attributes: "" + attributes: "c" - key: "MAX_VALUE" value: type: double @@ -1372,7 +1366,7 @@ objects: properties: - key: "length" value: 7 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -1380,7 +1374,7 @@ objects: attributes: "" - key: "name" value: "Date" - attributes: "" + attributes: "c" - key: "parse" value: @@ -1763,7 +1757,7 @@ objects: properties: - key: "length" value: 2 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -1771,7 +1765,7 @@ objects: attributes: "" - key: "name" value: "RegExp" - attributes: "" + attributes: "c" - id: bi_regexp_prototype class: Object # Object in ES6; RegExp in ES5 @@ -1893,7 +1887,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -1901,7 +1895,7 @@ objects: attributes: "" - key: "name" value: "Error" - attributes: "" + attributes: "c" - id: bi_error_prototype class: Error @@ -2000,7 +1994,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2008,7 +2002,7 @@ objects: attributes: "" - key: "name" value: "EvalError" - attributes: "" + attributes: "c" - id: bi_eval_error_prototype class: Error @@ -2040,7 +2034,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2048,7 +2042,7 @@ objects: attributes: "" - key: "name" value: "RangeError" - attributes: "" + attributes: "c" - id: bi_range_error_prototype class: Error @@ -2080,7 +2074,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2088,7 +2082,7 @@ objects: attributes: "" - key: "name" value: "ReferenceError" - attributes: "" + attributes: "c" - id: bi_reference_error_prototype class: Error @@ -2120,7 +2114,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2128,7 +2122,7 @@ objects: attributes: "" - key: "name" value: "SyntaxError" - attributes: "" + attributes: "c" - id: bi_syntax_error_prototype class: Error @@ -2160,7 +2154,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2168,7 +2162,7 @@ objects: attributes: "" - key: "name" value: "TypeError" - attributes: "" + attributes: "c" - id: bi_type_error_prototype class: Error @@ -2200,7 +2194,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" - key: "prototype" value: type: object @@ -2208,7 +2202,7 @@ objects: attributes: "" - key: "name" value: "URIError" - attributes: "" + attributes: "c" - id: bi_uri_error_prototype class: Error @@ -2498,11 +2492,12 @@ objects: properties: - key: "length" value: 0 - attributes: "" - # custom name, matches V8 + attributes: "c" + # Custom name, matches V8; ES2016 describes %ThrowTypeError% as being + # anonymous. - key: "name" value: "ThrowTypeError" - attributes: "" + attributes: "c" duktape: true # @@ -2604,7 +2599,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" duktape: true - key: "prototype" value: @@ -2614,7 +2609,7 @@ objects: duktape: true - key: "name" value: "Thread" - attributes: "" + attributes: "c" duktape: true # "yield" is a reserved word but does not prevent its use as a property name @@ -2687,7 +2682,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" duktape: true - key: "prototype" value: @@ -2697,7 +2692,7 @@ objects: duktape: true - key: "name" value: "Pointer" - attributes: "" + attributes: "c" duktape: true - id: bi_pointer_prototype @@ -2775,11 +2770,11 @@ objects: properties: - key: "length" value: 2 - attributes: "" + attributes: "c" es6: true - key: "name" value: "Proxy" - attributes: "" + attributes: "c" es6: true #- key: "revocable" # value: @@ -2905,7 +2900,7 @@ objects: properties: - key: "length" value: 1 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -2915,12 +2910,10 @@ objects: attributes: "" typedarray: true es6: true - - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "ArrayBuffer" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "isView" value: @@ -2994,7 +2987,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3004,12 +2997,10 @@ objects: attributes: "" typedarray: true es6: true - - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "DataView" - attributes: "" - duktape: true + attributes: "c" + es6: true - id: bi_dataview_prototype class: Object @@ -3256,6 +3247,45 @@ objects: typedarray: true es6: true + # %TypedArray% constructor + # Prototype object providing properties shared by all TypedArray + # constructors. Callable, but duk_bi_typedarray_constructor() + # rejects normal calls with TypeError; not constructable which + # rejects constructor calls with TypeError. + - id: bi_typedarray_constructor + class: Function + internal_prototype: bi_function_prototype + varargs: false + native: duk_bi_typedarray_constructor + callable: true + constructable: false + magic: 0 + typedarray: true + es6: true + bidx: true + present_if: DUK_USE_BUFFEROBJECT_SUPPORT + + properties: + - key: "length" + value: 0 + attributes: "c" + typedarray: true + es6: true + - key: "prototype" + value: + type: object + id: bi_typedarray_prototype + attributes: "" + es6: true + - key: "name" + value: "TypedArray" + attributes: "c" + es6: true + + # .from + # .of + # @@species getter + # %TypedArrayPrototype% # Prototype object providing properties shared by all TypedArray # instances (reduces built-in object count). The view specific prototypes @@ -3265,7 +3295,7 @@ objects: - id: bi_typedarray_prototype class: Object internal_prototype: bi_object_prototype - # no external_constructor (specific views provide it) + # no external_prototype (specific views provide it) typedarray: true es6: true bidx: true @@ -3292,7 +3322,7 @@ objects: - id: bi_int8array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3309,7 +3339,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3319,11 +3349,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Int8Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 1 attributes: "" @@ -3349,7 +3378,7 @@ objects: - id: bi_uint8array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3366,7 +3395,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3376,11 +3405,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Uint8Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 1 attributes: "" @@ -3406,7 +3434,7 @@ objects: - id: bi_uint8clampedarray_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3423,7 +3451,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3433,11 +3461,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Uint8ClampedArray" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 1 attributes: "" @@ -3463,7 +3490,7 @@ objects: - id: bi_int16array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3480,7 +3507,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3490,11 +3517,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Int16Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 2 attributes: "" @@ -3520,7 +3546,7 @@ objects: - id: bi_uint16array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3537,7 +3563,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3547,11 +3573,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Uint16Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 2 attributes: "" @@ -3577,7 +3602,7 @@ objects: - id: bi_int32array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3594,7 +3619,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3604,11 +3629,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Int32Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 4 attributes: "" @@ -3634,7 +3658,7 @@ objects: - id: bi_uint32array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3651,7 +3675,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3661,11 +3685,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Uint32Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 4 attributes: "" @@ -3691,7 +3714,7 @@ objects: - id: bi_float32array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3708,7 +3731,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3718,11 +3741,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Float32Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 4 attributes: "" @@ -3748,7 +3770,7 @@ objects: - id: bi_float64array_constructor class: Function - internal_prototype: bi_function_prototype + internal_prototype: bi_typedarray_constructor varargs: false native: duk_bi_typedarray_constructor callable: true @@ -3765,7 +3787,7 @@ objects: properties: - key: "length" value: 3 - attributes: "" + attributes: "c" typedarray: true es6: true - key: "prototype" @@ -3775,11 +3797,10 @@ objects: attributes: "" typedarray: true es6: true - # matches V8, not specified explicitly in Khronos spec - key: "name" value: "Float64Array" - attributes: "" - duktape: true + attributes: "c" + es6: true - key: "BYTES_PER_ELEMENT" value: 8 attributes: "" @@ -3821,7 +3842,7 @@ objects: properties: - key: "length" value: 2 - attributes: "" + attributes: "c" nodejs_buffer: true - key: "prototype" value: @@ -3831,7 +3852,7 @@ objects: nodejs_buffer: true - key: "name" value: "Buffer" - attributes: "" + attributes: "c" nodejs_buffer: true - key: "concat" @@ -4432,7 +4453,7 @@ objects: properties: - key: "length" value: 0 - attributes: "" + attributes: "c" encoding_api: true - key: "prototype" value: @@ -4442,7 +4463,7 @@ objects: encoding_api: true - key: "name" value: "TextEncoder" - attributes: "" + attributes: "c" encoding_api: true - id: bi_textencoder_prototype @@ -4490,7 +4511,7 @@ objects: properties: - key: "length" value: 0 - attributes: "" + attributes: "c" encoding_api: true - key: "prototype" value: @@ -4500,7 +4521,7 @@ objects: encoding_api: true - key: "name" value: "TextDecoder" - attributes: "" + attributes: "c" encoding_api: true - id: bi_textdecoder_prototype From 82b2e34364c75d11880f865cae3de923f2ab58d5 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sat, 17 Dec 2016 22:25:46 +0200 Subject: [PATCH 2/4] Genbuiltins fixes for property attributes --- tools/genbuiltins.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tools/genbuiltins.py b/tools/genbuiltins.py index 7d477233..88d6e845 100644 --- a/tools/genbuiltins.py +++ b/tools/genbuiltins.py @@ -360,7 +360,7 @@ def metadata_prepare_objects_bidx(meta): else: meta['objects'].append(obj) -# Normalize metadata property shorthand. For example, if a proprety value +# Normalize metadata property shorthand. For example, if a property value # is a shorthand function, create a function object and change the property # to point to that function object. def metadata_normalize_shorthand(meta): @@ -614,7 +614,7 @@ def metadata_normalize_ram_function_names(meta): if name_prop is None: num_added += 1 logger.debug('Adding missing "name" property for function %s' % o['id']) - o['properties'].append({ 'key': 'name', 'value': '', 'attributes': '' }) + o['properties'].append({ 'key': 'name', 'value': '', 'attributes': 'c' }) if num_added > 0: logger.debug('Added missing "name" property for %d functions' % num_added) @@ -1340,8 +1340,8 @@ def steal_prop(props, key): # XXX: Reserved word stridxs could be made to match token numbers # directly so that a duk_stridx2token[] would not be needed. -# Default property attributes, see E5 Section 15 beginning. -LENGTH_PROPERTY_ATTRIBUTES = '' +# Default property attributes. +LENGTH_PROPERTY_ATTRIBUTES = 'c' ACCESSOR_PROPERTY_ATTRIBUTES = 'c' DEFAULT_DATA_PROPERTY_ATTRIBUTES = 'wc' @@ -1739,9 +1739,7 @@ def gen_ramobj_initdata_for_props(meta, be, bi, string_to_stridx, natfunc_name_t prop_name = steal_prop(props, 'name') assert(prop_name is not None) assert(isinstance(prop_name['value'], str)) - # Function.prototype.name has special handling in duk_hthread_builtins.c - assert((bi['id'] != 'bi_function_prototype' and prop_name['attributes'] == '') or \ - (bi['id'] == 'bi_function_prototype' and prop_name['attributes'] == 'w')) + assert(prop_name['attributes'] == 'c') # length: encoded specially, so steal and ignore prop_proto = steal_prop(props, 'length') From ba57c486b417ea2e49b0d91d540ad17e9efade23 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sat, 17 Dec 2016 23:41:16 +0200 Subject: [PATCH 3/4] Testcase for %TypedArray% --- ...t-bi-typedarray-constructor-inheritance.js | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tests/ecmascript/test-bi-typedarray-constructor-inheritance.js diff --git a/tests/ecmascript/test-bi-typedarray-constructor-inheritance.js b/tests/ecmascript/test-bi-typedarray-constructor-inheritance.js new file mode 100644 index 00000000..9d526378 --- /dev/null +++ b/tests/ecmascript/test-bi-typedarray-constructor-inheritance.js @@ -0,0 +1,60 @@ +/* + * Typed array constructors inherit from %TypedArray% in ES6. + */ + +/*=== +Int8Array false true +Uint8Array false true +Uint8ClampedArray false true +Int16Array false true +Uint16Array false true +Int32Array false true +Uint32Array false true +Float32Array false true +Float64Array false true +TypeError +TypeError +object true false false false +string TypedArray false false true +number 0 false false true +===*/ + +function test() { + [ Int8Array, Uint8Array, Uint8ClampedArray, + Int16Array, Uint16Array, Int32Array, Uint32Array, + Float32Array, Float64Array ].forEach(function (fn) { + print(fn.name, Object.getPrototypeOf(fn) === Function.prototype, Object.getPrototypeOf(fn) === Object.getPrototypeOf(Int8Array)); + }); + + // The %TypedArray% rejects normal and constructor calls. + var TA = Object.getPrototypeOf(Int8Array); + try { + TA(); + } catch (e) { + print(e.name); + } + try { + new TA(); + } catch (e) { + print(e.name); + } + + // %TypedArray%.prototype is %TypedArrayPrototype%. + var TAP = Object.getPrototypeOf(Object.getPrototypeOf(new Uint8Array(1))); + pd = Object.getOwnPropertyDescriptor(TA, 'prototype'); + print(typeof pd.value, pd.value === TAP, pd.writable, pd.enumerable, pd.configurable); + + // .name + pd = Object.getOwnPropertyDescriptor(TA, 'name'); + print(typeof pd.value, pd.value, pd.writable, pd.enumerable, pd.configurable); + + // .length + pd = Object.getOwnPropertyDescriptor(TA, 'length'); + print(typeof pd.value, pd.value, pd.writable, pd.enumerable, pd.configurable); +} + +try { + test(); +} catch (e) { + print(e.stack || e); +} From 273557edb9a3cf9b8afe09b2621af8da1eb64030 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Sat, 17 Dec 2016 22:44:02 +0200 Subject: [PATCH 4/4] Releases: %TypedArray% inheritance --- RELEASES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.rst b/RELEASES.rst index 2167906e..f3a10803 100644 --- a/RELEASES.rst +++ b/RELEASES.rst @@ -2115,6 +2115,9 @@ Planned * Allow duplicate property names in object literals as required by ES6 (GH-1190) +* Change typed array constructor chain to match ES6, e.g. Uint8Array + constructor inherits from intrinsic %TypedArray% constructor (GH-1191) + * Add a fastint check for duk_put_number_list() values (GH-1086) * Remove an unintended fastint downgrade check for unary minus executor