Skip to content

Commit

Permalink
Split off literals table into its own module
Browse files Browse the repository at this point in the history
  • Loading branch information
cscott committed Feb 14, 2020
1 parent 49c62f8 commit b847a2b
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 36 deletions.
37 changes: 6 additions & 31 deletions bcompile.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
//
// C. Scott Ananian
// 2011-05-10 / 2020-02-12
define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_source, bytecode_table) {
define(["text!bcompile.js", "bytecode-table", "literal-map"], function make_bcompile(bcompile_source, bytecode_table, LiteralMap) {
// helper function for debugging
var assert = function(b, obj) {
if (!b) {
Expand All @@ -56,40 +56,15 @@ define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_s
// We also need to count lexical scope nesting depth during compilation
var state = {
functions: [],
literals: [],
literals: null,
// internal
scope: 0,
desugar_frame_get: !dont_desugar_frame_get
};
// literal symbol table. Does string intern'ing too.
var ObjectIs = Object.is || function(a, b) {
if (typeof(a)==='number' && typeof(b)==='number') {
if (a!==a) { return (b!==b); } // NaN
if (a===0) { return (b===0) && (1/a === 1/b); } // +/- 0
}
return (a===b);
};
var literalMap = Object.create(null);
state.literal = function(val) {
var i, pair, key, entries;
key = typeof(val) + ':' + val; // very basic hash key
entries = literalMap[key];
if (entries!==undefined) {
i = 0;
while (i < entries.length) {
pair = entries[i];
if (ObjectIs(pair[0], val)) { return pair[1]; }
i += 1;
}
} else {
entries = [];
literalMap[key] = entries;
}
i = this.literals.length;
this.literals[i] = val;
entries.push([val, i]);
return i;
};
var lm = LiteralMap.New();
state.literals = lm.list;
state.literal = function(val) { return lm.get(val); };
// create a function representation
state.new_function = function(nargs) {
var newf = {
Expand Down Expand Up @@ -755,7 +730,7 @@ define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_s
};
bcompile.__module_name__ = "bcompile";
bcompile.__module_init__ = make_bcompile;
bcompile.__module_deps__ = ["bytecode-table"];
bcompile.__module_deps__ = ["bytecode-table", "literal-map"];
bcompile.__module_source__ = bcompile_source;
return bcompile;
});
9 changes: 8 additions & 1 deletion binterp.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,20 @@ define(["text!binterp.js", "bytecode-table"/*, "!html-escape"*/], function make_
this.stack.push(na);
};
dispatch.new_function = function(idx) {
// See 14.1.20 InstantiateFunctionObject
// OrdinaryFunctionCreate
var f = Object.create(MyFunction);
// hidden fields of function object
f.parent_frame = this.frame;
f.module = this.module;
f.func_id = idx;
f[SLOT_PREFIX+"name"] = this.module.functions[idx].name;
f[SLOT_PREFIX+"length"] = this.module.functions[idx].nargs;
// MakeConstructor(f)
var prototype = Object.create(MyObject);
prototype[SLOT_PREFIX+"constructor"] = f;
f[SLOT_PREFIX+"prototype"] = prototype;
// SetFunctionName
f[SLOT_PREFIX+"name"] = this.module.functions[idx].name;
this.stack.push(f);
};
var get_slot = function(obj, name) {
Expand Down
1 change: 1 addition & 0 deletions ctiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_demo('JS parser', tests.lookup('parse'));
add_demo('JS compiler', tests.lookup('jcompile'));
add_demo('Tile renderer', tests.lookup('crender'));
add_demo('Bytecode table', tests.lookup('bytecode-table'));
add_demo('Literals map', tests.lookup('literal-map'));
add_demo('Bytecode compiler', tests.lookup('bcompile'));
add_demo('Bytecode interpreter', tests.lookup('binterp'));
add_demo('Standard library', tests.lookup('stdlib'));
Expand Down
52 changes: 52 additions & 0 deletions literal-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// # literal-map.js
//
// A simple table of (literal) values
//
// Uses a simple hashtable lookup, but uses SameValue for identity
// (ie, NaN, +0, and -0 are all treated as distinct)
// Maps any given value into an integer index.
define(["text!literal-map.js"], function make_literal_map(literal_map_source) {

var ObjectIs = Object.is || function(a, b) {
if (typeof(a)==='number' && typeof(b)==='number') {
if (a!==a) { return (b!==b); } // NaN
if (a===0) { return (b===0) && (1/a === 1/b); } // +/- 0
}
return (a===b);
};

var LiteralMap = function(items) {
this.map = Object.create(null);
this.list = [];
if (items!==undefined) {
items.forEach(function(v) { this.get(v); }, this);
}
};
// This next line isn't required, but it makes bootstrapping easier.
LiteralMap.prototype = { constructor: LiteralMap };
LiteralMap.prototype.get = function(val) {
var i, pair, key, entries;
key = typeof(val) + ':' + val; // very basic hash key
entries = this.map[key];
if (entries!==undefined) {
i = 0;
while (i < entries.length) {
pair = entries[i];
if (ObjectIs(pair[0], val)) { return pair[1]; }
i += 1;
}
} else {
entries = [];
this.map[key] = entries;
}
i = this.list.length;
this.list[i] = val;
entries.push([val, i]);
return i;
};
LiteralMap.__module_name__ = "literal-map";
LiteralMap.__module_init__ = make_literal_map;
LiteralMap.__module_deps__ = [];
LiteralMap.__module_source__ = literal_map_source;
return LiteralMap;
});
2 changes: 1 addition & 1 deletion nodemain.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module.exports = Object.create(null);
// Things to export.
['parse', 'jcompile',
// Bytecode compiler-interpreter.
'bytecode-table', 'bcompile', 'binterp', 'stdlib',
'bytecode-table', 'literal-map', 'bcompile', 'binterp', 'stdlib',
// `asm.js` project.
'asm-llvm',
// FRS-style event system.
Expand Down
1 change: 1 addition & 0 deletions tdop.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ function do_it() {
tests.lookup("tokenize")+"\n"+
tests.lookup("parse")+"\n"+
tests.lookup("bytecode-table")+"\n"+
tests.lookup("literal-map")+"\n"+
tests.lookup("bcompile")+"\n"+
tests.lookup("binterp")+"\n"+
top_level_source+"\n"+
Expand Down
1 change: 1 addition & 0 deletions test/binterp-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var metainterpreter = (function() {
tests.lookup("tokenize")+"\n"+
tests.lookup("parse")+"\n"+
tests.lookup("bytecode-table")+"\n"+
tests.lookup("literal-map")+"\n"+
tests.lookup("bcompile")+"\n"+
tests.lookup("binterp")+"\n"+
top_level_source+"\n"+
Expand Down
8 changes: 5 additions & 3 deletions tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
define(["text!tests.js", "str-escape",
/* These modules are just imported to make test cases out of them. */
"tokenize", "parse", "jcompile", "crender", "bytecode-table",
"bcompile", "binterp", "stdlib", "events", "asm-llvm"],
"literal-map", "bcompile", "binterp", "stdlib", "events", "asm-llvm"],
function make_tests(tests_source, str_escape,
tokenize, parse, jcompile, crender, bytecode_table,
bcompile, binterp, stdlib, events, asm_llvm) {
LiteralMap, bcompile, binterp, stdlib, events,
asm_llvm) {
var deps = ["tests_source", "str-escape",
"tokenize", "parse", "jcompile", "crender", "bytecode-table",
"bcompile", "binterp", "stdlib", "events", "asm-llvm"];
"literal-map", "bcompile", "binterp", "stdlib", "events",
"asm-llvm"];
var test=[], i=2/* skip tests_source and str_escape */;
// The first tests are our own source code, from the module arguments.
while (i < arguments.length) {
Expand Down
1 change: 1 addition & 0 deletions write-lua-bytecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
tests.lookup("tokenize")+"\n"+
tests.lookup("parse")+"\n"+
tests.lookup("bytecode-table")+"\n"+
tests.lookup("literal-map")+"\n"+
tests.lookup("bcompile")+"\n"+
top_level_source+"\n"+
cfs_source + '\n' +
Expand Down
1 change: 1 addition & 0 deletions write-php-bytecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
tests.lookup("tokenize")+"\n"+
tests.lookup("parse")+"\n"+
tests.lookup("bytecode-table")+"\n"+
tests.lookup("literal-map")+"\n"+
tests.lookup("bcompile")+"\n"+
top_level_source+"\n"+
cfs_source + '\n' +
Expand Down
1 change: 1 addition & 0 deletions write-rust-bytecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
tests.lookup("tokenize")+"\n"+
tests.lookup("parse")+"\n"+
tests.lookup("bytecode-table")+"\n"+
tests.lookup("literal-map")+"\n"+
tests.lookup("bcompile")+"\n"+
top_level_source+"\n"+
cfs_source + '\n' +
Expand Down

0 comments on commit b847a2b

Please sign in to comment.