Browse Source

first draft of 'initjs' code which would allow compatibility cruft to be implemented in JS and executed in init

pull/1/head
Sami Vaarala 11 years ago
parent
commit
48864f6d8f
  1. 11
      make_dist.sh
  2. 6
      src/duk_features.h
  3. 16
      src/duk_hthread_builtins.c
  4. 19
      src/duk_initjs_legacy.js
  5. 32
      src/genbuiltins.py

11
make_dist.sh

@ -211,6 +211,16 @@ for i in \
cp licenses/$i $DIST/licenses/
done
# Initjs code: built-in Ecmascript code snippets which are evaluated when
# a new global context is created. UglifyJS is used to compact the source,
# not to obfuscate it (although that happens as an unwanted side effect).
cat \
src/duk_initjs_legacy.js \
| UglifyJS/bin/uglifyjs --ascii --no-dead-code --no-copyright \
> $DISTSRCSEP/duk_initjs_min.js.tmp
cp $DISTSRCSEP/duk_initjs_min.js.tmp $DISTSRCSEP/duk_initjs_min.js
# Autogenerated strings and built-in files
#
# There are currently no profile specific variants of strings/builtins, but
@ -225,6 +235,7 @@ python src/genbuildparams.py \
python src/genbuiltins.py \
--buildinfo=$DISTSRCSEP/buildparams.json.tmp \
--initjs-data=$DISTSRCSEP/duk_initjs_min.js.tmp \
--out-header=$DISTSRCSEP/duk_builtins.h \
--out-source=$DISTSRCSEP/duk_builtins.c \

6
src/duk_features.h

@ -1304,6 +1304,12 @@ extern double duk_computed_nan;
#undef DUK_USE_JSONC
#endif
/*
* InitJS code
*/
#define DUK_USE_INITJS
/*
* Miscellaneous
*/

16
src/duk_hthread_builtins.c

@ -482,6 +482,22 @@ void duk_hthread_create_builtin_objects(duk_hthread *thr) {
DUK_USE_ARCH_STRING);
duk_def_prop_stridx(ctx, DUK_BIDX_DUK, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);
/*
* InitJS code - Ecmascript code evaluated from a built-in source
* which provides e.g. backward compatibility. User can also provide
* JS code to be evaluated at startup.
*/
#ifdef DUK_USE_INITJS
/* FIXME: compression */
duk_eval_string(ctx, duk_initjs_data); /* initjs data is NUL terminated */
#endif /* DUK_USE_INITJS */
#ifdef DUK_USE_USER_INITJS
/* FIXME: compression, at least as an option? */
duk_eval_string(ctx, DUK_USE_USER_INITJS);
#endif /* DUK_USE_USER_INITJS */
/*
* Since built-ins are not often extended, compact them.
*/

19
src/duk_initjs_legacy.js

@ -0,0 +1,19 @@
/*
* Init code for legacy compatibility.
*
* Compatibility properties / wrapper functions here allow Duktape to remain
* compatible for user code when core features are changed, without burdening
* the main C code with compatibility stuff.
*/
(function(D) {
function def(name, value) {
Object.defineProperty(D, name, {
value: value,
writable: true,
enumerable: false,
configurable: true
});
}
def('build', ''); // removed in Duktape 0.9.0
})(Duktape);

32
src/genbuiltins.py

@ -1294,6 +1294,7 @@ class GenBuiltins:
builtins = None
gs = None
init_data = None
initjs_data = None
native_func_hash = None
native_func_list = None
builtin_indexes = None
@ -1302,7 +1303,7 @@ class GenBuiltins:
count_normal_props = None
count_function_props = None
def __init__(self, build_info = None, byte_order=None, ext_section_b=None, ext_browser_like=None):
def __init__(self, build_info=None, initjs_data=None, byte_order=None, ext_section_b=None, ext_browser_like=None):
self.build_info = build_info
self.byte_order = byte_order
self.ext_section_b = ext_section_b
@ -1311,6 +1312,10 @@ class GenBuiltins:
self.builtins = copy.deepcopy(builtins_orig)
self.gs = None
self.init_data = None
self.initjs_data = initjs_data
if len(self.initjs_data) > 1 and self.initjs_data[-1] != '\0':
# force NUL termination, init code now expects that
self.initjs_data += '\0'
self.native_func_hash = {}
self.native_func_list = []
self.builtin_indexes = {}
@ -1676,8 +1681,8 @@ class GenBuiltins:
self.init_data = be.getByteString()
print '%d bytes of built-in init data, %d built-in objects, %d normal props, %d func props' % \
(len(self.init_data), self.count_builtins, self.count_normal_props, self.count_function_props)
print '%d bytes of built-in init data, %d built-in objects, %d normal props, %d func props, %d initjs data bytes' % \
(len(self.init_data), self.count_builtins, self.count_normal_props, self.count_function_props, len(self.initjs_data))
def emitSource(self, genc):
self.gs.emitStringsData(genc)
@ -1686,16 +1691,24 @@ class GenBuiltins:
self.writeNativeFuncArray(genc)
genc.emitLine('')
genc.emitArray(self.init_data, 'duk_builtins_data', typename='duk_uint8_t', intvalues=True, const=True)
genc.emitLine('#ifdef DUK_USE_INITJS')
genc.emitArray(self.initjs_data, 'duk_initjs_data', typename='duk_uint8_t', intvalues=True, const=True)
genc.emitLine('#endif /* DUK_USE_INITJS */')
def emitHeader(self, genc):
self.gs.emitStringsHeader(genc)
genc.emitLine('')
genc.emitLine('extern const duk_c_function duk_bi_native_functions[];')
genc.emitLine('')
genc.emitLine('extern const duk_uint8_t duk_builtins_data[];')
genc.emitLine('#ifdef DUK_USE_INITJS')
genc.emitLine('extern const duk_uint8_t duk_initjs_data[];')
genc.emitLine('#endif /* DUK_USE_INITJS */')
genc.emitLine('')
genc.emitDefine('DUK_BUILTINS_DATA_LENGTH', len(self.init_data))
genc.emitLine('#ifdef DUK_USE_INITJS')
genc.emitDefine('DUK_INITJS_DATA_LENGTH', len(self.initjs_data))
genc.emitLine('#endif /* DUK_USE_INITJS */')
genc.emitLine('')
for idx,t in enumerate(self.builtins):
def_name1, def_name2 = self.generateDefineNames(t['id'])
@ -1711,6 +1724,7 @@ class GenBuiltins:
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('--buildinfo', dest='buildinfo')
parser.add_option('--initjs-data', dest='initjs_data')
parser.add_option('--out-header', dest='out_header')
parser.add_option('--out-source', dest='out_source')
(opts, args) = parser.parse_args()
@ -1719,12 +1733,16 @@ if __name__ == '__main__':
build_info = dukutil.json_decode(f.read().strip())
f.close()
f = open(opts.initjs_data, 'rb')
initjs_data = f.read();
f.close()
# genbuiltins for different profiles
gb_little = GenBuiltins(build_info = build_info, byte_order='little', ext_section_b=True, ext_browser_like=True)
gb_little = GenBuiltins(build_info = build_info, initjs_data = initjs_data, byte_order='little', ext_section_b=True, ext_browser_like=True)
gb_little.processBuiltins()
gb_big = GenBuiltins(build_info = build_info, byte_order='big', ext_section_b=True, ext_browser_like=True)
gb_big = GenBuiltins(build_info = build_info, initjs_data = initjs_data, byte_order='big', ext_section_b=True, ext_browser_like=True)
gb_big.processBuiltins()
gb_middle = GenBuiltins(build_info = build_info, byte_order='middle', ext_section_b=True, ext_browser_like=True)
gb_middle = GenBuiltins(build_info = build_info, initjs_data = initjs_data, byte_order='middle', ext_section_b=True, ext_browser_like=True)
gb_middle.processBuiltins()
# write C source file containing both strings and builtins

Loading…
Cancel
Save