aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-07-16 20:57:52 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-07-16 20:57:52 -0700
commitab56efe76e94a0508d3983e9430e2aa18b1e2667 (patch)
treefa09903a81b61b1dbfb2f6e148e3d23e78b87607
parent7cfc95807c12a3351c640ad5dde954cba1d3ea4d (diff)
refactor and simplify library loading in order to make type info available there
-rw-r--r--src/compiler.js12
-rw-r--r--src/jsifier.js15
-rw-r--r--src/library.js82
-rw-r--r--src/library_browser.js2
-rw-r--r--src/library_gl.js2
-rw-r--r--src/library_sdl.js2
-rw-r--r--src/modules.js16
-rw-r--r--src/runtime.js85
8 files changed, 109 insertions, 107 deletions
diff --git a/src/compiler.js b/src/compiler.js
index 4fe68e88..8cb023d9 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -56,7 +56,7 @@ load('parseTools.js');
load('intertyper.js');
load('analyzer.js');
load('jsifier.js');
-load('runtime.js');
+eval(processMacros(preprocess(read('runtime.js'))));
//===============================
// Main
@@ -74,13 +74,5 @@ do {
// Do it
-var inter = intertyper(lines);
-
-// Load library, with preprocessing and macros. Must be done after intertyper, so we know if we have debug info or not
-for (suffix in set('', '_sdl', '_gl', '_browser')) {
- eval(processMacros(preprocess(read('library' + suffix + '.js'), CONSTANTS)));
-}
-LibraryManager.init();
-
-JSify(analyzer(inter));
+JSify(analyzer(intertyper(lines)));
diff --git a/src/jsifier.js b/src/jsifier.js
index dfd1f08d..b712e7ae 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -7,10 +7,11 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
// Add additional necessary items for the main pass
if (mainPass) {
+ LibraryManager.load();
var libFuncsToInclude;
if (INCLUDE_FULL_LIBRARY) {
assert(!BUILD_AS_SHARED_LIB, 'Cannot have both INCLUDE_FULL_LIBRARY and BUILD_AS_SHARED_LIB set.')
- libFuncsToInclude = keys(Library);
+ libFuncsToInclude = keys(LibraryManager.library);
} else {
libFuncsToInclude = ['memset', 'malloc', 'free'];
}
@@ -248,7 +249,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
if (BUILD_AS_SHARED_LIB) {
// Shared libraries reuse the runtime of their parents.
item.JS = '';
- } else if (Library.hasOwnProperty(shortident)) {
+ } else if (LibraryManager.library.hasOwnProperty(shortident)) {
function addFromLibrary(ident) {
if (ident in addedLibraryItems) return '';
// Don't replace implemented functions with library ones (which can happen when we add dependencies).
@@ -256,12 +257,12 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
if (('_' + ident) in moduleFunctions) return '';
addedLibraryItems[ident] = true;
- var snippet = Library[ident];
+ var snippet = LibraryManager.library[ident];
var redirectedIdent = null;
- var deps = Library[ident + '__deps'] || [];
+ var deps = LibraryManager.library[ident + '__deps'] || [];
if (typeof snippet === 'string') {
- if (Library[snippet]) {
+ if (LibraryManager.library[snippet]) {
// Redirection for aliases. We include the parent, and at runtime make ourselves equal to it.
// This avoid having duplicate functions with identical content.
redirectedIdent = snippet;
@@ -291,7 +292,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
var postsetId = ident + '__postset';
- var postset = Library[postsetId];
+ var postset = LibraryManager.library[postsetId];
if (postset && !addedLibraryItems[postsetId]) {
addedLibraryItems[postsetId] = true;
ret.push({
@@ -301,7 +302,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
if (redirectedIdent) {
- deps = deps.concat(Library[redirectedIdent + '__deps'] || []);
+ deps = deps.concat(LibraryManager.library[redirectedIdent + '__deps'] || []);
}
// $ident's are special, we do not prefix them with a '_'.
if (ident[0] === '$') {
diff --git a/src/library.js b/src/library.js
index 21078c3c..c900c90d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -13,7 +13,7 @@
// object. For convenience, the short name appears here. Note that if you add a
// new function with an '_', it will not be found.
-var Library = {
+LibraryManager.library = {
// ==========================================================================
// stdio.h
// ==========================================================================
@@ -1801,19 +1801,10 @@ var Library = {
return time1 - time0;
},
- __tm_struct_layout: Runtime.generateStructInfo([
- ['i32', 'tm_sec'],
- ['i32', 'tm_min'],
- ['i32', 'tm_hour'],
- ['i32', 'tm_mday'],
- ['i32', 'tm_mon'],
- ['i32', 'tm_year'],
- ['i32', 'tm_wday'],
- ['i32', 'tm_yday'],
- ['i32', 'tm_isdst'],
- ['i32', 'tm_gmtoff'],
- ['i8*', 'tm_zone'],
- ]),
+ __tm_struct_layout: Runtime.generateStructInfo(
+ ['tm_sec', 'tm_min', 'tm_hour', 'tm_mday', 'tm_mon', 'tm_year', 'tm_wday', 'tm_yday', 'tm_isdst', 'tm_gmtoff', 'tm_zone'],
+ '%struct.tm'
+ ),
// Statically allocated time struct.
__tm_current: 0,
// Statically allocated timezone strings.
@@ -2290,66 +2281,3 @@ var Library = {
}
};
-
-// 'Runtime' functions that need preprocessor parsing like library functions
-
-// Converts a value we have as signed, into an unsigned value. For
-// example, -1 in int32 would be a very large number as unsigned.
-function unSign(value, bits, ignore, sig) {
- if (value >= 0) {
-#if CHECK_SIGNS
- if (!ignore) CorrectionsMonitor.note('UnSign', 1, sig);
-#endif
- return value;
- }
-#if CHECK_SIGNS
- if (!ignore) CorrectionsMonitor.note('UnSign', 0, sig);
-#endif
- return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
- : Math.pow(2, bits) + value;
- // TODO: clean up previous line
-}
-
-// Converts a value we have as unsigned, into a signed value. For
-// example, 200 in a uint8 would be a negative number.
-function reSign(value, bits, ignore, sig) {
- if (value <= 0) {
-#if CHECK_SIGNS
- if (!ignore) CorrectionsMonitor.note('ReSign', 1, sig);
-#endif
- return value;
- }
- var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
- : Math.pow(2, bits-1);
-#if CHECK_SIGNS
- var noted = false;
-#endif
- if (value >= half) {
-#if CHECK_SIGNS
- if (!ignore) {
- CorrectionsMonitor.note('ReSign', 0, sig);
- noted = true;
- }
-#endif
- value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
- }
-#if CHECK_SIGNS
- // If this is a 32-bit value, then it should be corrected at this point. And,
- // without CHECK_SIGNS, we would just do the |0 shortcut, so check that that
- // would indeed give the exact same result.
- if (bits === 32 && (value|0) !== value && typeof value !== 'boolean') {
- if (!ignore) {
- CorrectionsMonitor.note('ReSign', 0, sig);
- noted = true;
- }
- }
- if (!noted) CorrectionsMonitor.note('ReSign', 1, sig);
-#endif
- return value;
-}
-
-// Just a stub. We don't care about noting compile-time corrections. But they are called.
-var CorrectionsMonitor = {
- note: function(){}
-};
-
diff --git a/src/library_browser.js b/src/library_browser.js
index d24854f9..c4d1d768 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -1,6 +1,6 @@
// Utilities for browser environments
-mergeInto(Library, {
+mergeInto(LibraryManager.library, {
$Browser: {
// Given binary data for an image, in a format like PNG or JPG, we convert it
// to flat pixel data. We do so using the browser's native code.
diff --git a/src/library_gl.js b/src/library_gl.js
index 9d5f14fa..20197141 100644
--- a/src/library_gl.js
+++ b/src/library_gl.js
@@ -89,5 +89,5 @@ var LibraryGL = {
});
});
-mergeInto(Library, LibraryGL);
+mergeInto(LibraryManager.library, LibraryGL);
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 6c70f9f6..57a98e64 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -81,7 +81,7 @@
// solution here is to have a singleIteration() function which is a single loop
// iteration, and from JS to do something like setInterval(_singleIteration, 1/30)
-mergeInto(Library, {
+mergeInto(LibraryManager.library, {
$SDL__deps: ['$Browser'],
$SDL: {
defaults: {
diff --git a/src/modules.js b/src/modules.js
index f1f5f487..dc4a296d 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -171,22 +171,26 @@ var Functions = {
};
var LibraryManager = {
- ready: false,
+ library: null,
- init: function() {
- this.ready = true;
+ load: function() {
+ assert(!this.library);
+
+ for (suffix in set('', '_sdl', '_gl', '_browser')) {
+ eval(processMacros(preprocess(read('library' + suffix + '.js'), CONSTANTS)));
+ }
},
// Given an ident, see if it is an alias for something, and so forth, returning
// the earliest ancestor (the root)
getRootIdent: function(ident) {
- if (!this.ready) return null;
- var ret = Library[ident];
+ if (!this.library) return null;
+ var ret = LibraryManager.library[ident];
if (!ret) return null;
var last = ident;
while (typeof ret === 'string') {
last = ret;
- ret = Library[ret];
+ ret = LibraryManager.library[ret];
}
return last;
}
diff --git a/src/runtime.js b/src/runtime.js
index 4246ad1c..8acb9260 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -160,15 +160,30 @@ Runtime = {
// ]
// ) will return
// { field1: 0, field2: 4 } (depending on QUANTUM_SIZE)
- generateStructInfo: function(struct) {
+ //
+ // You can optionally provide a type name as a second parameter. In that
+ // case, you do not need to provide the types (but you do still need to
+ // provide the names, since they are not present in the .ll), for example,
+ // generateStructInfo(['field1', 'field2'], '%struct.UserStructType');
+ // (Note that you will need the full %struct.* name here at compile time,
+ // but not at runtime. The reason is that during compilation we cannot simplify
+ // the type names yet.)
+ generateStructInfo: function(struct, typeName) {
var fields = struct.map(function(item) { return item[0] });
- var type = { fields: fields };
- var alignment = Runtime.calculateStructAlignment(type);
+ var type, alignment;
+ if (typeName) {
+ type = Types.types[typeName];
+ if (!type) return null;
+ alignment = type.flatIndexes;
+ } else {
+ var type = { fields: fields };
+ alignment = Runtime.calculateStructAlignment(type);
+ }
var ret = {
__size__: type.flatSize
};
struct.forEach(function(item, i) {
- ret[item[1]] = alignment[i];
+ ret[typeof item === 'string' ? item : item[1]] = alignment[i];
});
return ret;
}
@@ -193,3 +208,65 @@ function getRuntime() {
return ret + ' __dummy__: 0\n}\n';
}
+// Additional runtime elements, that need preprocessing
+
+// Converts a value we have as signed, into an unsigned value. For
+// example, -1 in int32 would be a very large number as unsigned.
+function unSign(value, bits, ignore, sig) {
+ if (value >= 0) {
+#if CHECK_SIGNS
+ if (!ignore) CorrectionsMonitor.note('UnSign', 1, sig);
+#endif
+ return value;
+ }
+#if CHECK_SIGNS
+ if (!ignore) CorrectionsMonitor.note('UnSign', 0, sig);
+#endif
+ return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+ : Math.pow(2, bits) + value;
+ // TODO: clean up previous line
+}
+
+// Converts a value we have as unsigned, into a signed value. For
+// example, 200 in a uint8 would be a negative number.
+function reSign(value, bits, ignore, sig) {
+ if (value <= 0) {
+#if CHECK_SIGNS
+ if (!ignore) CorrectionsMonitor.note('ReSign', 1, sig);
+#endif
+ return value;
+ }
+ var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+ : Math.pow(2, bits-1);
+#if CHECK_SIGNS
+ var noted = false;
+#endif
+ if (value >= half) {
+#if CHECK_SIGNS
+ if (!ignore) {
+ CorrectionsMonitor.note('ReSign', 0, sig);
+ noted = true;
+ }
+#endif
+ value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+ }
+#if CHECK_SIGNS
+ // If this is a 32-bit value, then it should be corrected at this point. And,
+ // without CHECK_SIGNS, we would just do the |0 shortcut, so check that that
+ // would indeed give the exact same result.
+ if (bits === 32 && (value|0) !== value && typeof value !== 'boolean') {
+ if (!ignore) {
+ CorrectionsMonitor.note('ReSign', 0, sig);
+ noted = true;
+ }
+ }
+ if (!noted) CorrectionsMonitor.note('ReSign', 1, sig);
+#endif
+ return value;
+}
+
+// Just a stub. We don't care about noting compile-time corrections. But they are called.
+var CorrectionsMonitor = {
+ note: function(){}
+};
+