From 4d0dc1a6030adc82a08a94fe178f92f2ca0e1133 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Wed, 18 May 2022 13:24:29 +0300 Subject: [PATCH] Tool source changes for property code switch --- src-tools/lib/builtins/classnames.js | 57 +++++++------- .../builtins/initdata/object_initializers.js | 18 +++-- .../initdata/property_table_initializers.js | 72 ------------------ .../builtins/initdata/string_initializers.js | 12 ++- src-tools/lib/builtins/ram_initdata.js | 6 +- src-tools/lib/builtins/rom_initdata.js | 8 +- src-tools/lib/configure/source_files.js | 17 ++++- src-tools/lib/duktool/misc_polyfill.js | 75 +++++++++++-------- 8 files changed, 115 insertions(+), 150 deletions(-) diff --git a/src-tools/lib/builtins/classnames.js b/src-tools/lib/builtins/classnames.js index b417dfbf..37605269 100644 --- a/src-tools/lib/builtins/classnames.js +++ b/src-tools/lib/builtins/classnames.js @@ -1,34 +1,31 @@ 'use strict'; -// Class names, numeric indices must match duk_hobject.h class numbers. -const classNames = [ - 'Unused', - 'Object', - 'Array', - 'Function', - 'Arguments', - 'Boolean', - 'Date', - 'Error', - 'JSON', - 'Math', - 'Number', - 'RegExp', - 'String', - 'global', - 'Symbol', - 'ObjEnv', - 'DecEnv', - 'Pointer', - 'Thread' - // Remaining class names are not currently needed. -]; -const classToNum = {}; -classNames.forEach((n, idx) =>{ - classToNum[n] = idx; -}); +// Map built-ins class name to a duk_heaphdr htype. +const classToHtypeNum = { + 'Array': 8, + 'Object': 10, + 'Function': 13, // natfunc, assumes built-ins are native for now. + 'Boolean': 16, + 'Date': 17, + 'Error': 18, + 'JSON': 19, + 'Math': 20, + 'Number': 21, + 'RegExp': 22, + 'String': 23, + 'global': 24, + 'Symbol': 25, + 'ObjEnv': 26, + 'Pointer': 28, + 'Thread': 29, + 'Proxy': 30 +}; -function classToNumber(x) { - return classToNum[x]; +function classToHtypeNumber(x) { + var res = classToHtypeNum[x]; + if (typeof res !== 'number') { + throw new TypeError('no htype number for class ' + x); + } + return res; } -exports.classToNumber = classToNumber; +exports.classToHtypeNumber = classToHtypeNumber; diff --git a/src-tools/lib/builtins/initdata/object_initializers.js b/src-tools/lib/builtins/initdata/object_initializers.js index 8ce2c239..3c9cc940 100644 --- a/src-tools/lib/builtins/initdata/object_initializers.js +++ b/src-tools/lib/builtins/initdata/object_initializers.js @@ -47,30 +47,32 @@ function emitObjectInitializersPtrComp(genc) { //genc.emitLine('#endif'); genc.emitLine('#define DUK__ROMOBJ_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize) ' + - ' { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) } }'); + ' { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, NULL, NULL, 0, 0, (iproto_enc16), (esize), (enext) } }'); + // XXX: Only zero-length Array actually supported now. genc.emitLine('#define DUK__ROMARR_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,length) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (length), 0 /*length_nonwritable*/ } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, NULL, NULL, 0, 0, (iproto_enc16), (esize), (enext) }, 0, (length), (length), 0 /*length_nonwritable*/ } }'); genc.emitLine('#define DUK__ROMFUN_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,nativefunc,nargs,magic) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, NULL, NULL, 0, 0, (iproto_enc16), (esize), (enext) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }'); genc.emitLine('#define DUK__ROMOBJENV_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,target,has_this) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, NULL, NULL, 0, 0, (iproto_enc16), (esize), (enext) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }'); } function emitObjectInitializersNoPtrComp(genc) { genc.emitLine('#define DUK__ROMOBJ_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize) ' + - ' { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) } }'); + ' { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), NULL, NULL, NULL, 0, 0, (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext) } }'); + // XXX: Only zero-length Array actually supported now. genc.emitLine('#define DUK__ROMARR_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,length) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (length), 0 /*length_nonwritable*/ } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), NULL, NULL, NULL, 0, 0, (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext) }, NULL, (length), (length), 0 /*length_nonwritable*/ } }'); genc.emitLine('#define DUK__ROMFUN_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,nativefunc,nargs,magic) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), NULL, NULL, NULL, 0, 0, (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }'); genc.emitLine('#define DUK__ROMOBJENV_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,target,has_this) ' + - ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }'); + ' { { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), NULL, NULL, NULL, 0, 0, (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }'); } function emitObjectInitializers(genc) { diff --git a/src-tools/lib/builtins/initdata/property_table_initializers.js b/src-tools/lib/builtins/initdata/property_table_initializers.js index ccce777d..5543d343 100644 --- a/src-tools/lib/builtins/initdata/property_table_initializers.js +++ b/src-tools/lib/builtins/initdata/property_table_initializers.js @@ -21,60 +21,6 @@ function emitPropertyTableStructs(genc, meta, objs, biStrMap, biObjMap) { // but there'd be very few of them so it's more straightforward to // not reuse the structs. - genc.emitLine('#if defined(DUK_USE_HOBJECT_LAYOUT_1)'); - - objs.forEach((o, idx) => { - var numProps = o.properties.length; - var parts = []; - if (numProps === 0) { - return; - } - - parts.push('typedef struct duk_romprops_' + idx + ' duk_romprops_' + idx + '; '); - parts.push('struct duk_romprops_' + idx + ' { '); - - o.properties.forEach((p, propIdx) => { - parts.push('const duk_hstring *key' + propIdx + '; '); - }); - o.properties.forEach((p, propIdx) => { - parts.push(getValueInitializerType(meta, p, biStrMap, biObjMap) + ' val' + propIdx + '; '); - }); - o.properties.forEach((p, propIdx) => { - parts.push('duk_uint8_t flags' + propIdx + '; '); - }); - parts.push('};'); - genc.emitLine(parts.join('')); - }); - - genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_2)'); - - objs.forEach((o, idx) => { - var numProps = o.properties.length; - var parts = []; - if (numProps === 0) { - return; - } - - parts.push('typedef struct duk_romprops_' + idx + ' duk_romprops_' + idx + '; '); - parts.push('struct duk_romprops_' + idx + ' { '); - - o.properties.forEach((p, propIdx) => { - parts.push(getValueInitializerType(meta, p, biStrMap, biObjMap) + ' val' + propIdx + '; '); - }); - o.properties.forEach((p, propIdx) => { - parts.push('const duk_hstring *key' + propIdx + '; '); - }); - o.properties.forEach((p, propIdx) => { - parts.push('duk_uint8_t flags' + propIdx + '; '); - }); - // Padding follows for flags, but we don't need to emit it - // (at the moment there is never an array or hash part). - parts.push('};'); - genc.emitLine(parts.join('')); - }); - - genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_3)'); - objs.forEach((o, idx) => { var numProps = o.properties.length; var parts = []; @@ -88,21 +34,15 @@ function emitPropertyTableStructs(genc, meta, objs, biStrMap, biObjMap) { o.properties.forEach((p, propIdx) => { parts.push(getValueInitializerType(meta, p, biStrMap, biObjMap) + ' val' + propIdx + '; '); }); - // No array values o.properties.forEach((p, propIdx) => { parts.push('const duk_hstring *key' + propIdx + '; '); }); - // No hash index o.properties.forEach((p, propIdx) => { parts.push('duk_uint8_t flags' + propIdx + '; '); }); parts.push('};'); genc.emitLine(parts.join('')); }); - - genc.emitLine('#else'); - genc.emitLine('#error invalid object layout'); - genc.emitLine('#endif'); } exports.emitPropertyTableStructs = emitPropertyTableStructs; @@ -183,20 +123,8 @@ function emitPropertyTableDefinitions(genc, meta, objs, biStrMap, biObjMap) { } } - genc.emitLine('#if defined(DUK_USE_HOBJECT_LAYOUT_1)'); - objs.forEach((o, idx) => { - emitInitializer(idx, o, 1); - }); - genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_2)'); objs.forEach((o, idx) => { emitInitializer(idx, o, 2); }); - genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_3)'); - objs.forEach((o, idx) => { - emitInitializer(idx, o, 3); - }); - genc.emitLine('#else'); - genc.emitLine('#error invalid object layout'); - genc.emitLine('#endif'); } exports.emitPropertyTableDefinitions = emitPropertyTableDefinitions; diff --git a/src-tools/lib/builtins/initdata/string_initializers.js b/src-tools/lib/builtins/initdata/string_initializers.js index fd289d17..69523bc2 100644 --- a/src-tools/lib/builtins/initdata/string_initializers.js +++ b/src-tools/lib/builtins/initdata/string_initializers.js @@ -70,10 +70,10 @@ function emitStringInitMacro(genc) { genc.emitLine('#endif'); genc.emitLine('#if defined(DUK_USE_HSTRING_CLEN)'); genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) ' + - ' { { (heaphdr_flags) | ((hash16) << 16), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) }, (clen) }'); + ' { { (heaphdr_flags), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) }, (hash16), (clen) }'); genc.emitLine('#else /* DUK_USE_HSTRING_CLEN */') genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) ' + - ' { { (heaphdr_flags) | ((hash16) << 16), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) } }'); + ' { { (heaphdr_flags), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) }, (hash16) }'); genc.emitLine('#endif /* DUK_USE_HSTRING_CLEN */'); genc.emitLine('#else /* DUK_USE_HEAPPTR16 */'); genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) ' + @@ -100,7 +100,7 @@ exports.emitStringDeclarations = emitStringDeclarations; function emitStringInitializer(genc, v, biStrMap, reservedWords, strictReservedWords, romstrNext) { let tmp = 'DUK_INTERNAL const duk_romstr_' + v.length + ' ' + biStrMap[v] + ' = {'; - let flags = [ 'DUK_HTYPE_STRING', + let flags = [ 'DUK_HTYPE_STRING_INTERNAL', 'DUK_HEAPHDR_FLAG_READONLY', 'DUK_HEAPHDR_FLAG_REACHABLE', 'DUK_HSTRING_FLAG_PINNED_LITERAL' ]; @@ -115,6 +115,9 @@ function emitStringInitializer(genc, v, biStrMap, reservedWords, strictReservedW if (isArridx) { flags.push('DUK_HSTRING_FLAG_ARRIDX'); } + if (false) { // XXX + flags.push('DUK_HSTRING_FLAG_CANNUM'); + } if (stringIsAnySymbol(v)) { flags.push('DUK_HSTRING_FLAG_SYMBOL'); } @@ -130,6 +133,9 @@ function emitStringInitializer(genc, v, biStrMap, reservedWords, strictReservedW if (typeof strictReservedWords[v] !== 'undefined') { flags.push('DUK_HSTRING_FLAG_STRICT_RESERVED_WORD'); } + if (v === 'length') { + flags.push('DUK_HSTRING_FLAG_LENGTH'); + } let h_next = 'NULL'; if (typeof romstrNext[v] !== 'undefined') { diff --git a/src-tools/lib/builtins/ram_initdata.js b/src-tools/lib/builtins/ram_initdata.js index 8a0b22d2..430dc88f 100644 --- a/src-tools/lib/builtins/ram_initdata.js +++ b/src-tools/lib/builtins/ram_initdata.js @@ -3,7 +3,7 @@ const { BitEncoder } = require('../util/bitencoder'); const { bitpack5BitBstr } = require('../formats/bitpack_5bit'); const { walkObjectsAndProperties, findObjectById, findPropertyByKey, propDefault } = require('./metadata/util'); -const { classToNumber } = require('./classnames'); +const { classToHtypeNumber } = require('./classnames'); const { assert } = require('../util/assert'); const { hexDecode } = require('../util/hex'); const { shallowCloneArray } = require('../util/clone'); @@ -192,8 +192,8 @@ function generateRamObjectInitDataForObject(meta, be, obj, stringToStridx, natfu be.varuint(natidx); } - var classNum = classToNumber(obj.class); - be.varuint(classNum); + var htype = classToHtypeNumber(obj.class); + be.varuint(htype); var props = shallowCloneArray(obj.properties); // Clone so we can steal. diff --git a/src-tools/lib/builtins/rom_initdata.js b/src-tools/lib/builtins/rom_initdata.js index 36045f6e..df71b581 100644 --- a/src-tools/lib/builtins/rom_initdata.js +++ b/src-tools/lib/builtins/rom_initdata.js @@ -9,7 +9,7 @@ const { propDefault, walkObjectsAndProperties } = require('./metadata/util'); const { createBareObject } = require('../util/bare'); const { assert } = require('../util/assert'); const { jsonStringifyAscii } = require('../util/json'); -const { classToNumber } = require('./classnames'); +const { classToHtypeNumber } = require('./classnames'); const { emitStringHashMacros, emitStringInitMacro, emitStringDeclarations, emitStringInitializer } = require('./initdata/string_initializers'); const { createRomStringTable } = require('./initdata/stringtable'); const { emitPropertyTableStructs, emitPropertyTableForwardDeclarations, emitPropertyTableDefinitions } = require('./initdata/property_table_initializers'); @@ -182,7 +182,6 @@ function emitObjectDefinitions(genc, meta, objs, biObjMap, compressRomPtr) { parts.push('DUK_EXTERNAL const ' + structName + ' duk_obj_' + idx + ' = '); - flags.push('DUK_HTYPE_OBJECT'); flags.push('DUK_HEAPHDR_FLAG_READONLY'); flags.push('DUK_HEAPHDR_FLAG_REACHABLE'); if (isFunc) { @@ -202,7 +201,7 @@ function emitObjectDefinitions(genc, meta, objs, biObjMap, compressRomPtr) { if (propDefault(o, 'special_call', false)) { flags.push('DUK_HOBJECT_FLAG_SPECIAL_CALL'); } - flags.push('DUK_HOBJECT_CLASS_AS_FLAGS(' + classToNumber(o.class) + ')'); + flags.push('DUK_HEAPHDR_HTYPE_AS_FLAGS(' + classToHtypeNumber(o.class) + ')'); var refcount = 1; // refcount is faked to be always 1 @@ -256,6 +255,9 @@ function emitObjectDefinitions(genc, meta, objs, biObjMap, compressRomPtr) { parts.push('DUK__ROMARR_INIT(' + sharedFields.concat([ arrlen ]).join(',') + ');'); + if (arrlen > 0) { + throw new TypeError('non-empty ROM Array initializers not supported at present'); + } } else if (o.class === 'ObjEnv') { var objenvTarget = '&' + biObjMap[o.objenv_target]; var objenvHasThis = o.objenv_has_this; diff --git a/src-tools/lib/configure/source_files.js b/src-tools/lib/configure/source_files.js index bcf9a7e2..91257b0f 100644 --- a/src-tools/lib/configure/source_files.js +++ b/src-tools/lib/configure/source_files.js @@ -19,6 +19,7 @@ const sourceFiles = [ 'duk_api_memory.c', 'duk_api_object.c', 'duk_api_random.c', + 'duk_api_readable.c', 'duk_api_string.c', 'duk_api_time.c', 'duk_api_debug.c', @@ -87,13 +88,16 @@ const sourceFiles = [ 'duk_heap_stringtable.c', 'duk_hnatfunc.h', 'duk_hobject_alloc.c', + 'duk_hobject_array.c', 'duk_hobject_assert.c', 'duk_hobject_class.c', - 'duk_hobject_enum.c', 'duk_hobject.h', + 'duk_hobject_lookup.c', 'duk_hobject_misc.c', 'duk_hobject_pc2line.c', 'duk_hobject_props.c', + 'duk_hobject_proxy.c', + 'duk_hobject_resize.c', 'duk_hproxy.h', 'duk_hstring.h', 'duk_hstring_assert.c', @@ -116,11 +120,22 @@ const sourceFiles = [ 'duk_js.h', 'duk_json.h', 'duk_js_ops.c', + 'duk_js_prop.c', 'duk_js_var.c', 'duk_lexer.c', 'duk_lexer.h', 'duk_numconv.c', 'duk_numconv.h', + 'duk_prop_defown.c', + 'duk_prop_delete.c', + 'duk_prop_enum.c', + 'duk_prop_get.c', + 'duk_prop_getown.c', + 'duk_prop.h', + 'duk_prop_has.c', + 'duk_prop_ownpropkeys.c', + 'duk_prop_set.c', + 'duk_prop_util.c', 'duk_refcount.h', 'duk_regexp_compiler.c', 'duk_regexp_executor.c', diff --git a/src-tools/lib/duktool/misc_polyfill.js b/src-tools/lib/duktool/misc_polyfill.js index 5d67a02b..8638c90e 100644 --- a/src-tools/lib/duktool/misc_polyfill.js +++ b/src-tools/lib/duktool/misc_polyfill.js @@ -5,44 +5,59 @@ function miscPolyfills() { if (typeof Array.prototype[Symbol.iterator] === 'undefined') { - Array.prototype[Symbol.iterator] = function arrayIterator() { - var arg = this; - var index = 0; - return { - next: function arrayNext() { - if (index >= arg.length) { return { done: true }; } - return { value: arg[index++], done: false }; + Object.defineProperty(Array.prototype, Symbol.iterator, { + value: function arrayIterator() { + var arg = this; + var index = 0; + return { + next: function arrayNext() { + if (index >= arg.length) { return { done: true }; } + return { value: arg[index++], done: false }; + } } - } - }; + }, + writable: true, + enumerable: false, + configurable: true + }); } if (typeof Array.prototype.flatMap === 'undefined') { - Array.prototype.flatMap = function flatMap(fn) { - var arg = this; - var tmp = Array.prototype.map.call(arg, fn); - var res = []; - tmp.forEach(function (v) { - if (Array.isArray(v)) { - res = res.concat(v); - } else { - res.push(v); - } - }); - return res; - }; + Object.defineProperty(Array.prototype, 'flatMap', { + value: function flatMap(fn) { + var arg = this; + var tmp = Array.prototype.map.call(arg, fn); + var res = []; + tmp.forEach(function (v) { + if (Array.isArray(v)) { + res = res.concat(v); + } else { + res.push(v); + } + }); + return res; + }, + writable: true, + enumerable: false, + configurable: true + }); } if (typeof Array.prototype.includes === 'undefined') { - Array.prototype.includes = function includes(v) { - var arg = this; - for (var i = 0; i < arg.length; i++) { - if (arg[i] === v) { - return true; + Object.defineProperty(Array.prototype, 'includes', { + value: function includes(v) { + var arg = this; + for (var i = 0; i < arg.length; i++) { + if (arg[i] === v) { + return true; + } } - } - return false; - }; + return false; + }, + writable: true, + enumerable: false, + configurable: true + }); } if (typeof Object.getPrototypeOf(new Uint8Array(0)).map === 'undefined') {