Skip to content

Commit b847a2b

Browse files
committed
Split off literals table into its own module
1 parent 49c62f8 commit b847a2b

11 files changed

+78
-36
lines changed

bcompile.js

+6-31
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
//
4141
// C. Scott Ananian
4242
// 2011-05-10 / 2020-02-12
43-
define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_source, bytecode_table) {
43+
define(["text!bcompile.js", "bytecode-table", "literal-map"], function make_bcompile(bcompile_source, bytecode_table, LiteralMap) {
4444
// helper function for debugging
4545
var assert = function(b, obj) {
4646
if (!b) {
@@ -56,40 +56,15 @@ define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_s
5656
// We also need to count lexical scope nesting depth during compilation
5757
var state = {
5858
functions: [],
59-
literals: [],
59+
literals: null,
6060
// internal
6161
scope: 0,
6262
desugar_frame_get: !dont_desugar_frame_get
6363
};
6464
// literal symbol table. Does string intern'ing too.
65-
var ObjectIs = Object.is || function(a, b) {
66-
if (typeof(a)==='number' && typeof(b)==='number') {
67-
if (a!==a) { return (b!==b); } // NaN
68-
if (a===0) { return (b===0) && (1/a === 1/b); } // +/- 0
69-
}
70-
return (a===b);
71-
};
72-
var literalMap = Object.create(null);
73-
state.literal = function(val) {
74-
var i, pair, key, entries;
75-
key = typeof(val) + ':' + val; // very basic hash key
76-
entries = literalMap[key];
77-
if (entries!==undefined) {
78-
i = 0;
79-
while (i < entries.length) {
80-
pair = entries[i];
81-
if (ObjectIs(pair[0], val)) { return pair[1]; }
82-
i += 1;
83-
}
84-
} else {
85-
entries = [];
86-
literalMap[key] = entries;
87-
}
88-
i = this.literals.length;
89-
this.literals[i] = val;
90-
entries.push([val, i]);
91-
return i;
92-
};
65+
var lm = LiteralMap.New();
66+
state.literals = lm.list;
67+
state.literal = function(val) { return lm.get(val); };
9368
// create a function representation
9469
state.new_function = function(nargs) {
9570
var newf = {
@@ -755,7 +730,7 @@ define(["text!bcompile.js", "bytecode-table"], function make_bcompile(bcompile_s
755730
};
756731
bcompile.__module_name__ = "bcompile";
757732
bcompile.__module_init__ = make_bcompile;
758-
bcompile.__module_deps__ = ["bytecode-table"];
733+
bcompile.__module_deps__ = ["bytecode-table", "literal-map"];
759734
bcompile.__module_source__ = bcompile_source;
760735
return bcompile;
761736
});

binterp.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,20 @@ define(["text!binterp.js", "bytecode-table"/*, "!html-escape"*/], function make_
111111
this.stack.push(na);
112112
};
113113
dispatch.new_function = function(idx) {
114+
// See 14.1.20 InstantiateFunctionObject
115+
// OrdinaryFunctionCreate
114116
var f = Object.create(MyFunction);
115117
// hidden fields of function object
116118
f.parent_frame = this.frame;
117119
f.module = this.module;
118120
f.func_id = idx;
119-
f[SLOT_PREFIX+"name"] = this.module.functions[idx].name;
120121
f[SLOT_PREFIX+"length"] = this.module.functions[idx].nargs;
122+
// MakeConstructor(f)
123+
var prototype = Object.create(MyObject);
124+
prototype[SLOT_PREFIX+"constructor"] = f;
125+
f[SLOT_PREFIX+"prototype"] = prototype;
126+
// SetFunctionName
127+
f[SLOT_PREFIX+"name"] = this.module.functions[idx].name;
121128
this.stack.push(f);
122129
};
123130
var get_slot = function(obj, name) {

ctiles.js

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ add_demo('JS parser', tests.lookup('parse'));
1515
add_demo('JS compiler', tests.lookup('jcompile'));
1616
add_demo('Tile renderer', tests.lookup('crender'));
1717
add_demo('Bytecode table', tests.lookup('bytecode-table'));
18+
add_demo('Literals map', tests.lookup('literal-map'));
1819
add_demo('Bytecode compiler', tests.lookup('bcompile'));
1920
add_demo('Bytecode interpreter', tests.lookup('binterp'));
2021
add_demo('Standard library', tests.lookup('stdlib'));

literal-map.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// # literal-map.js
2+
//
3+
// A simple table of (literal) values
4+
//
5+
// Uses a simple hashtable lookup, but uses SameValue for identity
6+
// (ie, NaN, +0, and -0 are all treated as distinct)
7+
// Maps any given value into an integer index.
8+
define(["text!literal-map.js"], function make_literal_map(literal_map_source) {
9+
10+
var ObjectIs = Object.is || function(a, b) {
11+
if (typeof(a)==='number' && typeof(b)==='number') {
12+
if (a!==a) { return (b!==b); } // NaN
13+
if (a===0) { return (b===0) && (1/a === 1/b); } // +/- 0
14+
}
15+
return (a===b);
16+
};
17+
18+
var LiteralMap = function(items) {
19+
this.map = Object.create(null);
20+
this.list = [];
21+
if (items!==undefined) {
22+
items.forEach(function(v) { this.get(v); }, this);
23+
}
24+
};
25+
// This next line isn't required, but it makes bootstrapping easier.
26+
LiteralMap.prototype = { constructor: LiteralMap };
27+
LiteralMap.prototype.get = function(val) {
28+
var i, pair, key, entries;
29+
key = typeof(val) + ':' + val; // very basic hash key
30+
entries = this.map[key];
31+
if (entries!==undefined) {
32+
i = 0;
33+
while (i < entries.length) {
34+
pair = entries[i];
35+
if (ObjectIs(pair[0], val)) { return pair[1]; }
36+
i += 1;
37+
}
38+
} else {
39+
entries = [];
40+
this.map[key] = entries;
41+
}
42+
i = this.list.length;
43+
this.list[i] = val;
44+
entries.push([val, i]);
45+
return i;
46+
};
47+
LiteralMap.__module_name__ = "literal-map";
48+
LiteralMap.__module_init__ = make_literal_map;
49+
LiteralMap.__module_deps__ = [];
50+
LiteralMap.__module_source__ = literal_map_source;
51+
return LiteralMap;
52+
});

nodemain.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = Object.create(null);
2222
// Things to export.
2323
['parse', 'jcompile',
2424
// Bytecode compiler-interpreter.
25-
'bytecode-table', 'bcompile', 'binterp', 'stdlib',
25+
'bytecode-table', 'literal-map', 'bcompile', 'binterp', 'stdlib',
2626
// `asm.js` project.
2727
'asm-llvm',
2828
// FRS-style event system.

tdop.js

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ function do_it() {
6363
tests.lookup("tokenize")+"\n"+
6464
tests.lookup("parse")+"\n"+
6565
tests.lookup("bytecode-table")+"\n"+
66+
tests.lookup("literal-map")+"\n"+
6667
tests.lookup("bcompile")+"\n"+
6768
tests.lookup("binterp")+"\n"+
6869
top_level_source+"\n"+

test/binterp-tests.js

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var metainterpreter = (function() {
3333
tests.lookup("tokenize")+"\n"+
3434
tests.lookup("parse")+"\n"+
3535
tests.lookup("bytecode-table")+"\n"+
36+
tests.lookup("literal-map")+"\n"+
3637
tests.lookup("bcompile")+"\n"+
3738
tests.lookup("binterp")+"\n"+
3839
top_level_source+"\n"+

tests.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
define(["text!tests.js", "str-escape",
33
/* These modules are just imported to make test cases out of them. */
44
"tokenize", "parse", "jcompile", "crender", "bytecode-table",
5-
"bcompile", "binterp", "stdlib", "events", "asm-llvm"],
5+
"literal-map", "bcompile", "binterp", "stdlib", "events", "asm-llvm"],
66
function make_tests(tests_source, str_escape,
77
tokenize, parse, jcompile, crender, bytecode_table,
8-
bcompile, binterp, stdlib, events, asm_llvm) {
8+
LiteralMap, bcompile, binterp, stdlib, events,
9+
asm_llvm) {
910
var deps = ["tests_source", "str-escape",
1011
"tokenize", "parse", "jcompile", "crender", "bytecode-table",
11-
"bcompile", "binterp", "stdlib", "events", "asm-llvm"];
12+
"literal-map", "bcompile", "binterp", "stdlib", "events",
13+
"asm-llvm"];
1214
var test=[], i=2/* skip tests_source and str_escape */;
1315
// The first tests are our own source code, from the module arguments.
1416
while (i < arguments.length) {

write-lua-bytecode.js

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
4040
tests.lookup("tokenize")+"\n"+
4141
tests.lookup("parse")+"\n"+
4242
tests.lookup("bytecode-table")+"\n"+
43+
tests.lookup("literal-map")+"\n"+
4344
tests.lookup("bcompile")+"\n"+
4445
top_level_source+"\n"+
4546
cfs_source + '\n' +

write-php-bytecode.js

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
4040
tests.lookup("tokenize")+"\n"+
4141
tests.lookup("parse")+"\n"+
4242
tests.lookup("bytecode-table")+"\n"+
43+
tests.lookup("literal-map")+"\n"+
4344
tests.lookup("bcompile")+"\n"+
4445
top_level_source+"\n"+
4546
cfs_source + '\n' +

write-rust-bytecode.js

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ define(['./parse', './bcompile', './bytecode-table', './top-level', './str-escap
4040
tests.lookup("tokenize")+"\n"+
4141
tests.lookup("parse")+"\n"+
4242
tests.lookup("bytecode-table")+"\n"+
43+
tests.lookup("literal-map")+"\n"+
4344
tests.lookup("bcompile")+"\n"+
4445
top_level_source+"\n"+
4546
cfs_source + '\n' +

0 commit comments

Comments
 (0)