aboutsummaryrefslogtreecommitdiff
path: root/src/jsifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsifier.js')
-rw-r--r--src/jsifier.js206
1 files changed, 105 insertions, 101 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 69d9842a..50030268 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -231,12 +231,11 @@ function JSify(data, functionsOnly, givenFunctions) {
if (value.intertype in PARSABLE_LLVM_FUNCTIONS) {
return [finalizeLLVMFunctionCall(value)];
} else if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) {
- return makeGlobalUse(indexizeFunctions(parseNumerical(value.value), type));
+ return [makeGlobalUse(indexizeFunctions(parseNumerical(value.value), type))];
} else if (value.intertype === 'emptystruct') {
return makeEmptyStruct(type);
} else if (value.intertype === 'string') {
- return JSON.stringify(parseLLVMString(value.text)) +
- ' /* ' + value.text.substr(0, 20).replace(/[*<>]/g, '_') + ' */'; // make string safe for inclusion in comment
+ return parseLLVMString(value.text);
} else {
return alignStruct(handleSegments(value.contents), type);
}
@@ -244,9 +243,7 @@ function JSify(data, functionsOnly, givenFunctions) {
function parseConst(value, type, ident) {
var constant = makeConst(value, type);
- if (typeof constant === 'object') {
- constant = flatten(constant).map(function(x) { return parseNumerical(x) })
- }
+ constant = flatten(constant).map(function(x) { return parseNumerical(x) })
return constant;
}
@@ -254,6 +251,7 @@ function JSify(data, functionsOnly, givenFunctions) {
substrate.addActor('GlobalVariable', {
processItem: function(item) {
function needsPostSet(value) {
+ if (typeof value !== 'string') return false;
return value[0] in UNDERSCORE_OPENPARENS || value.substr(0, 14) === 'CHECK_OVERFLOW'
|| value.substr(0, 6) === 'GLOBAL';
}
@@ -266,105 +264,82 @@ function JSify(data, functionsOnly, givenFunctions) {
item.ctors.map(function(ctor) { return ' { func: function() { ' + ctor + '() } }' }).join(',\n') +
'\n]);\n';
return ret;
+ }
+
+ var constant = null;
+ var allocator = (BUILD_AS_SHARED_LIB && !item.external) ? 'ALLOC_NORMAL' : 'ALLOC_STATIC';
+ var index = null;
+ if (item.external && BUILD_AS_SHARED_LIB) {
+ // External variables in shared libraries should not be declared as
+ // they would shadow similarly-named globals in the parent.
+ item.JS = '';
} else {
- var constant = null;
- var allocator = (BUILD_AS_SHARED_LIB && !item.external) ? 'ALLOC_NORMAL' : 'ALLOC_STATIC';
- var index = null;
- if (item.external && BUILD_AS_SHARED_LIB) {
- // External variables in shared libraries should not be declared as
- // they would shadow similarly-named globals in the parent.
- item.JS = '';
- } else {
- item.JS = makeGlobalDef(item.ident);
- }
+ item.JS = makeGlobalDef(item.ident);
+ }
- if (item.external && !ASM_JS) { // ASM_JS considers externs to be globals
- // Import external global variables from the library if available.
- var shortident = item.ident.slice(1);
- if (LibraryManager.library[shortident] &&
- LibraryManager.library[shortident].length &&
- !BUILD_AS_SHARED_LIB) {
- if (addedLibraryItems[shortident]) return ret;
- var val = LibraryManager.library[shortident];
- var padding;
- if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
- padding = [item.type].concat(zeros(Runtime.getNativeFieldSize(item.type)-1));
- } else {
- padding = makeEmptyStruct(item.type);
- }
- var padded = val.concat(padding.slice(val.length));
- var js = item.ident + '=' + makePointer(padded, null, allocator, item.type, index) + ';'
- if (LibraryManager.library[shortident + '__postset']) {
- js += '\n' + LibraryManager.library[shortident + '__postset'];
- }
- ret.push({
- intertype: 'GlobalVariablePostSet',
- JS: js
- });
- }
- return ret;
+ if (!NAMED_GLOBALS && isIndexableGlobal(item.ident)) {
+ index = makeGlobalUse(item.ident); // index !== null indicates we are indexing this
+ allocator = 'ALLOC_NONE';
+ }
+ if (item.external) {
+ if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
+ constant = zeros(Runtime.getNativeFieldSize(item.type));
} else {
- if (!NAMED_GLOBALS && isIndexableGlobal(item.ident)) {
- index = makeGlobalUse(item.ident); // index !== null indicates we are indexing this
- allocator = 'ALLOC_NONE';
- }
- if (item.external) {
- assert(ASM_JS);
- if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
- constant = zeros(Runtime.getNativeFieldSize(item.type));
- } else {
- constant = makeEmptyStruct(item.type);
- }
- constant = JSON.stringify(constant);
- } else {
- constant = parseConst(item.value, item.type, item.ident);
- }
- if (typeof constant === 'string' && constant[0] != '[') {
- constant = [constant]; // A single item. We may need a postset for it.
- }
- if (typeof constant === 'object') {
- // This is a flattened object. We need to find its idents, so they can be assigned to later
- constant.forEach(function(value, i) {
- if (needsPostSet(value)) { // ident, or expression containing an ident
- ret.push({
- intertype: 'GlobalVariablePostSet',
- JS: makeSetValue(makeGlobalUse(item.ident), i, value, 'i32', false, true) + ';' // ignore=true, since e.g. rtti and statics cause lots of safe_heap errors
- });
- constant[i] = '0';
- }
- });
- }
- // NOTE: This is the only place that could potentially create static
- // allocations in a shared library.
- constant = makePointer(constant, null, allocator, item.type, index);
- var js;
-
- js = (index !== null ? '' : item.ident + '=') + constant + ';'; // \n Module.print("' + item.ident + ' :" + ' + makeGlobalUse(item.ident) + ');';
+ constant = makeEmptyStruct(item.type);
+ }
+ } else {
+ constant = parseConst(item.value, item.type, item.ident);
+ }
+ assert(typeof constant === 'object');//, [typeof constant, JSON.stringify(constant), item.external]);
- // Special case: class vtables. We make sure they are null-terminated, to allow easy runtime operations
- if (item.ident.substr(0, 5) == '__ZTV') {
- if (index !== null) {
- index = getFastValue(index, '+', Runtime.alignMemory(calcAllocatedSize(Variables.globals[item.ident].type)));
- }
- js += '\n' + makePointer([0], null, allocator, ['void*'], index) + ';';
- }
- if (!ASM_JS && (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS))) {
- js += '\nModule["' + item.ident + '"] = ' + item.ident + ';';
- }
- if (BUILD_AS_SHARED_LIB == 2 && !item.private_) {
- // TODO: make the assert conditional on ASSERTIONS
- js += 'if (globalScope) { assert(!globalScope["' + item.ident + '"]); globalScope["' + item.ident + '"] = ' + item.ident + ' }';
- }
- if (item.external && !NAMED_GLOBALS) {
- assert(ASM_JS);
- js = 'var ' + item.ident + ' = ' + js; // force an explicit naming, even if unnamed globals, for asm forwarding
- }
- return ret.concat({
- intertype: 'GlobalVariable',
- JS: js,
+ // This is a flattened object. We need to find its idents, so they can be assigned to later
+ constant.forEach(function(value, i) {
+ if (needsPostSet(value)) { // ident, or expression containing an ident
+ ret.push({
+ intertype: 'GlobalVariablePostSet',
+ JS: makeSetValue(makeGlobalUse(item.ident), i, value, 'i32', false, true) + ';' // ignore=true, since e.g. rtti and statics cause lots of safe_heap errors
});
+ constant[i] = '0';
}
+ });
+
+ if (item.external) {
+ // External variables in shared libraries should not be declared as
+ // they would shadow similarly-named globals in the parent, so do nothing here.
+ if (BUILD_AS_SHARED_LIB) return ret;
+ // Library items need us to emit something, but everything else requires nothing.
+ if (!LibraryManager.library[item.ident.slice(1)]) return ret;
+ }
+
+ // ensure alignment
+ constant = constant.concat(zeros(Runtime.alignMemory(constant.length) - constant.length));
+
+ // Special case: class vtables. We make sure they are null-terminated, to allow easy runtime operations
+ if (item.ident.substr(0, 5) == '__ZTV') {
+ constant = constant.concat(zeros(Runtime.alignMemory(QUANTUM_SIZE)));
+ }
+
+ // NOTE: This is the only place that could potentially create static
+ // allocations in a shared library.
+ constant = makePointer(constant, null, allocator, item.type, index);
+
+ var js = (index !== null ? '' : item.ident + '=') + constant;
+ if (js) js += ';';
+
+ if (!ASM_JS && (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS))) {
+ js += '\nModule["' + item.ident + '"] = ' + item.ident + ';';
}
+ if (BUILD_AS_SHARED_LIB == 2 && !item.private_) {
+ // TODO: make the assert conditional on ASSERTIONS
+ js += 'if (globalScope) { assert(!globalScope["' + item.ident + '"]); globalScope["' + item.ident + '"] = ' + item.ident + ' }';
+ }
+ if (item.external && !NAMED_GLOBALS) {
+ js = 'var ' + item.ident + ' = ' + js; // force an explicit naming, even if unnamed globals, for asm forwarding
+ }
+ return ret.concat({
+ intertype: 'GlobalVariable',
+ JS: js,
+ });
}
});
@@ -1523,8 +1498,38 @@ function JSify(data, functionsOnly, givenFunctions) {
print('assert(STATICTOP < TOTAL_MEMORY);\n');
}
}
- var generated = itemsDict.function.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.GlobalVariable).concat(itemsDict.GlobalVariablePostSet);
- if (!DEBUG_MEMORY) print(generated.map(function(item) { return item.JS }).join('\n'));
+ var generated = itemsDict.function.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.GlobalVariable);
+ print(generated.map(function(item) { return item.JS }).join('\n'));
+
+ if (phase == 'pre') {
+ if (memoryInitialization.length > 0) {
+ // apply postsets directly into the big memory initialization
+ itemsDict.GlobalVariablePostSet = itemsDict.GlobalVariablePostSet.filter(function(item) {
+ var m;
+ if (m = /^HEAP([\dFU]+)\[([()>\d]+)\] *= *([()|\d{}\w_' ]+);?$/.exec(item.JS)) {
+ var type = getTypeFromHeap(m[1]);
+ var bytes = Runtime.getNativeTypeSize(type);
+ var target = eval(m[2]) << log2(bytes);
+ var value = m[3];
+ try {
+ value = eval(value);
+ } catch(e) {
+ // possibly function table {{{ FT_* }}} etc.
+ if (value.indexOf('{{ ') < 0) return true;
+ }
+ writeInt8s(memoryInitialization, target - TOTAL_STACK, value, type);
+ return false;
+ }
+ return true;
+ });
+ // write out the singleton big memory initialization value
+ print('/* memory initializer */ ' + makePointer(memoryInitialization, null, 'ALLOC_NONE', 'i8', 'TOTAL_STACK', true)); // we assert on TOTAL_STACK == GLOBAL_BASE
+ } else {
+ print('/* memory initializer */'); // test purposes
+ }
+ }
+
+ print(itemsDict.GlobalVariablePostSet.map(function(item) { return item.JS }).join('\n'));
return;
}
@@ -1546,7 +1551,6 @@ function JSify(data, functionsOnly, givenFunctions) {
}
});
}
-
JSify(globalsData, true, Functions);
globalsData = null;
data.unparsedGlobalss = null;