diff options
-rwxr-xr-x | emcc | 3 | ||||
-rw-r--r-- | src/analyzer.js | 36 | ||||
-rw-r--r-- | src/jsifier.js | 11 | ||||
-rw-r--r-- | src/library.js | 70 | ||||
-rw-r--r-- | src/library_browser.js | 31 | ||||
-rw-r--r-- | src/library_gl.js | 4 | ||||
-rw-r--r-- | src/library_sdl.js | 118 | ||||
-rw-r--r-- | src/parseTools.js | 8 | ||||
-rw-r--r-- | src/runtime.js | 10 | ||||
-rw-r--r-- | src/settings.js | 3 | ||||
-rw-r--r-- | system/include/libc/sys/stat.h | 3 | ||||
-rw-r--r-- | system/include/libc/sys/types.h | 4 | ||||
-rw-r--r-- | tests/cases/i32_mem.ll | 23 | ||||
-rw-r--r-- | tests/cases/i32_mem.txt | 2 | ||||
-rw-r--r-- | tests/cases/zeroembedded.ll | 7 | ||||
-rw-r--r-- | tests/glgetattachedshaders.c | 93 | ||||
-rwxr-xr-x | tests/runner.py | 76 | ||||
-rw-r--r-- | tests/sdl_audio.c | 29 | ||||
-rw-r--r-- | tests/stat/output.txt | 202 | ||||
-rw-r--r-- | tests/stat/src.c | 242 | ||||
-rw-r--r-- | tests/stat/test_chmod.c | 153 | ||||
-rw-r--r-- | tests/stat/test_mknod.c | 96 | ||||
-rw-r--r-- | tests/stat/test_stat.c | 167 | ||||
-rw-r--r-- | tools/js-optimizer.js | 21 |
24 files changed, 862 insertions, 550 deletions
@@ -302,6 +302,9 @@ Options that are modified or new in %s include: your main compiled code (or run it before in some other way). + For more docs on the options --preload-file + accepts, see https://github.com/kripken/emscripten/wiki/Filesystem-Guide + --compression <codec> Compress both the compiled code and embedded/ preloaded files. <codec> should be a triple, diff --git a/src/analyzer.js b/src/analyzer.js index 1d32d7fc..b1f0b585 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -502,18 +502,38 @@ function analyzer(data, sidePass) { { intertype: 'value', ident: j.toString(), type: 'i32' } ] }); - var actualSizeType = 'i' + element.bits; // The last one may be smaller than 32 bits - toAdd.push({ + var newItem = { intertype: 'load', assignTo: element.ident, - pointerType: actualSizeType + '*', - valueType: actualSizeType, - type: actualSizeType, // XXX why is this missing from intertyper? - pointer: { intertype: 'value', ident: tempVar, type: actualSizeType + '*' }, + pointerType: 'i32*', + valueType: 'i32', + type: 'i32', + pointer: { intertype: 'value', ident: tempVar, type: 'i32*' }, ident: tempVar, - pointerType: actualSizeType + '*', align: value.align - }); + }; + var newItem2 = null; + // The last one may be smaller than 32 bits + if (element.bits < 32) { + newItem.assignTo += '$preadd$'; + newItem2 = { + intertype: 'mathop', + op: 'and', + assignTo: element.ident, + type: 'i32', + params: [{ + intertype: 'value', + type: 'i32', + ident: newItem.assignTo + }, { + intertype: 'value', + type: 'i32', + ident: (0xffffffff >>> (32 - element.bits)).toString() + }], + }; + } + toAdd.push(newItem); + if (newItem2) toAdd.push(newItem2); j++; }); Types.needAnalysis['[0 x i32]'] = 0; diff --git a/src/jsifier.js b/src/jsifier.js index 30cea99b..b377202d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1211,7 +1211,7 @@ function JSify(data, functionsOnly, givenFunctions) { // in an assignment var disabled = DISABLE_EXCEPTION_CATCHING == 2 && !(item.funcData.ident in EXCEPTION_CATCHING_WHITELIST); var phiSets = calcPhiSets(item); - var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone); + var call_ = makeFunctionCall(item.ident, item.params, item.funcData, item.type, ASM_JS && !disabled, !!item.assignTo || !item.standalone, true); var ret; @@ -1368,7 +1368,7 @@ function JSify(data, functionsOnly, givenFunctions) { return ret; }); - function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn) { + function makeFunctionCall(ident, params, funcData, type, forceByPointer, hasReturn, invoke) { // We cannot compile assembly. See comment in intertyper.js:'Call' assert(ident != 'asm', 'Inline assembly cannot be compiled to JavaScript!'); @@ -1433,7 +1433,7 @@ function JSify(data, functionsOnly, givenFunctions) { args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) }); if (ASM_JS) { - if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || funcData.setjmpTable) { + if (shortident in Functions.libraryFunctions || simpleIdent in Functions.libraryFunctions || byPointerForced || invoke || funcData.setjmpTable) { args = args.map(function(arg, i) { return asmCoercion(arg, argsTypes[i]) }); } else { args = args.map(function(arg, i) { return asmEnsureFloat(arg, argsTypes[i]) }); @@ -1522,7 +1522,8 @@ function JSify(data, functionsOnly, givenFunctions) { var sig = Functions.getSignature(returnType, argsTypes, hasVarArgs); if (ASM_JS) { assert(returnType.search(/\("'\[,/) == -1); // XXX need isFunctionType(type, out) - if (!byPointerForced && !funcData.setjmpTable) { + var functionTableCall = !byPointerForced && !funcData.setjmpTable && !invoke; + if (functionTableCall) { // normal asm function pointer call callIdent = '(' + callIdent + ')&{{{ FTM_' + sig + ' }}}'; // the function table mask is set in emscripten.py Functions.neededTables[sig] = 1; @@ -1537,7 +1538,7 @@ function JSify(data, functionsOnly, givenFunctions) { assert(!ASM_JS, 'cannot emit safe dyncalls in asm'); callIdent = '(tempInt=' + callIdent + ',tempInt < 0 || tempInt >= FUNCTION_TABLE.length-1 || !FUNCTION_TABLE[tempInt] ? abort("dyncall error: ' + sig + ' " + FUNCTION_TABLE_NAMES[tempInt]) : tempInt)'; } - if (!ASM_JS || (!byPointerForced && !funcData.setjmpTable)) callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; + if (!ASM_JS || functionTableCall) callIdent = Functions.getTable(sig) + '[' + callIdent + ']'; } var ret = callIdent + '(' + args.join(', ') + ')'; diff --git a/src/library.js b/src/library.js index 83da2faf..e650a545 100644 --- a/src/library.js +++ b/src/library.js @@ -1048,27 +1048,45 @@ LibraryManager.library = { mknod: function(path, mode, dev) { // int mknod(const char *path, mode_t mode, dev_t dev); // http://pubs.opengroup.org/onlinepubs/7908799/xsh/mknod.html - if (dev !== 0 || !(mode & 0xC000)) { // S_IFREG | S_IFDIR. - // Can't create devices or pipes through mknod(). + path = Pointer_stringify(path); + var fmt = (mode & {{{ cDefine('S_IFMT') }}}); + if (fmt !== {{{ cDefine('S_IFREG') }}} && fmt !== {{{ cDefine('S_IFCHR') }}} && + fmt !== {{{ cDefine('S_IFBLK') }}} && fmt !== {{{ cDefine('S_IFIFO') }}} && + fmt !== {{{ cDefine('S_IFSOCK') }}}) { + // not valid formats for mknod ___setErrNo(ERRNO_CODES.EINVAL); return -1; - } else { - var properties = {contents: [], isFolder: Boolean(mode & 0x4000)}; // S_IFDIR. - path = FS.analyzePath(Pointer_stringify(path)); - try { - FS.createObject(path.parentObject, path.name, properties, - mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR. - return 0; - } catch (e) { - return -1; - } + } + if (fmt === {{{ cDefine('S_IFCHR') }}} || fmt === {{{ cDefine('S_IFBLK') }}} || + fmt === {{{ cDefine('S_IFIFO') }}} || fmt === {{{ cDefine('S_IFSOCK') }}}) { + // not supported currently + ___setErrNo(ERRNO_CODES.EPERM); + return -1; + } + path = FS.analyzePath(path); + var properties = { contents: [], isFolder: false }; // S_IFDIR. + try { + FS.createObject(path.parentObject, path.name, properties, + mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR. + return 0; + } catch (e) { + return -1; } }, mkdir__deps: ['mknod'], mkdir: function(path, mode) { // int mkdir(const char *path, mode_t mode); // http://pubs.opengroup.org/onlinepubs/7908799/xsh/mkdir.html - return _mknod(path, 0x4000 | (mode & 0x180), 0); // S_IFDIR, S_IRUSR | S_IWUSR. + path = Pointer_stringify(path); + path = FS.analyzePath(path); + var properties = { contents: [], isFolder: true }; + try { + FS.createObject(path.parentObject, path.name, properties, + mode & 0x100, mode & 0x80); // S_IRUSR, S_IWUSR. + return 0; + } catch (e) { + return -1; + } }, mkfifo__deps: ['__setErrNo', '$ERRNO_CODES'], mkfifo: function(path, mode) { @@ -1082,10 +1100,13 @@ LibraryManager.library = { return -1; }, chmod__deps: ['$FS'], - chmod: function(path, mode) { + chmod: function(path, mode, dontResolveLastLink) { // int chmod(const char *path, mode_t mode); // http://pubs.opengroup.org/onlinepubs/7908799/xsh/chmod.html - var obj = FS.findObject(Pointer_stringify(path)); + // NOTE: dontResolveLastLink is a shortcut for lchmod(). It should never be + // used in client code. + path = typeof path !== 'string' ? Pointer_stringify(path) : path; + var obj = FS.findObject(path, dontResolveLastLink); if (obj === null) return -1; obj.read = mode & 0x100; // S_IRUSR. obj.write = mode & 0x80; // S_IWUSR. @@ -1096,15 +1117,16 @@ LibraryManager.library = { fchmod: function(fildes, mode) { // int fchmod(int fildes, mode_t mode); // http://pubs.opengroup.org/onlinepubs/7908799/xsh/fchmod.html - if (!FS.streams[fildes]) { + var stream = FS.streams[fildes]; + if (!stream) { ___setErrNo(ERRNO_CODES.EBADF); return -1; - } else { - var pathArray = intArrayFromString(FS.streams[fildes].path); - return _chmod(allocate(pathArray, 'i8', ALLOC_STACK), mode); } + return _chmod(stream.path, mode); + }, + lchmod: function(path, mode) { + return _chmod(path, mode, true); }, - lchmod: function() { throw 'TODO: lchmod' }, umask__deps: ['$FS'], umask: function(newMask) { @@ -2578,7 +2600,7 @@ LibraryManager.library = { if (maxx != sub) maxx = 0; } if (maxx) { - var argPtr = HEAP32[(varargs + argIndex)>>2]; + var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; argIndex += Runtime.getAlignSize('void*', null, true); fields++; for (var i = 0; i < maxx; i++) { @@ -6931,15 +6953,15 @@ LibraryManager.library = { // NOTE: These are fake, since we don't support the C device creation API. // http://www.kernel.org/doc/man-pages/online/pages/man3/minor.3.html makedev: function(maj, min) { - return 0; + return ((maj) << 8 | (min)); }, gnu_dev_makedev: 'makedev', major: function(dev) { - return 0; + return ((dev) >> 8); }, gnu_dev_major: 'major', minor: function(dev) { - return 0; + return ((dev) & 0xff); }, gnu_dev_minor: 'minor', diff --git a/src/library_browser.js b/src/library_browser.js index 7f79b2bd..0db2cc44 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -70,18 +70,6 @@ mergeInto(LibraryManager.library, { // (possibly modified) data. For example, a plugin might decompress a file, or it // might create some side data structure for use later (like an Image element, etc.). - function getMimetype(name) { - return { - 'jpg': 'image/jpeg', - 'jpeg': 'image/jpeg', - 'png': 'image/png', - 'bmp': 'image/bmp', - 'ogg': 'audio/ogg', - 'wav': 'audio/wav', - 'mp3': 'audio/mpeg' - }[name.substr(name.lastIndexOf('.')+1)]; - } - var imagePlugin = {}; imagePlugin['canHandle'] = function(name) { return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name); @@ -90,10 +78,10 @@ mergeInto(LibraryManager.library, { var b = null; if (Browser.hasBlobConstructor) { try { - b = new Blob([byteArray], { type: getMimetype(name) }); + b = new Blob([byteArray], { type: Browser.getMimetype(name) }); if (b.size !== byteArray.length) { // Safari bug #118630 // Safari's Blob can only take an ArrayBuffer - b = new Blob([(new Uint8Array(byteArray)).buffer], { type: getMimetype(name) }); + b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) }); } } catch(e) { Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder'); @@ -148,7 +136,7 @@ mergeInto(LibraryManager.library, { } if (Browser.hasBlobConstructor) { try { - var b = new Blob([byteArray], { type: getMimetype(name) }); + var b = new Blob([byteArray], { type: Browser.getMimetype(name) }); } catch(e) { return fail(); } @@ -391,6 +379,18 @@ mergeInto(LibraryManager.library, { }, timeout); }, + getMimetype: function(name) { + return { + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'png': 'image/png', + 'bmp': 'image/bmp', + 'ogg': 'audio/ogg', + 'wav': 'audio/wav', + 'mp3': 'audio/mpeg' + }[name.substr(name.lastIndexOf('.')+1)]; + }, + getUserMedia: function(func) { if(!window.getUserMedia) { window.getUserMedia = navigator['getUserMedia'] || @@ -399,6 +399,7 @@ mergeInto(LibraryManager.library, { window.getUserMedia(func); }, + getMovementX: function(event) { return event['movementX'] || event['mozMovementX'] || diff --git a/src/library_gl.js b/src/library_gl.js index 266bf223..d0f1a692 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1082,7 +1082,9 @@ var LibraryGL = { } {{{ makeSetValue('count', '0', 'len', 'i32') }}}; for (var i = 0; i < len; ++i) { - {{{ makeSetValue('shaders', 'i*4', 'GL.shaders[result[i]]', 'i32') }}}; + var id = GL.shaders.indexOf(result[i]); + assert(id !== -1, 'shader not bound to local id'); + {{{ makeSetValue('shaders', 'i*4', 'id', 'i32') }}}; } }, diff --git a/src/library_sdl.js b/src/library_sdl.js index 9287bd3e..7078aa9d 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -28,6 +28,7 @@ var LibrarySDL = { // The currently preloaded audio elements ready to be played audios: [null], + rwops: [null], // The currently playing audio element. There's only one music track. music: { audio: null, @@ -1228,9 +1229,24 @@ var LibrarySDL = { return flags; // We support JPG, PNG, TIF because browsers do }, - IMG_Load__deps: ['SDL_LockSurface'], - IMG_Load: function(filename) { - filename = FS.standardizePath(Pointer_stringify(filename)); + IMG_Load_RW__deps: ['SDL_LockSurface'], + IMG_Load_RW: function(rwopsID, freesrc) { + var rwops = SDL.rwops[rwopsID]; + + if (rwops === undefined) { + return 0; + } + + var filename = rwops.filename; + + if (filename === undefined) { + Runtime.warnOnce('Only file names that have been preloaded are supported for IMG_Load_RW.'); + // TODO. Support loading image data from embedded files, similarly to Mix_LoadWAV_RW + // TODO. Support loading image data from byte arrays, similarly to Mix_LoadWAV_RW + return 0; + } + + filename = FS.standardizePath(filename); if (filename[0] == '/') { // Convert the path to relative filename = filename.substr(1); @@ -1262,8 +1278,14 @@ var LibrarySDL = { return surf; }, SDL_LoadBMP: 'IMG_Load', - SDL_LoadBMP_RW: 'IMG_Load', - IMG_Load_RW: 'IMG_Load', + SDL_LoadBMP_RW: 'IMG_Load_RW', + IMG_Load__deps: ['IMG_Load_RW', 'SDL_RWFromFile', 'SDL_FreeRW'], + IMG_Load: function(filename){ + var rwops = _SDL_RWFromFile(filename); + var result = _IMG_Load_RW(rwops); + _SDL_FreeRW(rwops); + return result; + }, // SDL_Audio @@ -1399,22 +1421,62 @@ var LibrarySDL = { return 0; // error }, - Mix_LoadWAV_RW: function(filename, freesrc) { - filename = FS.standardizePath(Pointer_stringify(filename)); - var raw = Module["preloadedAudios"][filename]; - if (!raw) { - if (raw === null) Module.printErr('Trying to reuse preloaded audio, but freePreloadedMediaOnUse is set!'); - Runtime.warnOnce('Cannot find preloaded audio ' + filename); + Mix_LoadWAV_RW: function(rwopsID, freesrc) { + var rwops = SDL.rwops[rwopsID]; + + if (rwops === undefined) + return 0; + + var filename = ''; + var audio; + var bytes; + + if (rwops.filename !== undefined) { + filename = rwops.filename; + filename = FS.standardizePath(filename); + var raw = Module["preloadedAudios"][filename]; + if (!raw) { + if (raw === null) Module.printErr('Trying to reuse preloaded audio, but freePreloadedMediaOnUse is set!'); + Runtime.warnOnce('Cannot find preloaded audio ' + filename); + + // see if we can read the file-contents from the in-memory FS + var fileObject = FS.findObject(filename); + + if (fileObject === null) Module.printErr('Couldn\'t find file for: ' + filename); + + // We found the file. Load the contents + if (fileObject && !fileObject.isFolder && fileObject.read) { + bytes = fileObject.contents + } else { + return 0; + } + } + if (Module['freePreloadedMediaOnUse']) { + Module["preloadedAudios"][filename] = null; + } + audio = raw; + } + else if (rwops.bytes !== undefined) { + bytes = HEAPU8.subarray(rwops.bytes, rwops.bytes + rwops.count); + } + else { return 0; } - if (Module['freePreloadedMediaOnUse']) { - Module["preloadedAudios"][filename] = null; + + // Here, we didn't find a preloaded audio but we either were passed a filepath for + // which we loaded bytes, or we were passed some bytes + if (audio === undefined && bytes) { + var blob = new Blob([new Uint8Array(bytes)], {type: rwops.mimetype}); + var url = URL.createObjectURL(blob); + audio = new Audio(); + audio.src = url; } + var id = SDL.audios.length; // Keep the loaded audio in the audio arrays, ready for playback SDL.audios.push({ source: filename, - audio: raw + audio: audio }); return id; }, @@ -1574,8 +1636,14 @@ var LibrarySDL = { return SDL.setGetVolume(SDL.music, volume); }, - Mix_LoadMUS: 'Mix_LoadWAV_RW', Mix_LoadMUS_RW: 'Mix_LoadWAV_RW', + Mix_LoadMUS__deps: ['Mix_LoadMUS_RW', 'SDL_RWFromFile', 'SDL_FreeRW'], + Mix_LoadMUS: function(filename) { + var rwops = _SDL_RWFromFile(filename); + var result = _Mix_LoadMUS_RW(rwops); + _SDL_FreeRW(rwops); + return result; + }, Mix_FreeMusic: 'Mix_FreeChunk', @@ -1978,9 +2046,24 @@ var LibrarySDL = { // Misc SDL_InitSubSystem: function(flags) { return 0 }, + SDL_RWFromConstMem: function(mem, size) { + var id = SDL.rwops.length; // TODO: recycle ids when they are null + SDL.rwops.push({ bytes: mem, count: size }); + return id; + }, - SDL_RWFromFile: function(filename, mode) { - return filename; // XXX We just forward the filename + SDL_RWFromFile: function(_name, mode) { + var id = SDL.rwops.length; // TODO: recycle ids when they are null + var name = Pointer_stringify(_name) + SDL.rwops.push({ filename: name, mimetype: Browser.getMimetype(name) }); + return id; + }, + + SDL_FreeRW: function(rwopsID) { + SDL.rwops[rwopsID] = null; + while (SDL.rwops.length > 0 && SDL.rwops[SDL.rwops.length-1] === null) { + SDL.rwops.pop(); + } }, SDL_EnableUNICODE: function(on) { @@ -2007,7 +2090,6 @@ var LibrarySDL = { SDL_GetThreadID: function() { throw 'SDL_GetThreadID' }, SDL_ThreadID: function() { throw 'SDL_ThreadID' }, SDL_AllocRW: function() { throw 'SDL_AllocRW: TODO' }, - SDL_FreeRW: function() { throw 'SDL_FreeRW: TODO' }, SDL_CondBroadcast: function() { throw 'SDL_CondBroadcast: TODO' }, SDL_CondWaitTimeout: function() { throw 'SDL_CondWaitTimeout: TODO' }, SDL_WM_IconifyWindow: function() { throw 'SDL_WM_IconifyWindow TODO' }, diff --git a/src/parseTools.js b/src/parseTools.js index a5785e27..72166592 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -969,6 +969,12 @@ function generateStructTypes(type) { } ret[index++] = type; } else { + if (Runtime.isStructType(type) && type[1] === '0') { + // this is [0 x something]. When inside another structure like here, it must be at the end, + // and it does nothing + assert(i === typeData.fields.length-1); + return; + } add(Types.types[type]); } var more = (i+1 < typeData.fields.length ? typeData.flatIndexes[i+1] : typeData.flatSize) - (index - start); @@ -1694,7 +1700,7 @@ function makeGetSlabs(ptr, type, allowMultiple, unsigned) { } case 'float': return ['HEAPF32']; default: { - throw 'what, exactly, can we do for unknown types in TA2?! ' + new Error().stack; + throw 'what, exactly, can we do for unknown types in TA2?! ' + [new Error().stack, ptr, type, allowMultiple, unsigned]; } } } diff --git a/src/runtime.js b/src/runtime.js index 062066af..8c2c8f4d 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -214,7 +214,7 @@ var Runtime = { // and it adds no size assert(index === type.fields.length); size = 0; - alignSize = 0; + alignSize = type.alignSize || QUANTUM_SIZE; } else { size = Types.types[field].flatSize; alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize); @@ -228,12 +228,8 @@ var Runtime = { } if (type.packed) alignSize = 1; type.alignSize = Math.max(type.alignSize, alignSize); - if (size > 0) { - var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory - type.flatSize = curr + size; - } else { - curr = prev; - } + var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory + type.flatSize = curr + size; if (prev >= 0) { diffs.push(curr-prev); } diff --git a/src/settings.js b/src/settings.js index b33ea7b3..b7460cf2 100644 --- a/src/settings.js +++ b/src/settings.js @@ -243,6 +243,8 @@ var FS_LOG = 0; // Log all FS operations. This is especially helpful when you'r // a new project and want to see a list of file system operations happening // so that you can create a virtual file system with all of the required files. +var USE_OLD_FS = 1; // Switch to toggle the new / old FS code. Currently only used for testing purposes. + var USE_BSS = 1; // https://en.wikipedia.org/wiki/.bss // When enabled, 0-initialized globals are sorted to the end of the globals list, // enabling us to not explicitly store the initialization value for each 0 byte. @@ -412,7 +414,6 @@ var DEBUG_TAGS_SHOWING = []; // metadata // legalizer - // A cached set of defines, generated from the header files. This // lets the emscripten libc (library.js) see the right values. // If you the headers or use different ones, you will need to override diff --git a/system/include/libc/sys/stat.h b/system/include/libc/sys/stat.h index e2b20187..2285b294 100644 --- a/system/include/libc/sys/stat.h +++ b/system/include/libc/sys/stat.h @@ -179,7 +179,8 @@ struct stat64 #endif int _EXFUN(chmod,( const char *__path, mode_t __mode )); -int _EXFUN(fchmod,(int __fd, mode_t __mode)); +int _EXFUN(lchmod,( const char *__path, mode_t __mode )); +int _EXFUN(fchmod,(int __fd, mode_t __mode)); int _EXFUN(fstat,( int __fd, struct stat *__sbuf )); int _EXFUN(fstat64,( int __fd, struct stat64 *__sbuf )); /* XXX Emscripten */ int _EXFUN(mkdir,( const char *_path, mode_t __mode )); diff --git a/system/include/libc/sys/types.h b/system/include/libc/sys/types.h index c36f724c..fe5d552a 100644 --- a/system/include/libc/sys/types.h +++ b/system/include/libc/sys/types.h @@ -159,6 +159,10 @@ typedef __gid_t gid_t; typedef __id_t id_t ; /* can hold a uid_t or pid_t */ #endif +__int32_t major(__uint32_t _x); +__int32_t minor(__uint32_t _x); +dev_t makedev(__uint32_t _major, __uint32_t _minor); + #if defined(__XMK__) typedef signed char pid_t; #else diff --git a/tests/cases/i32_mem.ll b/tests/cases/i32_mem.ll new file mode 100644 index 00000000..e50014ca --- /dev/null +++ b/tests/cases/i32_mem.ll @@ -0,0 +1,23 @@ +; ModuleID = 'tests/hello_world.bc' +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128" +target triple = "i386-pc-linux-gnu" + +@.str = private unnamed_addr constant [15 x i8] c".%x.\0A\00", align 1 ; [#uses=1 type=[5 x i8]*] + +define i32 @main() { +entry: + %mem = alloca i32 + store i32 4279383126, i32* %mem + %i24 = bitcast i32* %mem to i24* + %load = load i24* %i24, align 4 + %load32 = zext i24 %load to i32 + %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32) + %val_24 = trunc i32 4041265344 to i24 + store i24 %val_24, i24* %i24, align 4 + %load32b = load i32* %mem, align 4 + %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32b) + ret i32 1 +} + +; [#uses=1] +declare i32 @printf(i8*, ...) diff --git a/tests/cases/i32_mem.txt b/tests/cases/i32_mem.txt new file mode 100644 index 00000000..683e58e2 --- /dev/null +++ b/tests/cases/i32_mem.txt @@ -0,0 +1,2 @@ +.123456. +.ffe0d0c0. diff --git a/tests/cases/zeroembedded.ll b/tests/cases/zeroembedded.ll index c1ffa212..6a4f6073 100644 --- a/tests/cases/zeroembedded.ll +++ b/tests/cases/zeroembedded.ll @@ -2,15 +2,22 @@ %struct.pypy_str = type { i32, [0 x i8] } %struct.pypy_strval = type { i32, [13 x i8] } +%union.pypy_array3_len0u = type { %struct.pypy_array3_len0 } +%struct.pypy_array3_len0 = type { i32, i32, [0 x i8] } + @pypy_g_strval = global %struct.pypy_strval { i32 13, [13 x i8] c"hello world\0A\00" } +@pypy_g_strval2 = global %struct.pypy_array3_len0 { i32 13, i32 111, [0 x i8] c"" } declare i32 @printf(i8*, ...) define i32 @main(i32 %argc, i8** nocapture %argv) { + %waka = alloca %struct.pypy_array3_len0 %1 = bitcast %struct.pypy_strval* @pypy_g_strval to %struct.pypy_str* %2 = getelementptr inbounds %struct.pypy_str* %1, i32 1 %3 = bitcast %struct.pypy_str* %2 to i8* call i32 (i8*, ...)* @printf(i8* %3) + %unneeded = bitcast %struct.pypy_str* %2 to %struct.pypy_array3_len0* + call i32 (i8*, ...)* @printf(i8* %3, %struct.pypy_array3_len0* %unneeded) ret i32 0 } diff --git a/tests/glgetattachedshaders.c b/tests/glgetattachedshaders.c new file mode 100644 index 00000000..303e0f92 --- /dev/null +++ b/tests/glgetattachedshaders.c @@ -0,0 +1,93 @@ +#include <GLES2/gl2.h> +#include <EGL/egl.h> +#include <stdio.h> +#include <stdlib.h> + +static void die(const char *msg) +{ + printf("%s\n", msg); + abort(); +} + +static void create_context(void) +{ + EGLint num_config; + EGLContext g_egl_ctx; + EGLDisplay g_egl_dpy; + EGLConfig g_config; + + static const EGLint attribute_list[] = + { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + + static const EGLint context_attributes[] = + { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (!g_egl_dpy) + die("failed to create display"); + + if (!eglInitialize(g_egl_dpy, NULL, NULL)) + die("failed to initialize egl"); + + if (!eglChooseConfig(g_egl_dpy, attribute_list, &g_config, 1, &num_config)) + die("failed to choose config"); + + g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, context_attributes); + if (!g_egl_ctx) + die("failed to create context"); +} + +int main(int argc, char *argv[]) +{ + unsigned i; + + create_context(); + + GLuint prog = glCreateProgram(); + if (glGetError()) + die("failed to create program"); + + GLuint vertex = glCreateShader(GL_VERTEX_SHADER); + if (glGetError()) + die("failed to create vertex shader"); + glAttachShader(prog, vertex); + + GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); + if (glGetError()) + die("failed to create fragment shader"); + glAttachShader(prog, fragment); + + GLuint shaders[2]; + GLsizei count; + + glGetAttachedShaders(prog, 2, &count, shaders); + if (glGetError()) + die("failed to get attached shaders"); + if (count != 2) + die("unknown number of shaders returned"); + if (shaders[0] == shaders[1]) + die("returned identical shaders"); + + for (i = 0; i < count; i++) + { + if (shaders[i] == 0) + die("returned 0"); + if (shaders[i] != vertex && shaders[i] != fragment) + die("unknown shader returned"); + } + + int result = 1; + REPORT_RESULT(); + + return 0; +} |