mirror of https://github.com/svaarala/duktape.git
Sami Vaarala
5 years ago
1 changed files with 242 additions and 0 deletions
@ -0,0 +1,242 @@ |
|||||
|
/* |
||||
|
* Generate initialization data for built-in strings and objects. |
||||
|
* |
||||
|
* Supports two different initialization approaches: |
||||
|
* |
||||
|
* 1. Bit-packed format for unpacking strings and objects during |
||||
|
* heap or thread init into RAM-based structures. This is the |
||||
|
* default behavior. |
||||
|
* |
||||
|
* 2. Embedding strings and/or objects into a read-only data section |
||||
|
* at compile time. This is useful for low memory targets to reduce |
||||
|
* memory usage. Objects in data section will be immutable. |
||||
|
* |
||||
|
* Both of these have practical complications like endianness differences, |
||||
|
* pointer compression variants, object property table layout variants, |
||||
|
* and so on. Multiple #if defined()'d initializer sections are emitted |
||||
|
* to cover all supported alternatives. |
||||
|
* |
||||
|
* Based on genbuiltins.py. |
||||
|
*/ |
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const { loadMetadata, augmentMetadata } = require('./metadata/load'); |
||||
|
const { prettyPrintMetadata } = require('./metadata/pretty'); |
||||
|
const { GenerateC } = require('../util/generate_c'); |
||||
|
const { |
||||
|
generateRamStringInitDataBitpacked, |
||||
|
getRamobjNativeFuncMaps, |
||||
|
generateRamObjectInitDataBitpacked, |
||||
|
emitRamStringHeader, |
||||
|
emitRamStringInitData, |
||||
|
emitRamObjectNativeFuncArray, |
||||
|
emitRamObjectInitData, |
||||
|
emitRamObjectNativeFuncDeclarations, |
||||
|
emitRamObjectNativeFuncArrayDeclaration, |
||||
|
emitRamObjectHeader, |
||||
|
emitRamObjectInitDataDeclaration |
||||
|
} = require('./ram_initdata'); |
||||
|
const { |
||||
|
emitStringsSource, |
||||
|
emitObjectsSource, |
||||
|
emitStridxDefinesHeader, |
||||
|
emitStringsHeader, |
||||
|
emitNativeFunctionDeclarationsHeader, |
||||
|
emitObjectsHeader |
||||
|
} = require('./rom_initdata'); |
||||
|
const { |
||||
|
emit32BitPtrCheck, |
||||
|
emitInitializerTypesAndMacrosSource, |
||||
|
emitRefcountInitMacro |
||||
|
} = require('./initdata/object_initializers'); |
||||
|
const { ROMPTR_FIRST } = require('./rom_initdata'); |
||||
|
const { assert } = require('../util/assert'); |
||||
|
const { jsonDeepClone } = require('../util/clone'); |
||||
|
|
||||
|
function emitBuiltinsSource(args) { |
||||
|
var gcSrc = args.gcSrc; |
||||
|
var romMeta = args.romMeta; |
||||
|
var ramStrInitData = args.ramStrInitData; |
||||
|
var ramNativeFuncs = args.ramNativeFuncs; |
||||
|
var ramObjDataLe = args.ramObjDataLe; |
||||
|
var ramObjDataBe = args.ramObjDataBe; |
||||
|
var ramObjDataMe = args.ramObjDataMe; |
||||
|
var biStrMap; |
||||
|
|
||||
|
gcSrc.emitLine('#include "duk_internal.h"'); |
||||
|
gcSrc.emitLine(''); |
||||
|
emit32BitPtrCheck(gcSrc); |
||||
|
emitRefcountInitMacro(gcSrc); |
||||
|
|
||||
|
gcSrc.emitLine('#if defined(DUK_USE_ROM_STRINGS)'); |
||||
|
({ biStrMap } = emitStringsSource(gcSrc, romMeta)); |
||||
|
emitInitializerTypesAndMacrosSource(gcSrc); |
||||
|
emitObjectsSource(gcSrc, romMeta, biStrMap); |
||||
|
gcSrc.emitLine('#else /* DUK_USE_ROM_STRINGS */'); |
||||
|
emitRamStringInitData(gcSrc, ramStrInitData); |
||||
|
gcSrc.emitLine('#endif /* DUK_USE_ROM_STRINGS */'); |
||||
|
gcSrc.emitLine(''); |
||||
|
|
||||
|
gcSrc.emitLine('#if defined(DUK_USE_ROM_OBJECTS)'); |
||||
|
gcSrc.emitLine('#if !defined(DUK_USE_ROM_STRINGS)'); |
||||
|
gcSrc.emitLine('#error DUK_USE_ROM_OBJECTS requires DUK_USE_ROM_STRINGS'); |
||||
|
gcSrc.emitLine('#endif'); |
||||
|
gcSrc.emitLine('#if defined(DUK_USE_HSTRING_ARRIDX)'); |
||||
|
gcSrc.emitLine('#error DUK_USE_HSTRING_ARRIDX is currently incompatible with ROM built-ins'); |
||||
|
gcSrc.emitLine('#endif'); |
||||
|
gcSrc.emitLine('#else /* DUK_USE_ROM_OBJECTS */'); |
||||
|
emitRamObjectNativeFuncArray(gcSrc, ramNativeFuncs); |
||||
|
gcSrc.emitLine('#if defined(DUK_USE_DOUBLE_LE)'); |
||||
|
emitRamObjectInitData(gcSrc, ramObjDataLe); |
||||
|
gcSrc.emitLine('#elif defined(DUK_USE_DOUBLE_BE)') |
||||
|
emitRamObjectInitData(gcSrc, ramObjDataBe); |
||||
|
gcSrc.emitLine('#elif defined(DUK_USE_DOUBLE_ME)') |
||||
|
emitRamObjectInitData(gcSrc, ramObjDataMe); |
||||
|
gcSrc.emitLine('#else') |
||||
|
gcSrc.emitLine('#error invalid endianness defines') |
||||
|
gcSrc.emitLine('#endif') |
||||
|
gcSrc.emitLine('#endif /* DUK_USE_ROM_OBJECTS */'); |
||||
|
} |
||||
|
|
||||
|
function emitBuiltinsHeader(args) { |
||||
|
var gcHdr = args.gcHdr; |
||||
|
var romMeta = args.romMeta; |
||||
|
var ramMeta = args.ramMeta; |
||||
|
var ramStrInitData = args.ramStrInitData; |
||||
|
var ramStrMaxLen = args.ramStrMaxLen; |
||||
|
var ramNativeFuncs = args.ramNativeFuncs; |
||||
|
var ramObjDataLe = args.ramObjDataLe; |
||||
|
var ramObjDataBe = args.ramObjDataBe; |
||||
|
var ramObjDataMe = args.ramObjDataMe; |
||||
|
|
||||
|
gcHdr.emitLine('#if !defined(DUK_BUILTINS_H_INCLUDED)'); |
||||
|
gcHdr.emitLine('#define DUK_BUILTINS_H_INCLUDED'); |
||||
|
gcHdr.emitLine(''); |
||||
|
|
||||
|
gcHdr.emitLine('#if defined(DUK_USE_ROM_STRINGS)'); |
||||
|
emitStridxDefinesHeader(gcHdr, romMeta); |
||||
|
emitStringsHeader(gcHdr, romMeta); |
||||
|
gcHdr.emitLine('#else /* DUK_USE_ROM_STRINGS */'); |
||||
|
emitStridxDefinesHeader(gcHdr, ramMeta); |
||||
|
emitRamStringHeader(gcHdr, ramStrInitData, ramStrMaxLen); |
||||
|
gcHdr.emitLine('#endif /* DUK_USE_ROM_STRINGS */'); |
||||
|
gcHdr.emitLine(''); |
||||
|
|
||||
|
gcHdr.emitLine('#if defined(DUK_USE_ROM_OBJECTS)'); |
||||
|
// Currently DUK_USE_ROM_PTRCOMP_FIRST must match our fixed
|
||||
|
// define, and the two must be updated in sync. Catch any
|
||||
|
// mismatch to avoid difficult to diagnose errors.
|
||||
|
gcHdr.emitLine('#if !defined(DUK_USE_ROM_PTRCOMP_FIRST)'); |
||||
|
gcHdr.emitLine('#error missing DUK_USE_ROM_PTRCOMP_FIRST define'); |
||||
|
gcHdr.emitLine('#endif'); |
||||
|
gcHdr.emitLine('#if (DUK_USE_ROM_PTRCOMP_FIRST != ' + ROMPTR_FIRST + 'L)'); |
||||
|
gcHdr.emitLine('#error DUK_USE_ROM_PTRCOMP_FIRST must match ROMPTR_FIRST in duktool.js (' + ROMPTR_FIRST + '), update manually and re-dist'); |
||||
|
gcHdr.emitLine('#endif'); |
||||
|
emitNativeFunctionDeclarationsHeader(gcHdr, romMeta); |
||||
|
emitObjectsHeader(gcHdr, romMeta); |
||||
|
gcHdr.emitLine('#else /* DUK_USE_ROM_OBJECTS */'); |
||||
|
emitRamObjectNativeFuncDeclarations(gcHdr, ramNativeFuncs); |
||||
|
emitRamObjectNativeFuncArrayDeclaration(gcHdr, ramNativeFuncs); |
||||
|
emitRamObjectHeader(gcHdr, ramMeta); |
||||
|
gcHdr.emitLine('#if defined(DUK_USE_DOUBLE_LE)'); |
||||
|
emitRamObjectInitDataDeclaration(gcHdr, ramObjDataLe); |
||||
|
gcHdr.emitLine('#elif defined(DUK_USE_DOUBLE_BE)'); |
||||
|
emitRamObjectInitDataDeclaration(gcHdr, ramObjDataBe); |
||||
|
gcHdr.emitLine('#elif defined(DUK_USE_DOUBLE_ME)'); |
||||
|
emitRamObjectInitDataDeclaration(gcHdr, ramObjDataMe); |
||||
|
gcHdr.emitLine('#else') |
||||
|
gcHdr.emitLine('#error invalid endianness defines') |
||||
|
gcHdr.emitLine('#endif') |
||||
|
gcHdr.emitLine('#endif /* DUK_USE_ROM_OBJECTS */'); |
||||
|
gcHdr.emitLine(''); |
||||
|
gcHdr.emitLine('#endif /* DUK_BUILTINS_H_INCLUDED */'); |
||||
|
} |
||||
|
|
||||
|
function generateBuiltins(args) { |
||||
|
var usedStridxEtcMeta = args.usedStridxEtcMeta; |
||||
|
var dukVersion = args.dukVersion; |
||||
|
var activeOpts = args.activeOpts; |
||||
|
var romAutoLightfunc = args.romAutoLightfunc; |
||||
|
var userBuiltinFiles = args.userBuiltinFiles; |
||||
|
var objectsMetadataFile = args.objectsMetadataFile; |
||||
|
var stringsMetadataFile = args.stringsMetadataFile; |
||||
|
|
||||
|
// Read in metadata files, normalizing and merging as necessary.
|
||||
|
|
||||
|
var ramMeta = loadMetadata({ |
||||
|
stringsMetadataFilename: stringsMetadataFile, |
||||
|
objectsMetadataFilename: objectsMetadataFile, |
||||
|
userBuiltinFiles, |
||||
|
usedStridxEtcMeta, |
||||
|
activeOpts, |
||||
|
romBuild: false, |
||||
|
dukVersion |
||||
|
}); |
||||
|
var ramMetaUnaugmented = jsonDeepClone(ramMeta); |
||||
|
var prettyRamMeta = prettyPrintMetadata(ramMetaUnaugmented); |
||||
|
augmentMetadata(ramMeta); |
||||
|
|
||||
|
var romMeta = loadMetadata({ |
||||
|
stringsMetadataFilename: stringsMetadataFile, |
||||
|
objectsMetadataFilename: objectsMetadataFile, |
||||
|
userBuiltinFiles, |
||||
|
usedStridxEtcMeta, |
||||
|
activeOpts, |
||||
|
romBuild: true, |
||||
|
romAutoLightfunc, |
||||
|
dukVersion |
||||
|
}); |
||||
|
var romMetaUnaugmented = jsonDeepClone(romMeta); |
||||
|
var prettyRomMeta = prettyPrintMetadata(romMetaUnaugmented); |
||||
|
augmentMetadata(romMeta); |
||||
|
|
||||
|
let ramStrData, ramStrMaxLen; |
||||
|
let nativeFuncs, natfuncNameToNatidx; |
||||
|
let ramObjDataLe, ramObjDataBe, ramObjDataMe; |
||||
|
({ data: ramStrData, maxLen: ramStrMaxLen } = generateRamStringInitDataBitpacked(ramMeta)); |
||||
|
({ nativeFuncs, natfuncNameToNatidx } = getRamobjNativeFuncMaps(ramMeta)); |
||||
|
({ data: ramObjDataLe } = generateRamObjectInitDataBitpacked(ramMeta, nativeFuncs, natfuncNameToNatidx, 'little')); |
||||
|
({ data: ramObjDataBe } = generateRamObjectInitDataBitpacked(ramMeta, nativeFuncs, natfuncNameToNatidx, 'big')); |
||||
|
({ data: ramObjDataMe } = generateRamObjectInitDataBitpacked(ramMeta, nativeFuncs, natfuncNameToNatidx, 'mixed')); |
||||
|
assert(ramObjDataLe.length === ramObjDataBe.length); |
||||
|
assert(ramObjDataLe.length === ramObjDataMe.length); |
||||
|
|
||||
|
// Create source and header files.
|
||||
|
|
||||
|
var gcSrc = new GenerateC(); |
||||
|
emitBuiltinsSource({ |
||||
|
gcSrc, |
||||
|
romMeta, |
||||
|
ramStrInitData: ramStrData, |
||||
|
ramNativeFuncs: nativeFuncs, |
||||
|
ramObjDataLe, |
||||
|
ramObjDataBe, |
||||
|
ramObjDataMe |
||||
|
}); // duk_builtins.c
|
||||
|
|
||||
|
var gcHdr = new GenerateC(); |
||||
|
emitBuiltinsHeader({ |
||||
|
gcHdr, |
||||
|
romMeta, |
||||
|
ramMeta, |
||||
|
ramStrInitData: ramStrData, |
||||
|
ramStrMaxLen: ramStrMaxLen, |
||||
|
ramNativeFuncs: nativeFuncs, |
||||
|
ramObjDataLe, |
||||
|
ramObjDataBe, |
||||
|
ramObjDataMe |
||||
|
}); // duk_builtins.h
|
||||
|
|
||||
|
return { |
||||
|
preparedRomMetadata: romMeta, |
||||
|
unaugmentedRomMetadata: romMetaUnaugmented, |
||||
|
prettyRomMetadata: prettyRomMeta, |
||||
|
preparedRamMetadata: ramMeta, |
||||
|
unaugmentedRamMetadata: ramMetaUnaugmented, |
||||
|
prettyRamMetadata: prettyRamMeta, |
||||
|
sourceString: gcSrc.getString(), |
||||
|
headerString: gcHdr.getString() |
||||
|
}; |
||||
|
} |
||||
|
exports.generateBuiltins = generateBuiltins; |
Loading…
Reference in new issue