46
46
var form3ab = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:metadata !\d+|i32 \d+|null), metadata !(\d+).*$/);
47
47
var form3ac = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:metadata !\d+|null), metadata !"[^"]*", metadata !(\d+)[^\[]*.*$/);
48
48
var form3ad = new RegExp(/^!(\d+) = metadata !{i32 \d+, (?:i32 \d+|null), (?:i32 \d+|null), metadata !"[^"]*", metadata !"[^"]*", metadata !"[^"]*", metadata !(\d+),.*$/);
49
var form3b = new RegExp(/^!(\d+) = metadata !{i32 \d+, metadata !"([^"]+)", metadata !"([^"]*)", (metadata !\d+|null)}.*$/);
49
var form3ae = new RegExp(/^!(\d+) = metadata !{i32 \d+, metadata !(\d+).*$/);
50
// LLVM 3.3 drops the first and last parameters.
51
var form3b = new RegExp(/^!(\d+) = metadata !{(?:i32 \d+, )?metadata !"([^"]+)", metadata !"([^"]*)"(?:, (metadata !\d+|null))?}.*$/);
50
52
var form3c = new RegExp(/^!(\d+) = metadata !{\w+\d* !?(\d+)[^\d].*$/);
51
53
var form4 = new RegExp(/^!llvm.dbg.[\w\.]+ = .*$/);
52
54
var form5 = new RegExp(/^!(\d+) = metadata !{.*$/);
75
77
lines[i] = ';'; // return an empty line, to keep line numbers of subsequent lines the same
78
calc = form3a.exec(line) || form3ab.exec(line) || form3ac.exec(line) || form3ad.exec(line);
80
calc = form3a.exec(line) || form3ab.exec(line) || form3ac.exec(line) || form3ad.exec(line) || form3ae.exec(line);
80
82
metadataToParentMetadata[calc[1]] = calc[2];
114
116
m = metadataToParentMetadata[m];
115
117
assert(m, 'Confused as to parent metadata for llvm #' + l + ', metadata !' + m);
117
this.llvmLineToSourceFile[l] = metadataToFilename[m];
119
// Normalize Windows path slashes coming from LLVM metadata, so that forward slashes can be assumed as path delimiters.
120
this.llvmLineToSourceFile[l] = metadataToFilename[m].replace(/\\5C/g, '/');
225
228
needAnalysis: {}, // Types noticed during parsing, that need analysis
230
hasInlineJS: false, // whether the program has inline JS anywhere
227
232
// Set to true if we actually use precise i64 math: If PRECISE_I64_MATH is set, and also such math is actually
228
233
// needed (+,-,*,/,% - we do not need it for bitops), or PRECISE_I64_MATH is 2 (forced)
229
234
preciseI64MathUsed: (PRECISE_I64_MATH == 2)
245
250
blockAddresses: {}, // maps functions to a map of block labels to label ids
252
aliases: {}, // in shared modules (MAIN_MODULE or SHARED_MODULE), a list of aliases for functions that have them
247
254
getSignature: function(returnType, argTypes, hasVarArgs) {
248
255
var sig = returnType == 'void' ? 'v' : (isIntImplemented(returnType) ? 'i' : 'f');
249
256
for (var i = 0; i < argTypes.length; i++) {
250
257
var type = argTypes[i];
251
258
if (!type) break; // varargs
252
sig += isIntImplemented(type) ? (getBits(type) == 64 ? 'ii' : 'i') : 'f'; // legalized i64s will be i32s
259
if (type in Runtime.FLOAT_TYPES) {
262
var chunks = getNumIntChunks(type);
263
for (var j = 0; j < chunks; j++) sig += 'i';
254
266
if (hasVarArgs) sig += 'i';
270
getSignatureReturnType: function(sig) {
272
case 'v': return 'void';
273
case 'i': return 'i32';
274
case 'f': return 'double';
275
default: throw 'what is this sig? ' + sig;
258
279
// Mark a function as needing indexing. Python will coordinate them all
259
getIndex: function(ident, doNotCreate) {
260
if (doNotCreate && !(ident in this.indexedFunctions)) {
261
if (!Functions.getIndex.tentative) Functions.getIndex.tentative = {}; // only used by GL emulation; TODO: generalize when needed
262
Functions.getIndex.tentative[ident] = 0;
280
getIndex: function(ident, sig) {
264
282
if (phase != 'post' && singlePhase) {
265
if (!doNotCreate) this.indexedFunctions[ident] = 0; // tell python we need this indexized
266
return "'{{ FI_" + toNiceIdent(ident) + " }}'"; // something python will replace later
283
ret = "'{{ FI_" + toNiceIdent(ident) + " }}'"; // something python will replace later
284
this.indexedFunctions[ident] = 0;
268
286
if (!singlePhase) return 'NO_INDEX'; // Should not index functions in post
269
var ret = this.indexedFunctions[ident];
287
ret = this.indexedFunctions[ident];
271
if (doNotCreate) return '0';
272
289
ret = this.nextIndex;
273
290
this.nextIndex += 2; // Need to have indexes be even numbers, see |polymorph| test
274
291
this.indexedFunctions[ident] = ret;
276
return ret.toString();
293
ret = ret.toString();
295
if (SIDE_MODULE && sig) { // sig can be undefined for the GL library functions
296
ret = '((F_BASE_' + sig + ' + ' + ret + ')|0)';
297
} else if (BUILD_AS_SHARED_LIB) {
298
ret = '(FUNCTION_TABLE_OFFSET + ' + ret + ')';
280
303
getTable: function(sig) {
324
347
var curr = table[i];
325
348
if (curr && curr != '0' && !Functions.implementedFunctions[curr]) {
326
curr = toNiceIdent(curr); // fix Math.* to Math_*
349
var short = toNiceIdent(curr); // fix Math.* to Math_*
350
curr = t + '_' + short; // libfuncs can alias with different sigs, wrap each separately
327
351
// This is a library function, we can't just put it in the function table, need a wrapper
328
352
if (!wrapped[curr]) {
329
var args = '', arg_coercions = '', call = curr + '(', retPre = '', retPost = '';
353
var args = '', arg_coercions = '', call = short + '(', retPre = '', retPost = '';
330
354
if (t[0] != 'v') {
331
355
if (t[0] == 'i') {
332
356
retPre = 'return ';
341
365
call += (j > 1 ? ',' : '') + asmCoercion('a' + j, t[j] != 'i' ? 'float' : 'i32');
344
if (curr == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
368
if (short == '_setjmp') printErr('WARNING: setjmp used via a function pointer. If this is for libc setjmp (not something of your own with the same name), it will break things');
345
369
tables.pre += 'function ' + curr + '__wrapper(' + args + ') { ' + arg_coercions + ' ; ' + retPre + call + retPost + ' }\n';
346
370
wrapped[curr] = 1;
398
422
load: function() {
399
423
if (this.library) return;
401
var libraries = ['library.js', 'library_browser.js', 'library_sdl.js', 'library_gl.js', 'library_glut.js', 'library_xlib.js', 'library_egl.js', 'library_gc.js', 'library_jansson.js', 'library_openal.js', 'library_glfw.js'].concat(additionalLibraries);
425
var libraries = ['library.js', 'library_path.js', 'library_fs.js', 'library_memfs.js', 'library_sockfs.js', 'library_tty.js', 'library_browser.js', 'library_sdl.js', 'library_gl.js', 'library_glut.js', 'library_xlib.js', 'library_egl.js', 'library_gc.js', 'library_jansson.js', 'library_openal.js', 'library_glfw.js'].concat(additionalLibraries);
402
426
for (var i = 0; i < libraries.length; i++) {
403
427
eval(processMacros(preprocess(read(libraries[i]))));
423
447
isStubFunction: function(ident) {
448
if (SIDE_MODULE == 1) return false; // cannot eliminate these, as may be implement in the main module and imported by us
424
449
var libCall = LibraryManager.library[ident.substr(1)];
425
450
return typeof libCall === 'function' && libCall.toString().replace(/\s/g, '') === 'function(){}'
426
451
&& !(ident in Functions.implementedFunctions);
440
465
Variables: Variables,
441
466
Functions: Functions,
442
EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS // needed for asm.js global constructors (ctors)
467
EXPORTED_FUNCTIONS: EXPORTED_FUNCTIONS, // needed for asm.js global constructors (ctors)
468
Runtime: { GLOBAL_BASE: Runtime.GLOBAL_BASE }
444
470
} else if (phase == 'funcs') {
445
471
print('\n//FORWARDED_DATA:' + JSON.stringify({
446
Types: { preciseI64MathUsed: Types.preciseI64MathUsed },
473
hasInlineJS: Types.hasInlineJS,
474
preciseI64MathUsed: Types.preciseI64MathUsed
448
477
blockAddresses: Functions.blockAddresses,
449
478
indexedFunctions: Functions.indexedFunctions,