diff options
56 files changed, 10500 insertions, 308 deletions
@@ -136,5 +136,5 @@ a license to everyone to use it as detailed in LICENSE.) * Thomas Borsos <thomasborsos@gmail.com> * Ori Avtalion <ori@avtalion.name> * Guillaume Blanc <guillaumeblanc.sc@gmail.com> - - +* Usagi Ito <usagi@WonderRabbitProject.net> +* Camilo Polymeris <cpolymeris@gmail.com> @@ -1224,11 +1224,6 @@ try: value = value.replace('\\\\', '/').replace('\\', '/') # Convert backslash paths to forward slashes on Windows as well, since the JS compiler otherwise needs the backslashes escaped (alternative is to escape all input paths passing to JS, which feels clumsier to read) exec('shared.Settings.' + key + ' = ' + value) - # Apply effects from settings - if bind and shared.Settings.ASM_JS: - logging.warning('disabling asm.js since embind is not ready for it yet') - shared.Settings.ASM_JS = 0 - fastcomp = os.environ.get('EMCC_FAST_COMPILER') != '0' if fastcomp: @@ -1245,7 +1240,6 @@ try: assert shared.Settings.TARGET_ASMJS_UNKNOWN_EMSCRIPTEN == 1, 'fastcomp requires asmjs-unknown-emscripten' assert shared.Settings.USE_TYPED_ARRAYS == 2, 'fastcomp assumes ta2' assert not split_js_file, '--split-js is deprecated and not supported in fastcomp' - assert not bind, 'embind not supported in fastcomp yet' assert shared.Settings.MAX_SETJMPS == 20, 'changing MAX_SETJMPS is not supported in fastcomp yet' assert shared.Settings.INIT_HEAP == 0, 'HEAP_INIT is not supported in fastcomp (and should never be needed except for debugging)' assert not shared.Settings.RUNTIME_TYPE_INFO, 'RUNTIME_TYPE_INFO is not supported in fastcomp' @@ -1372,9 +1366,11 @@ try: for header in input_files: assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(input_files) + ' : ' + header args = newargs + shared.EMSDK_CXX_OPTS + input_files - logging.debug("running (for precompiled headers: " + call + ' ' + ' '.join(args)) + if specified_target: + args += ['-o', specified_target] + logging.debug("running (for precompiled headers): " + call + ' ' + ' '.join(args)) execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that) - sys.exit(1) + sys.exit(0) def get_bitcode_file(input_file): if final_suffix not in JS_CONTAINING_SUFFIXES: @@ -1731,7 +1727,7 @@ try: # with commaified code breaks late aggressive variable elimination) if shared.Settings.SIMPLIFY_IFS and (debug_level == 0 or profiling) and shared.Settings.OUTLINING_LIMIT == 0: js_optimizer_queue += ['simplifyIfs'] - if opt_level >= 3 and shared.Settings.PRECISE_F32: js_optimizer_queue += ['optimizeFrounds'] + if shared.Settings.PRECISE_F32: js_optimizer_queue += ['optimizeFrounds'] if closure and not shared.Settings.ASM_JS: flush_js_optimizer_queue() @@ -1750,7 +1746,7 @@ try: js_optimizer_extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT if opt_level >= 2 and (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3: - if shared.Settings.ASM_JS and opt_level >= 3 and shared.Settings.OUTLINING_LIMIT == 0: + if shared.Settings.ASM_JS and opt_level >= 3: js_optimizer_queue += ['registerizeHarder'] else: js_optimizer_queue += ['registerize'] diff --git a/emscripten-version.txt b/emscripten-version.txt index f488f67e..f9505a5c 100644 --- a/emscripten-version.txt +++ b/emscripten-version.txt @@ -1,2 +1,2 @@ -1.16.0 +1.17.0 diff --git a/emscripten.py b/emscripten.py index 94c6b61c..e2aef648 100755 --- a/emscripten.py +++ b/emscripten.py @@ -455,7 +455,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None, basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs] if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall') - if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE'] + if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_FT_MASK'] if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8'] if settings['ASSERTIONS']: basic_funcs += ['nullFunc'] @@ -584,7 +584,7 @@ var asm = (function(global, env, buffer) { var undef = 0; var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0; ''' + ''.join([''' - var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + [''' + var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ([' const f0 = Math_fround(0);\n'] if settings.get('PRECISE_F32') else []) + [''' // EMSCRIPTEN_START_FUNCS function stackAlloc(size) { size = size|0; @@ -611,21 +611,21 @@ function setThrew(threw, value) { } function copyTempFloat(ptr) { ptr = ptr|0; - HEAP8[tempDoublePtr] = HEAP8[ptr]; - HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0]; - HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0]; - HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0]; + HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; + HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; + HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; + HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; } function copyTempDouble(ptr) { ptr = ptr|0; - HEAP8[tempDoublePtr] = HEAP8[ptr]; - HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0]; - HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0]; - HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0]; - HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0]; - HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0]; - HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0]; - HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0]; + HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; + HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; + HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; + HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; + HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0]; + HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0]; + HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0]; + HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0]; } ''' + ''.join([''' function setTempRet%d(value) { @@ -754,6 +754,8 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None, backend_args += ['-emscripten-reserved-function-pointers=%d' % settings['RESERVED_FUNCTION_POINTERS']] if settings['ASSERTIONS'] > 0: backend_args += ['-emscripten-assertions=%d' % settings['ASSERTIONS']] + if settings['ALIASING_FUNCTION_POINTERS'] == 0: + backend_args += ['-emscripten-no-aliasing-function-pointers'] backend_args += ['-O' + str(settings['OPT_LEVEL'])] if DEBUG: logging.debug('emscript: llvm backend: ' + ' '.join(backend_args)) @@ -1009,7 +1011,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None, basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs] if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall') - if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE'] + if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_FT_MASK'] if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8'] if settings['ASSERTIONS']: if settings['ASSERTIONS'] >= 2: import difflib @@ -1080,8 +1082,9 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None, } ''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret)) + ffi_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings, ffi_arg=True) for i in range(1, len(sig))]) for i in range(settings['RESERVED_FUNCTION_POINTERS']): - jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings) + jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if ffi_args else '', ffi_args), sig[0], settings, ffi_result=True) function_tables_impls.append(''' function jsCall_%s_%s(%s) { %s @@ -1168,7 +1171,7 @@ var asm = (function(global, env, buffer) { var nan = +env.NaN, inf = +env.Infinity; var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0; ''' + ''.join([''' - var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + [''' + var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ([' const f0 = Math_fround(0);\n'] if settings.get('PRECISE_F32') else []) + [''' // EMSCRIPTEN_START_FUNCS function stackAlloc(size) { size = size|0; @@ -1195,21 +1198,21 @@ function setThrew(threw, value) { } function copyTempFloat(ptr) { ptr = ptr|0; - HEAP8[tempDoublePtr] = HEAP8[ptr]; - HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0]; - HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0]; - HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0]; + HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; + HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; + HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; + HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; } function copyTempDouble(ptr) { ptr = ptr|0; - HEAP8[tempDoublePtr] = HEAP8[ptr]; - HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0]; - HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0]; - HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0]; - HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0]; - HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0]; - HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0]; - HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0]; + HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0]; + HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0]; + HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0]; + HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0]; + HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0]; + HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0]; + HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0]; + HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0]; } function setTempRet0(value) { value = value|0; diff --git a/src/embind/embind.js b/src/embind/embind.js index 6ec07cd9..4821c77b 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -1,4 +1,4 @@ -/*global Module*/ +/*global Module, asm*/ /*global _malloc, _free, _memcpy*/ /*global FUNCTION_TABLE, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64*/ /*global readLatin1String*/ @@ -622,10 +622,6 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp var isClassMethodFunc = (argTypes[1] !== null && classType !== null); - if (!isClassMethodFunc && !FUNCTION_TABLE[cppTargetFunc]) { - throwBindingError('Global function '+humanName+' is not defined!'); - } - // Free functions with signature "void function()" do not need an invoker that marshalls between wire types. // TODO: This omits argument count check - enable only at -O3 or similar. // if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) { @@ -662,8 +658,8 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp } var dtorStack = needsDestructorStack ? "destructors" : "null"; - var args1 = ["throwBindingError", "classType", "invoker", "fn", "runDestructors", "retType", "classParam"]; - var args2 = [throwBindingError, classType, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; + var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"]; + var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]]; if (isClassMethodFunc) { invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n"; @@ -708,10 +704,50 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp return invokerFunction; } -function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker, fn) { +function requireFunction(signature, rawFunction) { + signature = readLatin1String(signature); + var fp; + // asm.js does not define FUNCTION_TABLE + if (typeof FUNCTION_TABLE === "undefined") { + // asm.js does not give direct access to the function tables, + // and thus we must go through the dynCall interface which allows + // calling into a signature's function table by pointer value. + // + // https://github.com/dherman/asm.js/issues/83 + // + // This has three main penalties: + // - dynCall is another function call in the path from JavaScript to C++. + // - JITs may not predict through the function table indirection at runtime. + // - Function.prototype.bind generally benchmarks poorly relative to + // function objects, but using 'arguments' would confound JITs and + // possibly allocate. + var dc = asm['dynCall_' + signature]; + if (dc === undefined) { + // We will always enter this branch if the signature + // contains 'f' and PRECISE_F32 is not enabled. + // + // Try again, replacing 'f' with 'd'. + dc = asm['dynCall_' + signature.replace(/f/g, 'd')]; + if (dc === undefined) { + throwBindingError("No dynCall invoker for signature: " + signature); + } + } + fp = dc.bind(undefined, rawFunction); + } else { + fp = FUNCTION_TABLE[rawFunction]; + } + + if (typeof fp !== "function") { + throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction); + } + return fp; +} + +function __embind_register_function(name, argCount, rawArgTypesAddr, signature, rawInvoker, fn) { var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr); name = readLatin1String(name); - rawInvoker = FUNCTION_TABLE[rawInvoker]; + + rawInvoker = requireFunction(signature, rawInvoker); exposePublicSymbol(name, function() { throwUnboundTypeError('Cannot call ' + name + ' due to unbound types', argTypes); @@ -726,11 +762,11 @@ function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker, var tupleRegistrations = {}; -function __embind_register_value_array(rawType, name, rawConstructor, rawDestructor) { +function __embind_register_value_array(rawType, name, constructorSignature, rawConstructor, destructorSignature, rawDestructor) { tupleRegistrations[rawType] = { name: readLatin1String(name), - rawConstructor: FUNCTION_TABLE[rawConstructor], - rawDestructor: FUNCTION_TABLE[rawDestructor], + rawConstructor: requireFunction(constructorSignature, rawConstructor), + rawDestructor: requireFunction(destructorSignature, rawDestructor), elements: [], }; } @@ -738,18 +774,20 @@ function __embind_register_value_array(rawType, name, rawConstructor, rawDestruc function __embind_register_value_array_element( rawTupleType, getterReturnType, + getterSignature, getter, getterContext, setterArgumentType, + setterSignature, setter, setterContext ) { tupleRegistrations[rawTupleType].elements.push({ getterReturnType: getterReturnType, - getter: FUNCTION_TABLE[getter], + getter: requireFunction(getterSignature, getter), getterContext: getterContext, setterArgumentType: setterArgumentType, - setter: FUNCTION_TABLE[setter], + setter: requireFunction(setterSignature, setter), setterContext: setterContext, }); } @@ -818,13 +856,15 @@ var structRegistrations = {}; function __embind_register_value_object( rawType, name, + constructorSignature, rawConstructor, + destructorSignature, rawDestructor ) { structRegistrations[rawType] = { name: readLatin1String(name), - rawConstructor: FUNCTION_TABLE[rawConstructor], - rawDestructor: FUNCTION_TABLE[rawDestructor], + rawConstructor: requireFunction(constructorSignature, rawConstructor), + rawDestructor: requireFunction(destructorSignature, rawDestructor), fields: [], }; } @@ -833,19 +873,21 @@ function __embind_register_value_object_field( structType, fieldName, getterReturnType, + getterSignature, getter, getterContext, setterArgumentType, + setterSignature, setter, setterContext ) { structRegistrations[structType].fields.push({ fieldName: readLatin1String(fieldName), getterReturnType: getterReturnType, - getter: FUNCTION_TABLE[getter], + getter: requireFunction(getterSignature, getter), getterContext: getterContext, setterArgumentType: setterArgumentType, - setter: FUNCTION_TABLE[setter], + setter: requireFunction(setterSignature, setter), setterContext: setterContext, }); } @@ -1324,17 +1366,25 @@ function __embind_register_class( rawPointerType, rawConstPointerType, baseClassRawType, + getActualTypeSignature, getActualType, + upcastSignature, upcast, + downcastSignature, downcast, name, + destructorSignature, rawDestructor ) { name = readLatin1String(name); - rawDestructor = FUNCTION_TABLE[rawDestructor]; - getActualType = FUNCTION_TABLE[getActualType]; - upcast = FUNCTION_TABLE[upcast]; - downcast = FUNCTION_TABLE[downcast]; + getActualType = requireFunction(getActualTypeSignature, getActualType); + if (upcast) { + upcast = requireFunction(upcastSignature, upcast); + } + if (downcast) { + downcast = requireFunction(downcastSignature, downcast); + } + rawDestructor = requireFunction(destructorSignature, rawDestructor); var legalFunctionName = makeLegalFunctionName(name); exposePublicSymbol(legalFunctionName, function() { @@ -1424,11 +1474,12 @@ function __embind_register_class_constructor( rawClassType, argCount, rawArgTypesAddr, + invokerSignature, invoker, rawConstructor ) { var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); - invoker = FUNCTION_TABLE[invoker]; + invoker = requireFunction(invokerSignature, invoker); whenDependentTypesAreResolved([], [rawClassType], function(classType) { classType = classType[0]; @@ -1474,9 +1525,12 @@ function downcastPointer(ptr, ptrClass, desiredClass) { if (undefined === desiredClass.baseClass) { return null; // no conversion } - // O(depth) stack space used - return desiredClass.downcast( - downcastPointer(ptr, ptrClass, desiredClass.baseClass)); + + var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass); + if (rv === null) { + return null; + } + return desiredClass.downcast(rv); } function upcastPointer(ptr, ptrClass, desiredClass) { @@ -1513,12 +1567,13 @@ function __embind_register_class_function( methodName, argCount, rawArgTypesAddr, // [ReturnType, ThisType, Args...] + invokerSignature, rawInvoker, context ) { var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); methodName = readLatin1String(methodName); - rawInvoker = FUNCTION_TABLE[rawInvoker]; + rawInvoker = requireFunction(invokerSignature, rawInvoker); whenDependentTypesAreResolved([], [rawClassType], function(classType) { classType = classType[0]; @@ -1564,12 +1619,13 @@ function __embind_register_class_class_function( methodName, argCount, rawArgTypesAddr, + invokerSignature, rawInvoker, fn ) { var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr); methodName = readLatin1String(methodName); - rawInvoker = FUNCTION_TABLE[rawInvoker]; + rawInvoker = requireFunction(invokerSignature, rawInvoker); whenDependentTypesAreResolved([], [rawClassType], function(classType) { classType = classType[0]; var humanName = classType.name + '.' + methodName; @@ -1609,14 +1665,16 @@ function __embind_register_class_property( classType, fieldName, getterReturnType, + getterSignature, getter, getterContext, setterArgumentType, + setterSignature, setter, setterContext ) { fieldName = readLatin1String(fieldName); - getter = FUNCTION_TABLE[getter]; + getter = requireFunction(getterSignature, getter); whenDependentTypesAreResolved([], [classType], function(classType) { classType = classType[0]; @@ -1654,7 +1712,7 @@ function __embind_register_class_property( }; if (setter) { - setter = FUNCTION_TABLE[setter]; + setter = requireFunction(setterSignature, setter); var setterArgumentType = types[1]; desc.set = function(v) { var ptr = validateThis(this, classType, humanName + ' setter'); @@ -1689,16 +1747,20 @@ function __embind_register_smart_ptr( rawPointeeType, name, sharingPolicy, + getPointeeSignature, rawGetPointee, + constructorSignature, rawConstructor, + shareSignature, rawShare, + destructorSignature, rawDestructor ) { name = readLatin1String(name); - rawGetPointee = FUNCTION_TABLE[rawGetPointee]; - rawConstructor = FUNCTION_TABLE[rawConstructor]; - rawShare = FUNCTION_TABLE[rawShare]; - rawDestructor = FUNCTION_TABLE[rawDestructor]; + rawGetPointee = requireFunction(getPointeeSignature, rawGetPointee); + rawConstructor = requireFunction(constructorSignature, rawConstructor); + rawShare = requireFunction(shareSignature, rawShare); + rawDestructor = requireFunction(destructorSignature, rawDestructor); whenDependentTypesAreResolved([rawType], [rawPointeeType], function(pointeeType) { pointeeType = pointeeType[0]; diff --git a/src/library.js b/src/library.js index c2830397..0d649258 100644 --- a/src/library.js +++ b/src/library.js @@ -762,12 +762,18 @@ LibraryManager.library = { // http://pubs.opengroup.org/onlinepubs/000095399/functions/crypt.html // TODO: Implement (probably compile from C). ___setErrNo(ERRNO_CODES.ENOSYS); +#if ASSERTIONS + Runtime.warnOnce('crypt() returning an error as we do not support it'); +#endif return 0; }, encrypt: function(block, edflag) { // void encrypt(char block[64], int edflag); // http://pubs.opengroup.org/onlinepubs/000095399/functions/encrypt.html // TODO: Implement (probably compile from C). +#if ASSERTIONS + Runtime.warnOnce('encrypt() returning an error as we do not support it'); +#endif ___setErrNo(ERRNO_CODES.ENOSYS); }, fpathconf__deps: ['__setErrNo', '$ERRNO_CODES'], @@ -940,6 +946,9 @@ LibraryManager.library = { // It is possible to implement this using two device streams, but pipes make // little sense in a single-threaded environment, so we do not support them. ___setErrNo(ERRNO_CODES.ENOSYS); +#if ASSERTIONS + Runtime.warnOnce('pipe() returning an error as we do not support them'); +#endif return -1; }, pread__deps: ['$FS', '__setErrNo', '$ERRNO_CODES'], @@ -1584,7 +1593,6 @@ LibraryManager.library = { return /^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?/.exec(text); }, - // TODO: Document. _scanString__deps: ['_getFloat'], _scanString: function(format, get, unget, varargs) { if (!__scanString.whiteSpace) { @@ -1726,6 +1734,7 @@ LibraryManager.library = { } var long_ = false; var half = false; + var quarter = false; var longLong = false; if (format[formatIndex] == 'l') { long_ = true; @@ -1737,6 +1746,10 @@ LibraryManager.library = { } else if (format[formatIndex] == 'h') { half = true; formatIndex++; + if (format[formatIndex] == 'h') { + quarter = true; + formatIndex++; + } } var type = format[formatIndex]; formatIndex++; @@ -1795,20 +1808,21 @@ LibraryManager.library = { var text = buffer.join(''); var argPtr = {{{ makeGetValue('varargs', 'argIndex', 'void*') }}}; argIndex += Runtime.getAlignSize('void*', null, true); + var base = 10; switch (type) { + case 'X': case 'x': + base = 16; case 'd': case 'u': case 'i': - if (half) { - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i16') }}}; + if (quarter) { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i8') }}}; + } else if (half) { + {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i16') }}}; } else if (longLong) { - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i64') }}}; + {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i64') }}}; } else { - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 10)', 'i32') }}}; + {{{ makeSetValue('argPtr', 0, 'parseInt(text, base)', 'i32') }}}; } break; - case 'X': - case 'x': - {{{ makeSetValue('argPtr', 0, 'parseInt(text, 16)', 'i32') }}}; - break; case 'F': case 'f': case 'E': @@ -5777,7 +5791,7 @@ LibraryManager.library = { pattern = pattern.replace(new RegExp('\\%'+pattern[i+1], 'g'), ''); } - var matches = new RegExp('^'+pattern).exec(Pointer_stringify(buf)) + var matches = new RegExp('^'+pattern, "i").exec(Pointer_stringify(buf)) // Module['print'](Pointer_stringify(buf)+ ' is matched by '+((new RegExp('^'+pattern)).source)+' into: '+JSON.stringify(matches)); function initDate() { @@ -6203,8 +6217,10 @@ LibraryManager.library = { raise__deps: ['$ERRNO_CODES', '__setErrNo'], raise: function(sig) { - // TODO: ___setErrNo(ERRNO_CODES.ENOSYS); +#if ASSERTIONS + Runtime.warnOnce('raise() returning an error as we do not support it'); +#endif return -1; }, diff --git a/src/library_browser.js b/src/library_browser.js index 4be7315e..44e8c473 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -196,41 +196,42 @@ mergeInto(LibraryManager.library, { // Canvas event setup var canvas = Module['canvas']; - - // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module - // Module['forcedAspectRatio'] = 4 / 3; - - canvas.requestPointerLock = canvas['requestPointerLock'] || - canvas['mozRequestPointerLock'] || - canvas['webkitRequestPointerLock'] || - canvas['msRequestPointerLock'] || - function(){}; - canvas.exitPointerLock = document['exitPointerLock'] || - document['mozExitPointerLock'] || - document['webkitExitPointerLock'] || - document['msExitPointerLock'] || - function(){}; // no-op if function does not exist - canvas.exitPointerLock = canvas.exitPointerLock.bind(document); - - function pointerLockChange() { - Browser.pointerLock = document['pointerLockElement'] === canvas || - document['mozPointerLockElement'] === canvas || - document['webkitPointerLockElement'] === canvas || - document['msPointerLockElement'] === canvas; - } + if (canvas) { + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + + canvas.requestPointerLock = canvas['requestPointerLock'] || + canvas['mozRequestPointerLock'] || + canvas['webkitRequestPointerLock'] || + canvas['msRequestPointerLock'] || + function(){}; + canvas.exitPointerLock = document['exitPointerLock'] || + document['mozExitPointerLock'] || + document['webkitExitPointerLock'] || + document['msExitPointerLock'] || + function(){}; // no-op if function does not exist + canvas.exitPointerLock = canvas.exitPointerLock.bind(document); + + function pointerLockChange() { + Browser.pointerLock = document['pointerLockElement'] === canvas || + document['mozPointerLockElement'] === canvas || + document['webkitPointerLockElement'] === canvas || + document['msPointerLockElement'] === canvas; + } - document.addEventListener('pointerlockchange', pointerLockChange, false); - document.addEventListener('mozpointerlockchange', pointerLockChange, false); - document.addEventListener('webkitpointerlockchange', pointerLockChange, false); - document.addEventListener('mspointerlockchange', pointerLockChange, false); + document.addEventListener('pointerlockchange', pointerLockChange, false); + document.addEventListener('mozpointerlockchange', pointerLockChange, false); + document.addEventListener('webkitpointerlockchange', pointerLockChange, false); + document.addEventListener('mspointerlockchange', pointerLockChange, false); - if (Module['elementPointerLock']) { - canvas.addEventListener("click", function(ev) { - if (!Browser.pointerLock && canvas.requestPointerLock) { - canvas.requestPointerLock(); - ev.preventDefault(); - } - }, false); + if (Module['elementPointerLock']) { + canvas.addEventListener("click", function(ev) { + if (!Browser.pointerLock && canvas.requestPointerLock) { + canvas.requestPointerLock(); + ev.preventDefault(); + } + }, false); + } } }, @@ -429,11 +430,13 @@ mergeInto(LibraryManager.library, { }); }, safeSetTimeout: function(func, timeout) { + Module['noExitRuntime'] = true; return setTimeout(function() { if (!ABORT) func(); }, timeout); }, safeSetInterval: function(func, timeout) { + Module['noExitRuntime'] = true; return setInterval(function() { if (!ABORT) func(); }, timeout); @@ -886,6 +889,8 @@ mergeInto(LibraryManager.library, { emscripten_set_main_loop: function(func, fps, simulateInfiniteLoop, arg) { Module['noExitRuntime'] = true; + assert(!Browser.mainLoop.scheduler, 'there can only be one main loop function at once: call emscripten_cancel_main_loop to cancel the previous one, if you want to'); + Browser.mainLoop.runner = function Browser_mainLoop_runner() { if (ABORT) return; if (Browser.mainLoop.queue.length > 0) { diff --git a/src/library_fs.js b/src/library_fs.js index d53210f9..5f7f1dea 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -26,7 +26,13 @@ mergeInto(LibraryManager.library, { // This is set to false when the runtime is initialized, allowing you // to modify the filesystem freely before run() is called. ignorePermissions: true, - + trackingDelegate: {}, + tracking: { + openFlags: { + READ: 1 << 0, + WRITE: 1 << 1 + } + }, ErrnoError: null, // set during init genericErrors: {}, @@ -713,6 +719,13 @@ mergeInto(LibraryManager.library, { throw new FS.ErrnoError(err); } } + try { + if (FS.trackingDelegate['willMovePath']) { + FS.trackingDelegate['willMovePath'](old_path, new_path); + } + } catch(e) { + console.log("FS.trackingDelegate['willMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); + } // remove the node from the lookup hash FS.hashRemoveNode(old_node); // do the underlying fs rename @@ -725,6 +738,11 @@ mergeInto(LibraryManager.library, { // changed its name) FS.hashAddNode(old_node); } + try { + if (FS.trackingDelegate['onMovePath']) FS.trackingDelegate['onMovePath'](old_path, new_path); + } catch(e) { + console.log("FS.trackingDelegate['onMovePath']('"+old_path+"', '"+new_path+"') threw an exception: " + e.message); + } }, rmdir: function(path) { var lookup = FS.lookupPath(path, { parent: true }); @@ -741,8 +759,20 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } + try { + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); + } parent.node_ops.rmdir(parent, name); FS.destroyNode(node); + try { + if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); + } catch(e) { + console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); + } }, readdir: function(path) { var lookup = FS.lookupPath(path, { follow: true }); @@ -769,8 +799,20 @@ mergeInto(LibraryManager.library, { if (FS.isMountpoint(node)) { throw new FS.ErrnoError(ERRNO_CODES.EBUSY); } + try { + if (FS.trackingDelegate['willDeletePath']) { + FS.trackingDelegate['willDeletePath'](path); + } + } catch(e) { + console.log("FS.trackingDelegate['willDeletePath']('"+path+"') threw an exception: " + e.message); + } parent.node_ops.unlink(parent, name); FS.destroyNode(node); + try { + if (FS.trackingDelegate['onDeletePath']) FS.trackingDelegate['onDeletePath'](path); + } catch(e) { + console.log("FS.trackingDelegate['onDeletePath']('"+path+"') threw an exception: " + e.message); + } }, readlink: function(path) { var lookup = FS.lookupPath(path); @@ -965,6 +1007,20 @@ mergeInto(LibraryManager.library, { Module['printErr']('read file: ' + path); } } + try { + if (FS.trackingDelegate['onOpenFile']) { + var trackingFlags = 0; + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_WRONLY') }}}) { + trackingFlags |= FS.tracking.openFlags.READ; + } + if ((flags & {{{ cDefine('O_ACCMODE') }}}) !== {{{ cDefine('O_RDONLY') }}}) { + trackingFlags |= FS.tracking.openFlags.WRITE; + } + FS.trackingDelegate['onOpenFile'](path, trackingFlags); + } + } catch(e) { + console.log("FS.trackingDelegate['onOpenFile']('"+path+"', flags) threw an exception: " + e.message); + } return stream; }, close: function(stream) { @@ -1034,6 +1090,11 @@ mergeInto(LibraryManager.library, { } var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn); if (!seeking) stream.position += bytesWritten; + try { + if (stream.path && FS.trackingDelegate['onWriteToFile']) FS.trackingDelegate['onWriteToFile'](stream.path); + } catch(e) { + console.log("FS.trackingDelegate['onWriteToFile']('"+path+"') threw an exception: " + e.message); + } return bytesWritten; }, allocate: function(stream, offset, length) { diff --git a/src/library_glfw.js b/src/library_glfw.js index 0b3fccd4..6d539326 100644 --- a/src/library_glfw.js +++ b/src/library_glfw.js @@ -211,7 +211,7 @@ var LibraryGLFW = { }, onMouseWheel: function(event) { - GLFW.wheelPos += Browser.getMouseWheelDelta(event); + GLFW.wheelPos -= Browser.getMouseWheelDelta(event); if (GLFW.mouseWheelFunc && event.target == Module["canvas"]) { Runtime.dynCall('vi', GLFW.mouseWheelFunc, [GLFW.wheelPos]); diff --git a/src/library_sdl.js b/src/library_sdl.js index eedb8c48..077f72eb 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -686,7 +686,6 @@ var LibrarySDL = { } else { code = SDL.keyCodes[event.keyCode] || event.keyCode; } - {{{ makeSetValue('SDL.keyboardState', 'code', 'down', 'i8') }}}; // TODO: lmeta, rmeta, numlock, capslock, KMOD_MODE, KMOD_RESERVED SDL.modState = ({{{ makeGetValue('SDL.keyboardState', '1248', 'i8') }}} ? 0x0040 | 0x0080 : 0) | // KMOD_LCTRL & KMOD_RCTRL diff --git a/src/parseTools.js b/src/parseTools.js index 4396abd9..0c413afa 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1168,15 +1168,10 @@ function getHeapOffset(offset, type, forceAsm) { var sz = Runtime.getNativeTypeSize(type); var shifts = Math.log(sz)/Math.LN2; offset = '(' + offset + ')'; - if (shifts != 0) { - if (CHECK_HEAP_ALIGN) { - return '((CHECK_ALIGN_' + sz + '(' + offset + '|0)|0)>>' + shifts + ')'; - } else { - return '(' + offset + '>>' + shifts + ')'; - } + if (CHECK_HEAP_ALIGN && shifts > 0) { + return '((CHECK_ALIGN_' + sz + '(' + offset + '|0)|0)>>' + shifts + ')'; } else { - // we need to guard against overflows here, HEAP[U]8 expects a guaranteed int - return isJSVar(offset) ? offset : '(' + offset + '|0)'; + return '(' + offset + '>>' + shifts + ')'; } } diff --git a/src/preamble.js b/src/preamble.js index 89ab5026..2aec94c6 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -186,17 +186,17 @@ function SAFE_HEAP_STORE(dest, value, bytes, isFloat) { #if SAFE_HEAP_LOG Module.print('SAFE_HEAP store: ' + [dest, value, bytes, isFloat]); #endif - assert(dest > 0, 'segmentation fault'); - assert(dest % bytes === 0, 'alignment error'); - assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)'); + if (dest <= 0) abort('segmentation fault storing ' + bytes + ' bytes to address ' + dest); + if (dest % bytes !== 0) abort('alignment error storing to address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes); + if (dest + bytes > Math.max(DYNAMICTOP, STATICTOP)) abort('segmentation fault, exceeded the top of the available heap when storing ' + bytes + ' bytes to address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + DYNAMICTOP); assert(DYNAMICTOP <= TOTAL_MEMORY); setValue(dest, value, getSafeHeapType(bytes, isFloat), 1); } function SAFE_HEAP_LOAD(dest, bytes, isFloat, unsigned) { - assert(dest > 0, 'segmentation fault'); - assert(dest % bytes === 0, 'alignment error'); - assert(dest < Math.max(DYNAMICTOP, STATICTOP), 'segmentation fault (high)'); + if (dest <= 0) abort('segmentation fault loading ' + bytes + ' bytes from address ' + dest); + if (dest % bytes !== 0) abort('alignment error loading from address ' + dest + ', which was expected to be aligned to a multiple of ' + bytes); + if (dest + bytes > Math.max(DYNAMICTOP, STATICTOP)) abort('segmentation fault, exceeded the top of the available heap when loading ' + bytes + ' bytes from address ' + dest + '. STATICTOP=' + STATICTOP + ', DYNAMICTOP=' + DYNAMICTOP); assert(DYNAMICTOP <= TOTAL_MEMORY); var type = getSafeHeapType(bytes, isFloat); var ret = getValue(dest, type, 1); @@ -207,6 +207,14 @@ function SAFE_HEAP_LOAD(dest, bytes, isFloat, unsigned) { return ret; } +function SAFE_FT_MASK(value, mask) { + var ret = value & mask; + if (ret !== value) { + abort('Function table mask error: function pointer is ' + value + ' which is masked by ' + mask + ', the likely cause of this is that the function pointer is being called by the wrong type.'); + } + return ret; +} + #endif #endif diff --git a/src/relooper/Relooper.cpp b/src/relooper/Relooper.cpp index ce9232d9..568dd381 100644 --- a/src/relooper/Relooper.cpp +++ b/src/relooper/Relooper.cpp @@ -17,6 +17,10 @@ typedef std::string ministring; #endif +// uncomment these out to get LLVM errs() debugging support +//#include <llvm/Support/raw_ostream.h> +//using namespace llvm; + template <class T, class U> static bool contains(const T& container, const U& contained) { return container.count(contained); } @@ -202,6 +206,7 @@ void Block::Render(bool InLoop) { if (Fused) { PrintDebug("Fusing Multiple to Simple\n"); Parent->Next = Parent->Next->Next; + Fused->UseSwitch = false; // TODO: emit switches here Fused->RenderLoopPrefix(); // When the Multiple has the same number of groups as we have branches, @@ -319,11 +324,7 @@ void MultipleShape::RenderLoopPrefix() { } } else { if (Labeled) { - if (UseSwitch) { - PrintIndented("L%d: ", Id); - } else { - PrintIndented("L%d: do {\n", Id); - } + PrintIndented("L%d: do {\n", Id); } else { PrintIndented("do {\n"); } diff --git a/src/settings.js b/src/settings.js index bf16290b..3289eace 100644 --- a/src/settings.js +++ b/src/settings.js @@ -124,13 +124,20 @@ var PRECISE_I32_MUL = 1; // If enabled, i32 multiplication is done with full pre var PRECISE_F32 = 0; // 0: Use JS numbers for floating-point values. These are 64-bit and do not model C++ // floats exactly, which are 32-bit. // 1: Model C++ floats precisely, using Math.fround, polyfilling when necessary. This - // can be slow if the polyfill is used on heavy float32 computation. + // can be slow if the polyfill is used on heavy float32 computation. See note on + // browser support below. // 2: Model C++ floats precisely using Math.fround if available in the JS engine, otherwise // use an empty polyfill. This will have much less of a speed penalty than using the full // polyfill in cases where engine support is not present. In addition, we can // remove the empty polyfill calls themselves on the client when generating html, // which should mean that this gives you the best of both worlds of 0 and 1, and is // therefore recommended. + // XXX Note: To optimize float32-using code, we use the 'const' keyword in the emitted + // code. This allows us to avoid unnecessary calls to Math.fround, which would + // slow down engines not yet supporting that function. 'const' is present in + // all modern browsers, including Firefox, Chrome and Safari, but in IE is only + // present in IE11 and above. Therefore if you need to support legacy versions of + // IE, you should not enable PRECISE_F32 1 or 2. var SIMD = 0; // Whether to emit SIMD code ( https://github.com/johnmccutchan/ecmascript_simd ) var CLOSURE_COMPILER = 0; // Whether closure compiling is being run on this output @@ -338,7 +345,7 @@ var EXPORTED_FUNCTIONS = ['_main', '_malloc']; var EXPORT_ALL = 0; // If true, we export all the symbols. Note that this does *not* affect LLVM, so it can // still eliminate functions as dead. This just exports them on the Module object. var EXPORT_BINDINGS = 0; // Export all bindings generator functions (prefixed with emscripten_bind_). This - // is necessary to use the bindings generator with asm.js + // is necessary to use the WebIDL binder or bindings generator with asm.js var RETAIN_COMPILER_SETTINGS = 0; // Remembers the values of these settings, and makes them accessible // through Runtime.getCompilerSetting and emscripten_get_compiler_setting. // To see what is retained, look for compilerSettings in the generated code. diff --git a/src/shell.html b/src/shell.html index 226f12b9..1e213024 100644 --- a/src/shell.html +++ b/src/shell.html @@ -1273,6 +1273,13 @@ } }; Module.setStatus('Downloading...'); + window.onerror = function() { + Module.setStatus('Exception thrown, see JavaScript console'); + spinnerElement.style.display = 'none'; + Module.setStatus = function(text) { + if (text) Module.printErr('[post-exception status] ' + text); + }; + }; </script> {{{ SCRIPT }}} </body> diff --git a/src/shell_minimal.html b/src/shell_minimal.html index 6f483719..7dd67929 100644 --- a/src/shell_minimal.html +++ b/src/shell_minimal.html @@ -129,6 +129,13 @@ } }; Module.setStatus('Downloading...'); + window.onerror = function() { + Module.setStatus('Exception thrown, see JavaScript console'); + spinnerElement.style.display = 'none'; + Module.setStatus = function(text) { + if (text) Module.printErr('[post-exception status] ' + text); + }; + }; </script> {{{ SCRIPT }}} </body> diff --git a/system/include/emscripten/bind.h b/system/include/emscripten/bind.h index 0699715c..eede0755 100644 --- a/system/include/emscripten/bind.h +++ b/system/include/emscripten/bind.h @@ -20,6 +20,8 @@ namespace emscripten { namespace internal { typedef long GenericEnumValue; + typedef void (*GenericFunction)(); + // Implemented in JavaScript. Don't call these directly. extern "C" { void _embind_fatal_error( @@ -70,21 +72,26 @@ namespace emscripten { const char* name, unsigned argCount, TYPEID argTypes[], + const char* signature, GenericFunction invoker, GenericFunction function); void _embind_register_value_array( TYPEID tupleType, const char* name, + const char* constructorSignature, GenericFunction constructor, + const char* destructorSignature, GenericFunction destructor); void _embind_register_value_array_element( TYPEID tupleType, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); @@ -93,46 +100,45 @@ namespace emscripten { void _embind_register_value_object( TYPEID structType, const char* fieldName, + const char* constructorSignature, GenericFunction constructor, + const char* destructorSignature, GenericFunction destructor); void _embind_register_value_object_field( TYPEID structType, const char* fieldName, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); void _embind_finalize_value_object(TYPEID structType); - void _embind_register_smart_ptr( - TYPEID pointerType, - TYPEID pointeeType, - const char* pointerName, - sharing_policy sharingPolicy, - GenericFunction getPointee, - GenericFunction constructor, - GenericFunction share, - GenericFunction destructor); - void _embind_register_class( TYPEID classType, TYPEID pointerType, TYPEID constPointerType, TYPEID baseClassType, + const char* getActualTypeSignature, GenericFunction getActualType, + const char* upcastSignature, GenericFunction upcast, + const char* downcastSignature, GenericFunction downcast, const char* className, + const char* destructorSignature, GenericFunction destructor); void _embind_register_class_constructor( TYPEID classType, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, GenericFunction constructor); @@ -141,6 +147,7 @@ namespace emscripten { const char* methodName, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, void* context); @@ -148,9 +155,11 @@ namespace emscripten { TYPEID classType, const char* fieldName, TYPEID getterReturnType, + const char* getterSignature, GenericFunction getter, void* getterContext, TYPEID setterArgumentType, + const char* setterSignature, GenericFunction setter, void* setterContext); @@ -159,6 +168,7 @@ namespace emscripten { const char* methodName, unsigned argCount, TYPEID argTypes[], + const char* invokerSignature, GenericFunction invoker, GenericFunction method); @@ -168,17 +178,25 @@ namespace emscripten { size_t size, bool isSigned); + void _embind_register_smart_ptr( + TYPEID pointerType, + TYPEID pointeeType, + const char* pointerName, + sharing_policy sharingPolicy, + const char* getPointeeSignature, + GenericFunction getPointee, + const char* constructorSignature, + GenericFunction constructor, + const char* shareSignature, + GenericFunction share, + const char* destructorSignature, + GenericFunction destructor); + void _embind_register_enum_value( TYPEID enumType, const char* valueName, GenericEnumValue value); - void _embind_register_interface( - TYPEID interfaceType, - const char* name, - GenericFunction constructor, - GenericFunction destructor); - void _embind_register_constant( const char* name, TYPEID constantType, @@ -291,6 +309,63 @@ namespace emscripten { } //////////////////////////////////////////////////////////////////////////////// + // SignatureCode, SignatureString + //////////////////////////////////////////////////////////////////////////////// + + namespace internal { + template<typename T> + struct SignatureCode { + static constexpr char get() { + return 'i'; + } + }; + + template<> + struct SignatureCode<void> { + static constexpr char get() { + return 'v'; + } + }; + + template<> + struct SignatureCode<float> { + static constexpr char get() { + return 'f'; + } + }; + + template<> + struct SignatureCode<double> { + static constexpr char get() { + return 'd'; + } + }; + + template<typename... T> + struct SignatureString; + + template<> + struct SignatureString<> { + char c = 0; + }; + + template<typename First, typename... Rest> + struct SignatureString<First, Rest...> { + constexpr SignatureString() + : c(SignatureCode<First>::get()) + {} + char c; + SignatureString<Rest...> rest; + }; + + template<typename Return, typename... Args> + const char* getSignature(Return (*)(Args...)) { + static constexpr SignatureString<Return, Args...> sig; + return &sig.c; + } + } + + //////////////////////////////////////////////////////////////////////////////// // FUNCTIONS //////////////////////////////////////////////////////////////////////////////// @@ -302,11 +377,13 @@ namespace emscripten { void function(const char* name, ReturnType (*fn)(Args...), Policies...) { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoker = &Invoker<ReturnType, Args...>::invoke; _embind_register_function( name, args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), reinterpret_cast<GenericFunction>(fn)); } @@ -542,11 +619,16 @@ namespace emscripten { value_array(const char* name) { using namespace internal; + + auto constructor = &raw_constructor<ClassType>; + auto destructor = &raw_destructor<ClassType>; _embind_register_value_array( TypeID<ClassType>::get(), name, - reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(constructor), + reinterpret_cast<GenericFunction>(constructor), + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); } ~value_array() { @@ -557,17 +639,21 @@ namespace emscripten { template<typename InstanceType, typename ElementType> value_array& element(ElementType InstanceType::*field) { using namespace internal; + + auto getter = &MemberAccess<InstanceType, ElementType> + ::template getWire<ClassType>; + auto setter = &MemberAccess<InstanceType, ElementType> + ::template setWire<ClassType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, ElementType> - ::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, ElementType> - ::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -577,13 +663,19 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto g = &GP::template get<ClassType>; + auto s = &SP::template set<ClassType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(g), + reinterpret_cast<GenericFunction>(g), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(s), + reinterpret_cast<GenericFunction>(s), SP::getContext(setter)); return *this; } @@ -593,13 +685,18 @@ namespace emscripten { using namespace internal; ClassType* null = 0; typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType; + auto getter = &internal::get_by_index<ClassType, ElementType>; + auto setter = &internal::set_by_index<ClassType, ElementType>; + _embind_register_value_array_element( TypeID<ClassType>::get(), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), reinterpret_cast<void*>(Index), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), reinterpret_cast<void*>(Index)); return *this; } @@ -616,11 +713,17 @@ namespace emscripten { value_object(const char* name) { using namespace internal; + + auto ctor = &raw_constructor<ClassType>; + auto dtor = &raw_destructor<ClassType>; + _embind_register_value_object( TypeID<ClassType>::get(), name, - reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>), - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(ctor), + reinterpret_cast<GenericFunction>(ctor), + getSignature(dtor), + reinterpret_cast<GenericFunction>(dtor)); } ~value_object() { @@ -630,18 +733,22 @@ namespace emscripten { template<typename InstanceType, typename FieldType> value_object& field(const char* fieldName, FieldType InstanceType::*field) { using namespace internal; + + auto getter = &MemberAccess<InstanceType, FieldType> + ::template getWire<ClassType>; + auto setter = &MemberAccess<InstanceType, FieldType> + ::template setWire<ClassType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, FieldType> - ::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>( - &MemberAccess<InstanceType, FieldType> - ::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -655,14 +762,20 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto g = &GP::template get<ClassType>; + auto s = &SP::template set<ClassType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(g), + reinterpret_cast<GenericFunction>(g), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(s), + reinterpret_cast<GenericFunction>(s), SP::getContext(setter)); return *this; } @@ -672,14 +785,20 @@ namespace emscripten { using namespace internal; ClassType* null = 0; typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType; + + auto getter = &internal::get_by_index<ClassType, ElementType>; + auto setter = &internal::set_by_index<ClassType, ElementType>; + _embind_register_value_object_field( TypeID<ClassType>::get(), fieldName, TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), reinterpret_cast<void*>(Index), TypeID<ElementType>::get(), - reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), reinterpret_cast<void*>(Index)); return *this; } @@ -832,13 +951,19 @@ namespace emscripten { } template<typename ClassType> - static internal::GenericFunction getUpcaster() { - return reinterpret_cast<internal::GenericFunction>(&convertPointer<ClassType, BaseClass>); + using Upcaster = BaseClass* (*)(ClassType*); + + template<typename ClassType> + using Downcaster = ClassType* (*)(BaseClass*); + + template<typename ClassType> + static Upcaster<ClassType> getUpcaster() { + return &convertPointer<ClassType, BaseClass>; } template<typename ClassType> - static internal::GenericFunction getDowncaster() { - return reinterpret_cast<internal::GenericFunction>(&convertPointer<BaseClass, ClassType>); + static Downcaster<ClassType> getDowncaster() { + return &convertPointer<BaseClass, ClassType>; } template<typename From, typename To> @@ -877,16 +1002,25 @@ namespace emscripten { BaseSpecifier::template verify<ClassType>(); + auto _getActualType = &getActualType<ClassType>; + auto upcast = BaseSpecifier::template getUpcaster<ClassType>(); + auto downcast = BaseSpecifier::template getDowncaster<ClassType>(); + auto destructor = &raw_destructor<ClassType>; + _embind_register_class( TypeID<ClassType>::get(), TypeID<AllowedRawPointer<ClassType>>::get(), TypeID<AllowedRawPointer<const ClassType>>::get(), BaseSpecifier::get(), - reinterpret_cast<GenericFunction>(&getActualType<ClassType>), - BaseSpecifier::template getUpcaster<ClassType>(), - BaseSpecifier::template getDowncaster<ClassType>(), + getSignature(_getActualType), + reinterpret_cast<GenericFunction>(_getActualType), + getSignature(upcast), + reinterpret_cast<GenericFunction>(upcast), + getSignature(downcast), + reinterpret_cast<GenericFunction>(downcast), name, - reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>)); + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); } template<typename PointerType> @@ -898,15 +1032,24 @@ namespace emscripten { static_assert(std::is_same<ClassType, typename std::remove_cv<PointeeType>::type>::value, "smart pointer must point to this class"); + auto get = &PointerTrait::get; + auto construct_null = &PointerTrait::construct_null; + auto share = &PointerTrait::share; + auto destructor = &raw_destructor<PointerType>; + _embind_register_smart_ptr( TypeID<PointerType>::get(), TypeID<PointeeType>::get(), name, PointerTrait::get_sharing_policy(), - reinterpret_cast<GenericFunction>(&PointerTrait::get), - reinterpret_cast<GenericFunction>(&PointerTrait::construct_null), - reinterpret_cast<GenericFunction>(&PointerTrait::share), - reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>)); + getSignature(get), + reinterpret_cast<GenericFunction>(get), + getSignature(construct_null), + reinterpret_cast<GenericFunction>(construct_null), + getSignature(share), + reinterpret_cast<GenericFunction>(share), + getSignature(destructor), + reinterpret_cast<GenericFunction>(destructor)); return *this; }; @@ -923,11 +1066,13 @@ namespace emscripten { // TODO: allows all raw pointers... policies need a rethink typename WithPolicies<allow_raw_pointers, Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoke = &Invoker<ReturnType, Args...>::invoke; _embind_register_class_constructor( TypeID<ClassType>::get(), args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), reinterpret_cast<GenericFunction>(factory)); return *this; } @@ -939,11 +1084,13 @@ namespace emscripten { smart_ptr<SmartPtr>(smartPtrName); typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args; + auto invoke = &Invoker<SmartPtr, Args...>::invoke; _embind_register_class_constructor( TypeID<ClassType>::get(), args.count, args.types, - reinterpret_cast<GenericFunction>(&Invoker<SmartPtr, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), reinterpret_cast<GenericFunction>(factory)); return *this; } @@ -966,13 +1113,16 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) const { using namespace internal; + auto invoker = &MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke; + typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), getContext(memberFunction)); return *this; } @@ -981,13 +1131,16 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) const { using namespace internal; + auto invoker = &MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke; + typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke), + getSignature(invoker), + reinterpret_cast<GenericFunction>(invoker), getContext(memberFunction)); return *this; } @@ -997,12 +1150,14 @@ namespace emscripten { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args; + auto invoke = &FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke; _embind_register_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<GenericFunction>(invoke), getContext(function)); return *this; } @@ -1010,15 +1165,18 @@ namespace emscripten { template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type> EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, const FieldType ClassType::*field) const { using namespace internal; - + + auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), 0, 0, + 0, 0); return *this; } @@ -1027,14 +1185,18 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, FieldType ClassType::*field) const { using namespace internal; + auto getter = &MemberAccess<ClassType, FieldType>::template getWire<ClassType>; + auto setter = &MemberAccess<ClassType, FieldType>::template setWire<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>), + getSignature(getter), + reinterpret_cast<GenericFunction>(getter), getContext(field), TypeID<FieldType>::get(), - reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template setWire<ClassType>), + getSignature(setter), + reinterpret_cast<GenericFunction>(setter), getContext(field)); return *this; } @@ -1043,14 +1205,17 @@ namespace emscripten { EMSCRIPTEN_ALWAYS_INLINE const class_& property(const char* fieldName, Getter getter) const { using namespace internal; typedef GetterPolicy<Getter> GP; + auto gter = &GP::template get<ClassType>; _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(gter), + reinterpret_cast<GenericFunction>(gter), GP::getContext(getter), 0, 0, + 0, 0); return *this; } @@ -1060,14 +1225,20 @@ namespace emscripten { using namespace internal; typedef GetterPolicy<Getter> GP; typedef SetterPolicy<Setter> SP; + + auto gter = &GP::template get<ClassType>; + auto ster = &SP::template set<ClassType>; + _embind_register_class_property( TypeID<ClassType>::get(), fieldName, TypeID<typename GP::ReturnType>::get(), - reinterpret_cast<GenericFunction>(&GP::template get<ClassType>), + getSignature(gter), + reinterpret_cast<GenericFunction>(gter), GP::getContext(getter), TypeID<typename SP::ArgumentType>::get(), - reinterpret_cast<GenericFunction>(&SP::template set<ClassType>), + getSignature(ster), + reinterpret_cast<GenericFunction>(ster), SP::getContext(setter)); return *this; } @@ -1077,12 +1248,14 @@ namespace emscripten { using namespace internal; typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args; + auto invoke = &internal::Invoker<ReturnType, Args...>::invoke; _embind_register_class_class_function( TypeID<ClassType>::get(), methodName, args.count, args.types, - reinterpret_cast<internal::GenericFunction>(&internal::Invoker<ReturnType, Args...>::invoke), + getSignature(invoke), + reinterpret_cast<internal::GenericFunction>(invoke), reinterpret_cast<GenericFunction>(classMethod)); return *this; } diff --git a/system/include/emscripten/emscripten.h b/system/include/emscripten/emscripten.h index 73836018..66017a8d 100644 --- a/system/include/emscripten/emscripten.h +++ b/system/include/emscripten/emscripten.h @@ -121,7 +121,11 @@ extern void emscripten_async_load_script(const char *script, void (*onload)(void * * If you want your main loop function to receive a void* * argument, use emscripten_set_main_loop_arg. - + * + * There can be only *one* main loop function at a time. You + * can cancel the current one and set another, if you want to + * change it. + * * @simulate_infinite_loop If true, this function will throw an * exception in order to stop execution of the caller. This * will lead to the main loop being entered instead of code @@ -248,7 +252,7 @@ void emscripten_get_canvas_size(int *width, int *height, int *isFullscreen); double emscripten_get_now(void); #else #include <time.h> -double emscripten_get_now(void) { +static inline double emscripten_get_now(void) { return (1000*clock())/(double)CLOCKS_PER_SEC; } #endif diff --git a/system/lib/embind/bind.cpp b/system/lib/embind/bind.cpp index 37918050..16c24a91 100644 --- a/system/lib/embind/bind.cpp +++ b/system/lib/embind/bind.cpp @@ -78,6 +78,7 @@ EMSCRIPTEN_BINDINGS(native_and_builtin_types) { register_float<double>("double");
_embind_register_std_string(TypeID<std::string>::get(), "std::string");
+ _embind_register_std_string(TypeID<std::basic_string<unsigned char> >::get(), "std::basic_string<unsigned char>");
_embind_register_std_wstring(TypeID<std::wstring>::get(), sizeof(wchar_t), "std::wstring");
_embind_register_emval(TypeID<val>::get(), "emscripten::val");
_embind_register_memory_view(TypeID<memory_view>::get(), "emscripten::memory_view");
diff --git a/tests/cases/redundantswitch_fastcomp.ll b/tests/cases/redundantswitch_fastcomp.ll new file mode 100644 index 00000000..5b797ac8 --- /dev/null +++ b/tests/cases/redundantswitch_fastcomp.ll @@ -0,0 +1,28 @@ +target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:128-n32-S128" +target triple = "asmjs-unknown-emscripten" + +@.str = private constant [18 x i8] c"hello, world: %d\0A\00", align 1 + +declare i32 @printf(i8*, ...) + +define linkonce_odr i32 @main() align 2 { +entry: + %temp32 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 5) + switch i32 %temp32, label %mid1 [ + i32 1000, label %mid1 + i32 1001, label %mid2 + i32 2000, label %finish + ] + +mid1: + br label %finish + +mid2: + br label %finish + +finish: ; preds = %555 + %last = phi i32 [0, %entry], [1, %mid1], [2, %mid2] + %a333c = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([18 x i8]* @.str, i32 0, i32 0), i32 %last) + ret i32 0 +} + diff --git a/tests/cases/redundantswitch_fastcomp.txt b/tests/cases/redundantswitch_fastcomp.txt new file mode 100644 index 00000000..72084b0c --- /dev/null +++ b/tests/cases/redundantswitch_fastcomp.txt @@ -0,0 +1,2 @@ +hello, world: 5 +hello, world: 1 diff --git a/tests/core/test_polymorph.in b/tests/core/test_polymorph.in index 1f24a1aa..af07dc05 100644 --- a/tests/core/test_polymorph.in +++ b/tests/core/test_polymorph.in @@ -16,6 +16,8 @@ struct Child : Parent { struct Other { int one() { return 11; } int two() { return 22; } + virtual int three() { return 33; } + virtual int four() { return 44; } }; int main() { @@ -24,10 +26,16 @@ int main() { printf("*%d,%d,%d,%d*\n", x->getit(), y->getit(), x->implme(), y->implme()); Other *o = new Other; + int (Other::*Ls)() = &Other::one; printf("*%d*\n", (o->*(Ls))()); Ls = &Other::two; printf("*%d*\n", (o->*(Ls))()); + Ls = &Other::three; + printf("*%d*\n", (o->*(Ls))()); + Ls = &Other::four; + printf("*%d*\n", (o->*(Ls))()); + return 0; } diff --git a/tests/core/test_polymorph.out b/tests/core/test_polymorph.out index 0d036bf0..5163ea8e 100644 --- a/tests/core/test_polymorph.out +++ b/tests/core/test_polymorph.out @@ -1,3 +1,5 @@ *11,74,32,1012* *11* -*22*
\ No newline at end of file +*22* +*33* +*44* diff --git a/tests/core/test_sscanf_hex.in b/tests/core/test_sscanf_hex.in index d8175e82..a05eb890 100644 --- a/tests/core/test_sscanf_hex.in +++ b/tests/core/test_sscanf_hex.in @@ -1,7 +1,27 @@ -#include "stdio.h" +#include <stdio.h> +#include <string> +#include <cstdlib> -int main() { +int main() +{ unsigned int a, b; sscanf("0x12AB 12AB", "%x %x", &a, &b); printf("%d %d\n", a, b); + + std::string hexstr("0102037F00FF"); + const char * cstr = hexstr.c_str(); + int len = hexstr.length() / 2; + char * tmp_data = new char[len]; + for(int i = 0; i < len; i++) + { + sscanf(cstr, "%2hhx", &tmp_data[i]); + cstr += 2 * sizeof(char); + } + + for (int j = 0; j < len; j++) + printf("%i, ", tmp_data[j]); + printf("\n"); + delete[] tmp_data; } + + diff --git a/tests/core/test_sscanf_hex.out b/tests/core/test_sscanf_hex.out index ac855044..6e7f66aa 100644 --- a/tests/core/test_sscanf_hex.out +++ b/tests/core/test_sscanf_hex.out @@ -1 +1,2 @@ -4779 4779
\ No newline at end of file +4779 4779 +1, 2, 3, 127, 0, -1, diff --git a/tests/core/test_strptime_tm.in b/tests/core/test_strptime_tm.in index 93cdb1d5..2cccfa55 100644 --- a/tests/core/test_strptime_tm.in +++ b/tests/core/test_strptime_tm.in @@ -2,6 +2,15 @@ #include <stdio.h> #include <string.h> +void ReadMonth(const char *month) +{ + tm value = {0}; + if(strptime(month, "%b", &value)) + { + printf("%s: %d\n", month, value.tm_mon); + } +} + int main() { struct tm tm; char *ptr = strptime("17410105012000", "%H%M%S%d%m%Y", &tm); @@ -24,4 +33,26 @@ int main() { : "ERR")))))), tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); + + printf("\n"); + + ReadMonth("jan"); + ReadMonth("january"); + ReadMonth("feb"); + ReadMonth("february"); + ReadMonth("march"); + ReadMonth("mar"); + ReadMonth("april"); + ReadMonth("may"); + ReadMonth("may"); + ReadMonth("june"); + ReadMonth("jul"); + ReadMonth("august"); + ReadMonth("september"); + ReadMonth("oct"); + ReadMonth("nov"); + ReadMonth("november"); + ReadMonth("december"); + + return 0; } diff --git a/tests/core/test_strptime_tm.out b/tests/core/test_strptime_tm.out index 32c321f7..c241cbdd 100644 --- a/tests/core/test_strptime_tm.out +++ b/tests/core/test_strptime_tm.out @@ -1 +1,18 @@ -OK: Wed, 1/5/2000 17:41:1
\ No newline at end of file +OK: Wed, 1/5/2000 17:41:1 +jan: 0 +january: 0 +feb: 1 +february: 1 +march: 2 +mar: 2 +april: 3 +may: 4 +may: 4 +june: 5 +jul: 6 +august: 7 +september: 8 +oct: 9 +nov: 10 +november: 10 +december: 11 diff --git a/tests/embind/embind.test.js b/tests/embind/embind.test.js index 6bba4de0..3ded811a 100644 --- a/tests/embind/embind.test.js +++ b/tests/embind/embind.test.js @@ -442,6 +442,21 @@ module({ var e = cm.emval_test_take_and_return_std_string((new Int8Array([65, 66, 67, 68])).buffer); assert.equal('ABCD', e); }); + + test("can pass Uint8Array to std::basic_string<unsigned char>", function() { + var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char(new Uint8Array([65, 66, 67, 68])); + assert.equal('ABCD', e); + }); + + test("can pass Int8Array to std::basic_string<unsigned char>", function() { + var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char(new Int8Array([65, 66, 67, 68])); + assert.equal('ABCD', e); + }); + + test("can pass ArrayBuffer to std::basic_string<unsigned char>", function() { + var e = cm.emval_test_take_and_return_std_basic_string_unsigned_char((new Int8Array([65, 66, 67, 68])).buffer); + assert.equal('ABCD', e); + }); test("non-ascii wstrings", function() { var expected = String.fromCharCode(10) + diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index 1b835751..5a83903a 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -109,6 +109,10 @@ std::string emval_test_take_and_return_std_string_const_ref(const std::string& s return str; } +std::basic_string<unsigned char> emval_test_take_and_return_std_basic_string_unsigned_char(std::basic_string<unsigned char> str) { + return str; +} + std::wstring take_and_return_std_wstring(std::wstring str) { return str; } @@ -1446,6 +1450,7 @@ EMSCRIPTEN_BINDINGS(tests) { //function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star); function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string); function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref); + function("emval_test_take_and_return_std_basic_string_unsigned_char", &emval_test_take_and_return_std_basic_string_unsigned_char); function("take_and_return_std_wstring", &take_and_return_std_wstring); //function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct); diff --git a/tests/embind/imvu_test_adapter.js b/tests/embind/imvu_test_adapter.js index 421e86c8..93eeab37 100644 --- a/tests/embind/imvu_test_adapter.js +++ b/tests/embind/imvu_test_adapter.js @@ -586,12 +586,6 @@ function module(ignore, func) { throw new AssertionError("Don't call setInterval in tests. Use fakes.");
};
- if (typeof process !== 'undefined') {
- process.nextTick = function() {
- throw new AssertionError("Don't call process.nextTick in tests. Use fakes.");
- };
- }
-
Math.random = function() {
throw new AssertionError("Don't call Math.random in tests. Use fakes.");
};
diff --git a/tests/fs/test_trackingdelegate.c b/tests/fs/test_trackingdelegate.c new file mode 100644 index 00000000..6cdece72 --- /dev/null +++ b/tests/fs/test_trackingdelegate.c @@ -0,0 +1,39 @@ +#include <stdio.h> +#include <stdlib.h> +#include <emscripten.h> + +int main() { + + EM_ASM( + FS.trackingDelegate['willMovePath'] = function(oldpath, newpath) { + Module.print('About to move "' + oldpath + '" to "' + newpath + '"'); + }; + FS.trackingDelegate['onMovePath'] = function(oldpath, newpath) { + Module.print('Moved "' + oldpath + '" to "' + newpath + '"'); + }; + FS.trackingDelegate['willDeletePath'] = function(path) { + Module.print('About to delete "' + path + '"'); + }; + FS.trackingDelegate['onDeletePath'] = function(path) { + Module.print('Deleted "' + path + '"'); + }; + FS.trackingDelegate['onOpenFile'] = function(path, flags) { + Module.print('Opened "' + path + '" with flags ' + flags); + }; + FS.trackingDelegate['onWriteToFile'] = function(path) { + Module.print('Wrote to file "' + path + '"'); + }; + ); + + FILE *file; + file = fopen("/file.txt", "w"); + fputs("hello!", file); + fclose(file); + rename("/file.txt", "/renamed.txt"); + file = fopen("/renamed.txt", "r"); + char str[256] = {}; + fgets(str, 255, file); + printf("File read returned '%s'\n", str); + fclose(file); + remove("/renamed.txt"); +} diff --git a/tests/fs/test_trackingdelegate.out b/tests/fs/test_trackingdelegate.out new file mode 100644 index 00000000..b3c941c2 --- /dev/null +++ b/tests/fs/test_trackingdelegate.out @@ -0,0 +1,9 @@ +Opened "/file.txt" with flags 2 +Wrote to file "/file.txt" +About to move "/file.txt" to "/renamed.txt" +Moved "/file.txt" to "/renamed.txt" +Opened "/renamed.txt" with flags 1 +File read returned 'hello!' +Wrote to file "/dev/tty" +About to delete "/renamed.txt" +Deleted "/renamed.txt" diff --git a/tests/fs/test_writeFile.cc b/tests/fs/test_writeFile.cc new file mode 100644 index 00000000..31466b8e --- /dev/null +++ b/tests/fs/test_writeFile.cc @@ -0,0 +1,43 @@ +// https://github.com/kripken/emscripten/issues/2334 + +#include <fstream> +#include <iostream> +#include <string> + +#include <emscripten/emscripten.h> + +int main() +{ + EM_ASM( + FS.writeFile("testfile", "a=1\nb=2\nc=3"); + ); + + std::ifstream file("testfile"); + + while(!file.eof() && !file.fail()) + { + std::string line; + getline(file, line); + std::string name; + + std::cout << "read " << line << std::endl; + + size_t equalsPos = 1; + + size_t notSpace = line.find_first_not_of(" \t", equalsPos); + + if(notSpace != std::string::npos && notSpace != equalsPos) + { + line.erase(std::remove_if(line.begin(), line.begin() + notSpace, isspace), line.end()); + + equalsPos = line.find('='); + } + + if(equalsPos == std::string::npos) + continue; + + name = line.substr(0, equalsPos); + } + + return 0; +} diff --git a/tests/fs/test_writeFile.out b/tests/fs/test_writeFile.out new file mode 100644 index 00000000..16e520be --- /dev/null +++ b/tests/fs/test_writeFile.out @@ -0,0 +1,3 @@ +read a=1 +read b=2 +read c=3 diff --git a/tests/fuzz/20.cpp b/tests/fuzz/20.cpp new file mode 100644 index 00000000..619ac697 --- /dev/null +++ b/tests/fuzz/20.cpp @@ -0,0 +1,977 @@ +/* + * This is a RANDOMLY GENERATED PROGRAM. + * + * Generator: csmith 2.2.0 + * Git version: bf42ffd + * Options: --no-volatiles --no-packed-struct --no-math64 --lang-cpp + * Seed: 2354592696 + */ + +#include "csmith.h" + + +static long __undefined; + +/* --- Struct/Union Declarations --- */ +/* --- GLOBAL VARIABLES --- */ +static int32_t g_8[4] = {(-1L),(-1L),(-1L),(-1L)}; +static int32_t g_10 = 0x095A9796L; +static uint8_t g_14 = 0xBBL; +static uint16_t g_68 = 65535UL; +static int32_t g_89 = (-1L); +static int32_t *g_88 = &g_89; +static const uint16_t g_95 = 65535UL; +static const uint16_t *g_94 = &g_95; +static int32_t g_101[1][2][5] = {{{0L,0L,0L,0L,0L},{(-1L),(-1L),(-1L),(-1L),(-1L)}}}; +static uint16_t g_168 = 65535UL; +static int16_t g_175 = (-10L); +static uint8_t g_177 = 1UL; +static int8_t g_208 = 1L; +static int8_t *g_207[4] = {&g_208,&g_208,&g_208,&g_208}; +static int32_t g_263 = (-4L); +static int32_t **g_311 = NULL; +static int32_t ***g_310 = &g_311; +static uint32_t g_324[4][1][5] = {{{0xA3D675C6L,0x497B3AE0L,0xA3D675C6L,1UL,1UL}},{{0xA3D675C6L,0x497B3AE0L,0xA3D675C6L,1UL,1UL}},{{0xA3D675C6L,0x497B3AE0L,0xA3D675C6L,1UL,1UL}},{{0xA3D675C6L,0x497B3AE0L,0xA3D675C6L,1UL,1UL}}}; +static uint32_t g_369 = 0x38F403BAL; +static int16_t **g_435 = NULL; +static const int32_t g_490 = (-1L); +static int8_t g_532 = 0xE9L; +static uint32_t g_534 = 0UL; +static int32_t g_679[1][5] = {{0x6C6BABE0L,0x6C6BABE0L,0x6C6BABE0L,0x6C6BABE0L,0x6C6BABE0L}}; +static int16_t *g_691 = &g_175; +static int32_t *g_735 = NULL; +static uint16_t g_813 = 1UL; +static int16_t g_906 = 0x50BEL; +static uint32_t g_912 = 0x1175B058L; +static int8_t * const *g_1027 = &g_207[2]; +static int8_t * const **g_1026[5] = {&g_1027,&g_1027,&g_1027,&g_1027,&g_1027}; +static int8_t **g_1029 = &g_207[1]; +static int8_t ***g_1028 = &g_1029; +static uint8_t g_1098 = 251UL; +static int16_t ***g_1103 = &g_435; +static int16_t ****g_1102 = &g_1103; +static uint32_t *g_1251 = &g_534; +static uint32_t **g_1250 = &g_1251; +static uint32_t ***g_1249 = &g_1250; +static int8_t ***g_1452 = &g_1029; +static uint8_t *g_1457 = &g_1098; +static uint8_t **g_1456 = &g_1457; +static int32_t *g_1463 = &g_10; +static int32_t **g_1486 = &g_1463; +static int32_t **g_1487 = &g_735; +static int16_t **** const *g_1490 = &g_1102; +static int16_t **** const **g_1489 = &g_1490; +static int32_t g_1555 = 0x5CD64271L; +static uint16_t g_1566 = 65531UL; +static int8_t g_1611 = (-1L); +static int16_t g_1671[8] = {(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L)}; +static uint32_t g_1726 = 2UL; +static uint32_t g_1781[2][2] = {{1UL,1UL},{1UL,1UL}}; +static int8_t ****g_1806 = &g_1028; +static int8_t *****g_1805[10][1][3] = {{{NULL,NULL,NULL}},{{&g_1806,&g_1806,&g_1806}},{{NULL,NULL,NULL}},{{&g_1806,&g_1806,&g_1806}},{{NULL,NULL,NULL}},{{&g_1806,&g_1806,&g_1806}},{{NULL,NULL,NULL}},{{&g_1806,&g_1806,&g_1806}},{{NULL,NULL,NULL}},{{&g_1806,&g_1806,&g_1806}}}; +static uint32_t g_1846[4] = {1UL,1UL,1UL,1UL}; +static const uint32_t g_1878[9][9][3] = {{{18446744073709551609UL,0x41FAE503L,5UL},{4UL,0xB45FB625L,0xBA90DCABL},{0x7859E91FL,18446744073709551609UL,5UL},{0UL,0x87F82538L,1UL},{0xDE88EC26L,0x8F3A2F9CL,0xC2B3141CL},{0x8C538065L,0x49C63EC0L,0x44D75A98L},{18446744073709551615UL,18446744073709551615UL,0x3EA8F13BL},{0x44D75A98L,18446744073709551614UL,18446744073709551606UL},{0xB1C843BDL,18446744073709551615UL,0x384A1D15L}},{{0x5E837D39L,0x49C63EC0L,0x5E837D39L},{18446744073709551615UL,0x8F3A2F9CL,18446744073709551609UL},{0UL,0x87F82538L,0xB7463E48L},{0x384A1D15L,18446744073709551609UL,0x97952306L},{0x03506829L,0xB45FB625L,0xB011D241L},{0x384A1D15L,0x41FAE503L,0x7859E91FL},{0UL,0x0EC69127L,0xD92197E9L},{18446744073709551615UL,5UL,0x06FB78C1L},{0x5E837D39L,0xD81B3B3EL,0UL}},{{0xB1C843BDL,0x5098CCB1L,1UL},{0x44D75A98L,0x37E638FAL,0UL},{18446744073709551615UL,0x06FB78C1L,0x06FB78C1L},{0x8C538065L,18446744073709551607UL,0xD92197E9L},{0xDE88EC26L,0xC2B3141CL,0x7859E91FL},{0UL,0xA98FC4D4L,0xB011D241L},{0x7859E91FL,0xB1C843BDL,0x97952306L},{4UL,0xA98FC4D4L,0xB7463E48L},{18446744073709551609UL,0xC2B3141CL,18446744073709551609UL}},{{0UL,18446744073709551607UL,0x5E837D39L},{5UL,0x06FB78C1L,0x384A1D15L},{0xB7463E48L,0x37E638FAL,18446744073709551606UL},{0x8F3A2F9CL,0x5098CCB1L,0x3EA8F13BL},{0xB7463E48L,0xD81B3B3EL,0x44D75A98L},{5UL,5UL,0xC2B3141CL},{0UL,0x0EC69127L,1UL},{18446744073709551609UL,0x41FAE503L,5UL},{4UL,0xB45FB625L,0xBA90DCABL}},{{0x7859E91FL,18446744073709551609UL,5UL},{0UL,0x87F82538L,1UL},{0xDE88EC26L,0x8F3A2F9CL,0xC2B3141CL},{0x8C538065L,0x49C63EC0L,0x44D75A98L},{18446744073709551615UL,18446744073709551615UL,0x3EA8F13BL},{0x44D75A98L,18446744073709551614UL,18446744073709551606UL},{0xB1C843BDL,18446744073709551615UL,0x384A1D15L},{0x5E837D39L,0x49C63EC0L,0x5E837D39L},{18446744073709551615UL,0x8F3A2F9CL,18446744073709551609UL}},{{0UL,0x87F82538L,0xB7463E48L},{0x384A1D15L,18446744073709551609UL,0x97952306L},{0x03506829L,0xB45FB625L,0UL},{18446744073709551609UL,5UL,0x8F3A2F9CL},{0x44D75A98L,0x36765C43L,0xD909217BL},{0x06FB78C1L,0x7859E91FL,0x97952306L},{0xB513056EL,0x0EC69127L,0x44D75A98L},{0x41FAE503L,0xB1C843BDL,0x384A1D15L},{0x03506829L,0xDAD1FA39L,0x44D75A98L}},{{0xDE88EC26L,0x97952306L,0x97952306L},{0xB011D241L,0UL,0xD909217BL},{0x3EA8F13BL,0x5098CCB1L,0x8F3A2F9CL},{0x8C538065L,0x87F82538L,0UL},{0x8F3A2F9CL,0x41FAE503L,1UL},{0x685D1A38L,0x87F82538L,0x5E837D39L},{0x6768B2D9L,0x5098CCB1L,0x6768B2D9L},{1UL,0UL,0xB513056EL},{0x7859E91FL,0x97952306L,18446744073709551609UL}},{{0x5E837D39L,0xDAD1FA39L,0xBA90DCABL},{18446744073709551615UL,0xB1C843BDL,18446744073709551615UL},{0x5E837D39L,0x0EC69127L,0x03506829L},{0x7859E91FL,0x7859E91FL,0x5098CCB1L},{1UL,0x36765C43L,18446744073709551606UL},{0x6768B2D9L,5UL,0x7859E91FL},{0x685D1A38L,18446744073709551614UL,0xB7463E48L},{0x8F3A2F9CL,0x6768B2D9L,0x7859E91FL},{0x8C538065L,0x2406F886L,18446744073709551606UL}},{{0x3EA8F13BL,18446744073709551615UL,0x5098CCB1L},{0xB011D241L,0xB45FB625L,0x03506829L},{0xDE88EC26L,0x06FB78C1L,18446744073709551615UL},{0x03506829L,0xD81B3B3EL,0xBA90DCABL},{0x41FAE503L,0x06FB78C1L,18446744073709551609UL},{0xB513056EL,0xB45FB625L,0xB513056EL},{0x06FB78C1L,18446744073709551615UL,0x6768B2D9L},{0x44D75A98L,0x2406F886L,0x5E837D39L},{18446744073709551609UL,0x6768B2D9L,1UL}}}; +static uint32_t * const g_1962 = &g_324[3][0][0]; +static uint32_t * const *g_1961 = &g_1962; +static uint16_t g_2002 = 4UL; +static int16_t ** const * const g_2016 = &g_435; +static int16_t ** const * const *g_2015 = &g_2016; +static int16_t ** const * const **g_2014 = &g_2015; +static int16_t ** const * const **g_2018 = &g_2015; + + +/* --- FORWARD DECLARATIONS --- */ +static uint32_t func_1(void); +static int32_t func_5(int32_t p_6, uint32_t p_7); +static uint8_t func_39(uint32_t p_40, int32_t * p_41, int32_t p_42); +static const int32_t * func_52(int32_t p_53, uint8_t p_54, uint32_t p_55, int16_t p_56, uint8_t p_57); +static int32_t * func_64(uint16_t p_65, int32_t * p_66); +static int32_t * func_69(int8_t p_70); +static uint8_t func_76(uint8_t p_77, const int32_t * const p_78, int32_t * p_79); +static int32_t * const func_80(int32_t * p_81); +static int32_t * func_82(int32_t p_83, uint16_t p_84, int32_t * p_85); +static int32_t func_92(const uint16_t * p_93); + + +/* --- FUNCTIONS --- */ +/* ------------------------------------------ */ +/* + * reads : g_8 g_14 g_10 g_68 g_88 g_912 g_94 g_95 g_735 g_101 g_1250 g_1251 g_534 g_679 g_1029 g_207 g_208 g_691 g_1463 g_168 g_1457 g_1098 g_1249 g_1489 g_263 g_89 g_175 g_813 g_1566 g_1027 g_1611 g_532 g_1726 g_1028 g_1781 g_1490 g_1102 g_1103 g_435 g_177 g_1555 g_906 g_324 g_1671 g_1487 g_1961 g_1456 g_2002 g_1486 g_1962 g_2014 + * writes: g_14 g_68 g_10 g_735 g_88 g_168 g_534 g_1028 g_1452 g_101 g_1456 g_175 g_1486 g_1487 g_263 g_89 g_94 g_813 g_208 g_1555 g_1566 g_532 g_1098 g_1611 g_1726 g_1102 g_1781 g_435 g_177 g_207 g_2002 g_1463 g_324 g_2014 g_2018 + */ +static uint32_t func_1(void) +{ /* block id: 0 */ + uint32_t l_4 = 0x20398070L; + int32_t l_17 = (-1L); + int32_t *l_18 = &l_17; + int32_t *l_21[4][2][10] = {{{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,&g_8[0],NULL,NULL,&g_8[3],&g_8[0],&g_8[3],NULL,NULL}},{{NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},{NULL,NULL,&g_8[1],NULL,NULL,NULL,&g_8[1],NULL,NULL,NULL}},{{NULL,NULL,NULL,&g_8[3],NULL,NULL,NULL,&g_8[3],NULL,NULL},{NULL,&g_8[3],&g_8[0],&g_8[3],NULL,NULL,&g_8[0],NULL,NULL,&g_8[3]}},{{NULL,&g_8[3],NULL,NULL,NULL,&g_8[3],NULL,NULL,NULL,&g_8[3]},{NULL,NULL,&g_8[1],NULL,NULL,NULL,&g_8[1],NULL,NULL,NULL}}}; + uint16_t l_1947 = 0UL; + uint8_t l_1950 = 8UL; + int32_t l_1952 = (-7L); + int32_t l_1967 = 0x2594DE78L; + int8_t *l_1968 = &g_208; + uint32_t l_1969 = 0xA55E1FD4L; + uint32_t **l_1994 = &g_1251; + int32_t l_2003 = 0xD7936716L; + int16_t *****l_2013 = &g_1102; + int16_t ******l_2012 = &l_2013; + int16_t ** const * const ***l_2017[9]; + int i, j, k; + for (i = 0; i < 9; i++) + l_2017[i] = NULL; + (*l_18) = (safe_rshift_func_uint16_t_u_s((((l_4 , (func_5(g_8[0], l_4) ^ 0x4D07DDBFL)) , 5UL) , (((((+func_5(g_8[0], (l_17 |= ((g_8[0] || (l_4 , l_4)) , g_8[2])))) >= g_10) , 0xA6C2E3A4L) , 0L) < 4294967295UL)), g_8[0])); + if (func_5(((*l_18) = (safe_lshift_func_uint8_t_u_u(func_5(g_14, (*l_18)), 3))), (&g_10 == &g_10))) + { /* block id: 8 */ + uint32_t l_30 = 0x8A7E8B7DL; + int16_t l_49 = (-1L); + const int16_t l_50 = 0xB00FL; + int32_t *l_51 = &l_17; + uint16_t *l_1948 = NULL; + uint16_t *l_1949 = NULL; + uint16_t *l_1951[1][8][1] = {{{NULL},{&g_168},{NULL},{&g_168},{NULL},{&g_168},{NULL},{&g_168}}}; + int8_t l_1953 = (-4L); + uint32_t l_1954[8][4][2] = {{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}},{{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL},{0xF7B7F389L,0x84E19BCBL},{0x2B89271DL,0x84E19BCBL}}}; + int i, j, k; + (*l_18) = ((((NULL != &g_8[1]) <= ((((safe_add_func_uint8_t_u_u(((*g_1457) = func_5(((safe_rshift_func_int8_t_s_u((((++g_14) , (-8L)) , (((safe_rshift_func_int16_t_s_s(l_30, 1)) <= (func_5((((safe_mul_func_uint16_t_u_u((l_1952 = (l_30 , ((safe_rshift_func_uint16_t_u_s((safe_rshift_func_uint16_t_u_u((l_1950 ^= (+((safe_mod_func_uint8_t_u_u(func_39((((((func_5((func_5(g_10, func_5((((((((safe_add_func_uint8_t_u_u(((safe_mul_func_uint16_t_u_u((NULL != &g_10), (safe_lshift_func_int8_t_s_s(g_10, 1)))) ^ 0x8CD8B12AL), g_8[0])) <= l_30) != 0x7384L) < (*l_18)) , (*l_18)) , l_49) <= (*l_18)), g_14)) & l_50), g_8[0]) >= 0x8DL) , &g_8[3]) != NULL) , (int32_t*) NULL) != NULL), l_51, g_8[1]), g_906)) < l_1947))), 10)), (*l_51))) , 0xE604L))), 0x59B6L)) ^ (*l_51)) | (*l_51)), (*l_51)) | (*l_51))) <= (*l_51))), g_324[3][0][0])) , (*l_18)), (*l_18))), l_1953)) , (*l_18)) | (*l_18)) & (*l_51))) | (*l_51)) , l_1954[3][2][0]); + return g_1671[5]; + } + else + { /* block id: 885 */ + int8_t *l_1963 = &g_1611; + int32_t l_1966 = 1L; + const int32_t *l_1971 = &g_89; + const int32_t **l_1970 = &l_1971; + uint16_t *l_1991[2]; + uint32_t *l_1999 = &l_1969; + int i; + for (i = 0; i < 2; i++) + l_1991[i] = &g_813; + (*g_1487) = &l_17; + (*l_1970) = func_52((safe_div_func_uint8_t_u_u((safe_mul_func_uint16_t_u_u(((*g_1249) != (*g_1249)), (safe_rshift_func_uint16_t_u_s(((*l_18) & (NULL != (*g_1490))), (NULL == g_1961))))), ((((**g_1028) = l_1963) != ((safe_lshift_func_uint8_t_u_s(((l_1967 |= l_1966) <= 0x55L), 5)) , l_1968)) ^ l_1969))), (*l_18), l_1966, (*l_18), (**g_1456)); + l_18 = ((*g_1486) = ((((safe_div_func_uint16_t_u_u((safe_div_func_int8_t_s_s(((safe_rshift_func_uint8_t_u_s((safe_rshift_func_uint16_t_u_u(((safe_mul_func_uint8_t_u_u(0UL, ((g_2002 = ((*g_1251) < (safe_lshift_func_int8_t_s_u(((((safe_div_func_int32_t_s_s((((safe_sub_func_uint16_t_u_u((safe_rshift_func_uint8_t_u_u((*l_18), 1)), (g_168 &= (safe_unary_minus_func_int8_t_s(0x8AL))))) < ((safe_mul_func_int16_t_s_s((l_1994 != ((safe_mul_func_int8_t_s_s(((***g_1028) |= (*l_18)), (safe_add_func_uint32_t_u_u((++(*l_1999)), (**g_1487))))) , (*g_1249))), g_2002)) , 0xCDA1EE90L)) && (*l_18)), 0x4EED3296L)) && (**g_1456)) <= (*l_18)) >= 255UL), l_2003)))) , (*l_18)))) == (*l_18)), 8)), 2)) <= (*l_18)), 1L)), 8L)) != 0xEBL) , (*g_1457)) , (int32_t*) NULL)); + } + (**g_1487) = ((safe_add_func_int8_t_s_s(l_1952, (((**g_1456) | (-8L)) <= (safe_mul_func_int16_t_s_s(l_1952, (l_17 , (0x039BF18DL > ((safe_sub_func_int32_t_s_s((safe_add_func_uint16_t_u_u(65535UL, ((((*l_2012) = &g_1102) != (g_2018 = (g_2014 = ((((*g_1962) = 3UL) , (**g_1456)) , g_2014)))) <= l_17))), (*g_735))) <= l_1967)))))))) || l_1952); + return (*g_1962); +} + + +/* ------------------------------------------ */ +/* + * reads : g_14 + * writes: g_14 + */ +static int32_t func_5(int32_t p_6, uint32_t p_7) +{ /* block id: 1 */ + int32_t *l_9[2]; + uint32_t l_11 = 1UL; + int i; + for (i = 0; i < 2; i++) + l_9[i] = &g_10; + l_11--; + ++g_14; + return p_6; +} + + +/* ------------------------------------------ */ +/* + * reads : g_8 g_10 g_68 g_14 g_88 g_912 g_94 g_813 g_95 g_735 g_101 g_1250 g_1251 g_534 g_679 g_1029 g_207 g_208 g_691 g_1463 g_168 g_1457 g_1098 g_1249 g_1489 g_175 g_89 g_1566 g_1027 g_1611 g_532 g_1726 g_1028 g_1781 g_1490 g_1102 g_1103 g_435 g_177 g_1555 g_263 + * writes: g_68 g_10 g_735 g_88 g_168 g_14 g_534 g_1028 g_1452 g_101 g_1456 g_175 g_1486 g_1487 g_263 g_89 g_94 g_813 g_208 g_1555 g_1566 g_532 g_1098 g_1611 g_1726 g_1102 g_1781 g_435 g_177 + */ +static uint8_t func_39(uint32_t p_40, int32_t * p_41, int32_t p_42) +{ /* block id: 10 */ + uint16_t *l_67 = &g_68; + int32_t l_75 = 1L; + int32_t **l_1491[8] = {&g_735,NULL,&g_735,NULL,&g_735,NULL,&g_735,NULL}; + int32_t *l_1492 = NULL; + const int32_t *l_1680 = &g_10; + const int32_t **l_1679 = &l_1680; + int32_t *l_1681 = &g_101[0][1][2]; + uint32_t l_1738 = 0x915B1875L; + int16_t ****l_1759 = &g_1103; + int8_t l_1785[2][10][5] = {{{0L,0xD1L,0L,0x10L,0xA1L},{(-4L),0xF8L,0L,(-9L),9L},{(-1L),0L,0x19L,0L,0x60L},{0x10L,(-7L),0L,9L,(-1L)},{0x20L,0L,0L,(-4L),0x12L},{1L,(-1L),(-1L),0x89L,0x10L},{0x1CL,0x60L,0x33L,0L,0x8FL},{0x7BL,0x4EL,9L,0L,1L},{0x83L,0x8FL,(-1L),0x89L,0x3AL},{0L,(-4L),(-1L),(-4L),0L}},{{(-1L),(-9L),(-7L),9L,(-8L)},{0x8FL,0x46L,0xD1L,0L,(-4L)},{0xD1L,(-7L),0x60L,(-9L),(-8L)},{(-1L),0L,1L,0x10L,0L},{(-8L),0x50L,(-7L),0x46L,0x3AL},{0x33L,1L,0x3AL,0xC2L,1L},{(-1L),0x20L,0x10L,(-1L),0x8FL},{(-1L),(-1L),(-1L),0x20L,0x10L},{0x33L,9L,0x12L,0L,0x12L},{(-8L),(-8L),1L,0x3AL,(-1L)}}}; + uint32_t l_1789 = 18446744073709551613UL; + uint32_t **l_1796 = &g_1251; + int16_t l_1841 = 0x47E8L; + int8_t ****l_1864 = &g_1452; + const uint32_t *l_1877 = &g_1878[1][2][2]; + const uint32_t **l_1876 = &l_1877; + int16_t l_1889 = 0x474EL; + int32_t l_1941 = 0x901B980BL; + uint8_t *l_1944 = &g_14; + uint8_t *l_1945 = NULL; + uint8_t *l_1946 = &g_177; + int i, j, k; +lbl_1744: + (*l_1679) = func_52(g_8[0], g_8[0], ((g_10 , (func_5((g_8[0] && ((safe_lshift_func_int8_t_s_u(func_5((safe_mul_func_int8_t_s_s(((l_1492 = func_64(((*l_67) |= 0xAE56L), func_69(((safe_add_func_uint16_t_u_u((g_168 = ((safe_sub_func_int32_t_s_s(l_75, ((l_75 , func_76(g_14, func_80(func_82((g_10 = (safe_rshift_func_uint8_t_u_u(g_8[2], 6))), g_14, g_88)), &g_101[0][1][1])) < 5UL))) || p_40)), l_75)) >= (*g_94))))) != NULL), 0x19L)), p_40), p_40)) <= p_40)), p_40) , (*g_1251))) < p_42), p_40, p_40); + if (((p_41 = &p_42) != (l_1681 = &g_89))) + { /* block id: 749 */ + uint16_t l_1684[9][7] = {{0x4D1DL,1UL,0x075BL,0xEA90L,0xD27EL,65526UL,0x9259L},{0x075BL,0xFB9BL,0x10FFL,65526UL,65530UL,6UL,65526UL},{1UL,0x9259L,0xD27EL,0UL,65526UL,0UL,0xD27EL},{6UL,6UL,0x10FFL,0xDC46L,65526UL,0x9922L,0x9259L},{0x9922L,0x3934L,6UL,1UL,0x10FFL,65527UL,0xFC16L},{0x10FFL,1UL,65526UL,65526UL,65526UL,0xFC16L,6UL},{0x861FL,0xD27EL,6UL,65535UL,65530UL,65530UL,65535UL},{0UL,0xD27EL,0UL,6UL,0xFC16L,65526UL,65526UL},{0x4D1DL,1UL,3UL,0xFC16L,65527UL,0x10FFL,1UL}}; + uint8_t * const *l_1695 = &g_1457; + int32_t l_1711 = 0x5C5B3728L; + int8_t l_1728 = 0x47L; + int32_t l_1733 = 0x9B2D669CL; + int32_t l_1735 = 1L; + int32_t l_1737 = 0xD5DDB545L; + int32_t l_1784 = (-7L); + int32_t l_1786 = (-1L); + int32_t l_1787 = 0L; + int32_t l_1788 = 0xB7C3DCB2L; + int i, j; + for (g_1611 = 0; (g_1611 > 2); g_1611 = safe_add_func_uint16_t_u_u(g_1611, 8)) + { /* block id: 752 */ + int32_t l_1710 = 1L; + int32_t l_1731 = 0x84BCF933L; + int32_t l_1732 = (-1L); + int32_t l_1734 = 0L; + int32_t l_1775 = 1L; + int32_t l_1776 = 0xE5BFAA72L; + int32_t l_1777 = (-6L); + int32_t l_1778 = 0x647D0747L; + int32_t l_1779 = 0x099AC607L; + int32_t l_1780 = 0xD5FEF757L; + (*p_41) &= l_1684[1][6]; + for (g_175 = 3; (g_175 >= 1); g_175 -= 1) + { /* block id: 756 */ + int32_t l_1730 = 8L; + int32_t *l_1746 = &g_10; + int32_t l_1760 = 1L; + int32_t l_1774[1][2][5] = {{{2L,(-1L),2L,2L,(-1L)},{(-1L),2L,2L,(-1L),2L}}}; + int i, j, k; + if ((safe_div_func_int32_t_s_s(g_8[g_175], (safe_sub_func_int8_t_s_s((-1L), g_8[g_175]))))) + { /* block id: 757 */ + uint32_t ***l_1724 = &g_1250; + int32_t l_1727 = (-7L); + int32_t l_1729 = 0x4E2B1F57L; + int32_t l_1736 = 0xD335B7D7L; + for (p_40 = 0; (p_40 <= 4); p_40 += 1) + { /* block id: 760 */ + uint32_t *l_1725 = &g_1726; + int i; + l_1711 = (safe_rshift_func_int8_t_s_s(((safe_mul_func_int16_t_s_s(g_8[g_175], (safe_sub_func_int16_t_s_s((l_1695 == ((((((((safe_add_func_uint16_t_u_u((safe_mod_func_int16_t_s_s(((0UL ^ (((p_40 >= (safe_div_func_uint16_t_u_u((!(*g_94)), ((safe_div_func_int16_t_s_s(1L, (safe_rshift_func_int16_t_s_s(((*p_41) , 5L), (safe_mul_func_uint16_t_u_u((safe_lshift_func_int16_t_s_u(((*p_41) < p_42), 14)), g_8[g_175])))))) | 0x7A52D48EL)))) || (*p_41)) , (*p_41))) , 6L), 1UL)), l_1710)) | p_40) , l_1710) | 0x94D1L) , &g_1456) != &g_1456) && 0x35F8L) , l_1695)), (*g_691))))) >= 1UL), 4)); + (*g_1463) = ((((((safe_sub_func_uint16_t_u_u((l_1711 &= (safe_mod_func_uint8_t_u_u(((p_40 > (*g_1457)) <= ((*g_94) >= (p_40 == (safe_add_func_int32_t_s_s((((p_40 < p_40) & (safe_sub_func_int8_t_s_s((~(safe_lshift_func_uint16_t_u_u(((((l_1727 ^= ((*l_1725) &= ((**g_1250) ^= (safe_sub_func_int16_t_s_s((l_1724 != l_1724), (((((~0xE6FD0E25L) ^ 8L) != 0x1FF1L) <= (*g_94)) | g_8[g_175])))))) == (*p_41)) < p_40) == p_40), 1))), l_1728))) , (*p_41)), (*l_1681)))))), p_42))), l_1728)) <= l_1729) > (*g_94)) , (int32_t***) NULL) == &g_311) & p_40); + } + if ((*g_1463)) + { /* block id: 768 */ + (*g_1463) ^= l_1711; + if ((*p_41)) + continue; + } + else + { /* block id: 771 */ + return p_42; + } + l_1738--; + } + else + { /* block id: 775 */ + uint8_t l_1741 = 0xA9L; + l_1741--; + if (l_75) + goto lbl_1744; + } + if (l_1735) + { /* block id: 779 */ + (*l_1681) ^= l_1728; + } + else + { /* block id: 781 */ + int32_t l_1745 = 0xB909AFC6L; + int16_t *****l_1747 = NULL; + int16_t *****l_1748 = &g_1102; + int32_t l_1768[9][4][3] = {{{0xCD9A7C8AL,(-5L),(-4L)},{0xAF3B7215L,0x2196F175L,(-6L)},{1L,(-1L),0x3F1D03C1L},{(-1L),0x2196F175L,(-1L)}},{{0x21C896E3L,(-5L),0L},{0x2196F175L,0x41C49213L,0L},{(-1L),0xAACA832CL,(-1L)},{0x919DCA21L,0x21C896E3L,0x3F1D03C1L}},{{0x41C49213L,0xF437A5A9L,(-6L)},{0x919DCA21L,0xEDA3817EL,(-4L)},{(-1L),(-1L),0x520C3304L},{0x2196F175L,(-1L),0x4D455C86L}},{{0x21C896E3L,0xEDA3817EL,0L},{(-1L),0xF437A5A9L,0xA4D09836L},{1L,0x21C896E3L,0L},{0xAF3B7215L,0xAACA832CL,0x4D455C86L}},{{0xCD9A7C8AL,0x41C49213L,0x520C3304L},{0xCD9A7C8AL,(-5L),(-4L)},{0xAF3B7215L,0x2196F175L,(-6L)},{1L,(-1L),0x3F1D03C1L}},{{(-1L),0x2196F175L,(-1L)},{0x21C896E3L,(-5L),0L},{0x2196F175L,0x41C49213L,0L},{(-1L),0xAACA832CL,(-1L)}},{{0x919DCA21L,0x21C896E3L,0x3F1D03C1L},{0x41C49213L,0xF437A5A9L,(-6L)},{0x919DCA21L,0xEDA3817EL,(-4L)},{(-1L),(-1L),0x520C3304L}},{{0x2196F175L,(-1L),0x4D455C86L},{0x21C896E3L,0xEDA3817EL,0L},{(-1L),0xF437A5A9L,0xA4D09836L},{1L,0x21C896E3L,0L}},{{0xAF3B7215L,0xAACA832CL,0x4D455C86L},{0xCD9A7C8AL,0x41C49213L,0x520C3304L},{0xCD9A7C8AL,(-5L),(-4L)},{0xAF3B7215L,0x2196F175L,(-6L)}}}; + int i, j, k; + for (p_42 = 7; (p_42 >= 0); p_42 -= 1) + { /* block id: 784 */ + int i; + if ((*p_41)) + break; + if (l_1745) + break; + l_1746 = &p_42; + if (l_1710) + continue; + } + (*l_1681) = ((0x2EEBL < (((*l_1748) = &g_1103) != (((safe_rshift_func_int8_t_s_u(p_40, l_1745)) ^ ((*l_1746) = (safe_sub_func_int8_t_s_s((safe_mul_func_int16_t_s_s((-1L), (~l_1745))), (((***g_1028) = 0x9DL) != ((((safe_mod_func_int32_t_s_s((-6L), (safe_mod_func_uint32_t_u_u((**g_1250), 0x6072443AL)))) & p_40) != (*l_1746)) ^ 4UL)))))) , l_1759))) < l_1760); + if ((*p_41)) + { /* block id: 794 */ + int32_t * const l_1767 = &g_263; + int32_t * const *l_1766 = &l_1767; + int32_t * const * const *l_1765 = &l_1766; + int32_t l_1769 = 0xF3C67E0AL; + int32_t l_1770 = 0xDE144CE1L; + int32_t l_1771 = 0x87004860L; + int32_t l_1772 = 0L; + int32_t l_1773[4][2][1]; + int i, j, k; + for (i = 0; i < 4; i++) + { + for (j = 0; j < 2; j++) + { + for (k = 0; k < 1; k++) + l_1773[i][j][k] = 0xCD9C8AADL; + } + } + (*l_1681) ^= ((*l_1746) = (*p_41)); + (*l_1679) = func_82(((*p_41) = ((p_42 || ((*g_94) != (&g_1250 == &g_1250))) && (((l_1745 , (safe_mul_func_int8_t_s_s((((**g_1029) = ((NULL != (uint32_t*) l_1746) || ((*l_1746) == (p_42 >= 0xAB24L)))) != 0xDAL), l_1737))) , l_1765) == &g_311))), p_40, p_41); + g_1781[1][0]++; + } + else + { /* block id: 801 */ + (*p_41) = 0xF85691D2L; + } + } + l_1789++; + } + if ((*p_41)) + break; + } + } + else + { /* block id: 809 */ + int8_t ****l_1797[3][10][8] = {{{NULL,&g_1028,&g_1028,&g_1452,&g_1028,&g_1452,&g_1028,&g_1028},{&g_1028,&g_1028,&g_1028,&g_1028,&g_1028,&g_1028,&g_1452,&g_1028},{NULL,&g_1452,&g_1028,&g_1452,&g_1452,&g_1028,&g_1028,&g_1452},{&g_1452,&g_1028,NULL,&g_1452,&g_1028,&g_1452,NULL,&g_1452},{&g_1452,&g_1452,&g_1028,NULL,&g_1452,&g_1452,NULL,&g_1452},{&g_1028,&g_1028,NULL,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{NULL,&g_1452,&g_1028,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,NULL,NULL,&g_1452,&g_1452,NULL,&g_1452},{NULL,&g_1028,&g_1028,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{&g_1028,&g_1452,&g_1452,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452}},{{&g_1452,&g_1452,&g_1028,NULL,&g_1452,&g_1452,NULL,&g_1452},{&g_1028,&g_1028,NULL,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{NULL,&g_1452,&g_1028,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,NULL,NULL,&g_1452,&g_1452,NULL,&g_1452},{NULL,&g_1028,&g_1028,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{&g_1028,&g_1452,&g_1452,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,&g_1028,NULL,&g_1452,&g_1452,NULL,&g_1452},{&g_1028,&g_1028,NULL,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{NULL,&g_1452,&g_1028,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,NULL,NULL,&g_1452,&g_1452,NULL,&g_1452}},{{NULL,&g_1028,&g_1028,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{&g_1028,&g_1452,&g_1452,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,&g_1028,NULL,&g_1452,&g_1452,NULL,&g_1452},{&g_1028,&g_1028,NULL,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{NULL,&g_1452,&g_1028,&g_1028,&g_1452,&g_1452,&g_1452,&g_1452},{&g_1452,&g_1452,NULL,NULL,&g_1452,&g_1452,NULL,&g_1452},{NULL,&g_1028,&g_1028,&g_1028,&g_1028,&g_1452,&g_1452,NULL},{&g_1028,&g_1452,&g_1452,&g_1028,&g_1452,&g_1452,NULL,NULL},{NULL,&g_1028,&g_1028,&g_1452,&g_1028,&g_1452,&g_1028,NULL},{&g_1452,&g_1028,&g_1452,NULL,&g_1028,&g_1452,NULL,&g_1028}}}; + int32_t l_1809 = (-5L); + int32_t *l_1811 = &g_89; + int32_t l_1828 = 0x18381127L; + int32_t l_1830 = 2L; + int32_t l_1837 = 1L; + int32_t l_1843 = 0x4408EEE1L; + int32_t *l_1924 = &l_1809; + int i, j, k; + for (p_42 = (-7); (p_42 >= (-19)); p_42--) + { /* block id: 812 */ + int8_t *****l_1798 = &l_1797[2][7][5]; + uint32_t *l_1807[10]; + int32_t l_1808 = 0x8CAAAE7BL; + int32_t l_1810 = (-10L); + int16_t l_1813[4]; + int32_t l_1820 = 0x8E71FA34L; + int32_t l_1821 = 8L; + int32_t l_1823 = 0L; + int32_t l_1824 = 0xE5358F3EL; + int32_t l_1827 = 0x2A6C0624L; + int32_t l_1829 = 0L; + int32_t l_1832 = 0x231C0186L; + int32_t l_1835 = 1L; + int32_t l_1838 = 1L; + int32_t l_1842[4] = {(-1L),(-1L),(-1L),(-1L)}; + const uint32_t *l_1875 = &g_1846[2]; + const uint32_t **l_1874[10] = {&l_1875,&l_1875,&l_1875,&l_1875,&l_1875,&l_1875,&l_1875,&l_1875,&l_1875,&l_1875}; + int i; + for (i = 0; i < 10; i++) + l_1807[i] = &l_1738; + for (i = 0; i < 4; i++) + l_1813[i] = (-1L); + (*g_1463) = (*p_41); + } + } + g_1555 &= (safe_div_func_uint32_t_u_u((safe_sub_func_int8_t_s_s(0xD7L, (+(safe_sub_func_uint32_t_u_u((((*l_1946) ^= (safe_rshift_func_uint8_t_u_s(((*l_1944) = ((*g_1457) = (((safe_mod_func_int32_t_s_s(((*g_1463) |= (safe_add_func_uint16_t_u_u(0x2230L, ((safe_lshift_func_int8_t_s_s(((safe_add_func_int8_t_s_s((((((****g_1489) = (g_175 , (***g_1490))) != NULL) | ((0xFFA26F57L || 0L) , ((*l_1681) = (l_1941 < (safe_div_func_uint16_t_u_u((((((!(0xFEF0B100L & p_40)) | p_42) ^ (*l_1681)) || 1UL) && (*g_1457)), p_42)))))) != p_40), p_40)) != p_40), 2)) && 0L)))), (*g_1251))) & (*p_41)) , 0UL))), 7))) | 4L), (*p_41)))))), 0x49EE9D83L)); + return (*g_1457); +} + + +/* ------------------------------------------ */ +/* + * reads : g_691 g_175 g_1249 g_1250 g_1251 g_534 g_88 g_89 g_813 g_263 g_1029 g_207 g_1457 g_1098 g_101 g_1463 g_10 g_1566 g_94 g_95 g_1027 g_208 g_1611 g_532 g_68 + * writes: g_88 g_68 g_263 g_89 g_94 g_813 g_208 g_175 g_10 g_1555 g_1566 g_532 g_1098 g_534 g_14 g_1611 + */ +static const int32_t * func_52(int32_t p_53, uint8_t p_54, uint32_t p_55, int16_t p_56, uint8_t p_57) +{ /* block id: 675 */ + int32_t * const l_1493 = &g_89; + int32_t **l_1494 = &g_88; + uint16_t l_1523 = 0xBC23L; + int32_t l_1626 = (-1L); + int32_t l_1630 = 0x2F07589FL; + int32_t l_1635 = 0x2A660ECFL; + int32_t l_1636 = 0x149622CEL; + int32_t l_1638 = 0xF571B7A6L; + int32_t l_1640 = 0x4D6D3401L; + int32_t l_1641 = 0xE0CBE1D6L; + int32_t l_1642 = 0xB844DA30L; + int32_t l_1643 = 0xA3C3B5ABL; + int32_t l_1644 = (-1L); + int32_t l_1645 = 0x1F07B77DL; + int32_t l_1646 = 0xE5CFA295L; + int32_t l_1649 = (-1L); + int32_t l_1650[6][4] = {{0L,0x2CBBE18CL,0L,0L},{0x2CBBE18CL,0x2CBBE18CL,0L,0x2CBBE18CL},{0x2CBBE18CL,0L,0L,0x2CBBE18CL},{0L,0x2CBBE18CL,0L,0L},{0x2CBBE18CL,0x2CBBE18CL,0L,0x2CBBE18CL},{0x2CBBE18CL,0L,0L,0x2CBBE18CL}}; + int32_t l_1657 = (-4L); + int i, j; +lbl_1575: + (*l_1494) = l_1493; + for (g_68 = 24; (g_68 == 39); g_68 = safe_add_func_uint8_t_u_u(g_68, 4)) + { /* block id: 679 */ + uint16_t l_1504[6]; + const int32_t *l_1518 = &g_101[0][0][1]; + int8_t * const l_1535 = &g_532; + int8_t *l_1537 = &g_532; + int32_t l_1617 = 0xDC512F73L; + int32_t l_1629[4][1] = {{(-6L)},{0x1AD9824DL},{(-6L)},{0x1AD9824DL}}; + int8_t l_1637 = (-10L); + int i, j; + for (i = 0; i < 6; i++) + l_1504[i] = 0UL; + for (g_263 = 3; (g_263 >= 0); g_263 -= 1) + { /* block id: 682 */ + const uint16_t l_1513 = 0x834AL; + uint8_t *l_1514 = &g_14; + const int32_t *l_1517 = &g_89; + int32_t *l_1565 = NULL; + int32_t **l_1564 = &l_1565; + int32_t l_1568[7]; + int i; + for (i = 0; i < 7; i++) + l_1568[i] = 0L; + for (g_89 = 3; (g_89 >= 1); g_89 -= 1) + { /* block id: 685 */ + int32_t l_1503 = 0x8350D1F8L; + const uint16_t *l_1505[7]; + const uint16_t **l_1506 = &l_1505[1]; + uint32_t l_1515[2]; + uint32_t *l_1554[7] = {&l_1515[1],&l_1515[1],&l_1515[1],&l_1515[1],&l_1515[1],&l_1515[1],&l_1515[1]}; + int32_t l_1567 = (-5L); + uint16_t *l_1574 = NULL; + uint16_t **l_1573 = &l_1574; + int i; + for (i = 0; i < 7; i++) + l_1505[i] = &g_813; + for (i = 0; i < 2; i++) + l_1515[i] = 0x234DA6F4L; + if (((safe_add_func_int16_t_s_s((((((safe_mul_func_int16_t_s_s((safe_lshift_func_int8_t_s_s(l_1503, 1)), l_1504[0])) , ((((p_57 & (NULL == &p_54)) & 1UL) <= ((((*l_1506) = (g_94 = l_1505[0])) != NULL) , ((safe_mod_func_int16_t_s_s((p_56 = (safe_mod_func_int32_t_s_s(((safe_add_func_int16_t_s_s((*g_691), l_1503)) , p_53), (***g_1249)))), p_53)) == l_1513))) , (**l_1494))) & 0x6641EF11L) , (uint8_t*) NULL) != l_1514), l_1515[1])) & (***g_1249))) + { /* block id: 689 */ + uint32_t l_1516 = 1UL; + if (l_1516) + { /* block id: 690 */ + return l_1517; + } + else + { /* block id: 692 */ + return l_1518; + } + } + else + { /* block id: 695 */ + uint16_t *l_1521 = &g_813; + int8_t *l_1536 = &g_532; + (*g_1463) = (((((**g_1029) = (safe_mod_func_uint16_t_u_u((NULL != &g_1250), ((*l_1521) ^= 1UL)))) <= (*g_1457)) >= ((safe_unary_minus_func_uint32_t_u((!(**g_1250)))) > (l_1523 <= ((safe_unary_minus_func_uint32_t_u((safe_add_func_uint16_t_u_u((safe_mod_func_int32_t_s_s((safe_rshift_func_int16_t_s_s(((*g_691) = ((safe_mul_func_int16_t_s_s(p_56, (0x2F59L || ((((safe_mod_func_int8_t_s_s(p_53, (*l_1518))) == (-7L)) >= (-1L)) == g_175)))) , 0xBA32L)), p_56)), (*g_1251))), g_89)))) <= p_56)))) , 0xBDB685A7L); + if ((*g_1463)) + continue; + (*g_1463) |= (l_1535 != (l_1537 = l_1536)); + } + (*g_1463) |= (safe_mod_func_int8_t_s_s((safe_div_func_int8_t_s_s(p_54, (safe_rshift_func_int8_t_s_u(((safe_rshift_func_uint16_t_u_s(((safe_add_func_int8_t_s_s(((*l_1535) = ((NULL == (*g_1249)) , ((l_1503 || (*g_1251)) > (safe_div_func_int16_t_s_s((safe_add_func_uint32_t_u_u((p_55 = (((safe_sub_func_int32_t_s_s(((g_1555 = 0x02FA4FDCL) != (*l_1493)), (g_1566 ^= (((((safe_sub_func_uint8_t_u_u(((safe_add_func_uint8_t_u_u(p_53, (((safe_mod_func_int8_t_s_s((safe_rshift_func_uint16_t_u_u(((+(p_56 != 0xE9L)) > p_54), (**l_1494))), 0xD9L)) , 0x63D33749L) ^ (**g_1250)))) , l_1515[1]), (*l_1518))) , l_1515[0]) > p_57) , l_1564) != &l_1565)))) , &g_1098) != &p_54)), (**g_1250))), p_57))))), (**l_1494))) | (*l_1493)), l_1515[1])) != (*l_1518)), 0)))), 1L)); + (*g_1463) = ((l_1568[1] = (!(3L <= l_1567))) && ((safe_rshift_func_int16_t_s_s((safe_sub_func_uint16_t_u_u((*g_94), (*g_94))), (*g_691))) > (((*l_1573) = &g_1566) == &l_1504[0]))); + if ((*l_1517)) + break; + } + for (g_1098 = 1; (g_1098 <= 4); g_1098 += 1) + { /* block id: 716 */ + int8_t l_1596 = (-1L); + uint16_t l_1612[10][1]; + int32_t l_1627[10][8][3] = {{{0xC0858DD3L,0x6CDF6292L,0x0C47EFC1L},{1L,0x2B909333L,(-1L)},{(-1L),0x51500EF7L,8L},{(-3L),1L,(-1L)},{(-10L),0L,0x0C47EFC1L},{0x2B39689EL,(-4L),1L},{0xCF339FD2L,(-4L),0xB192890FL},{0xE885E439L,1L,0xE885E439L}},{{(-1L),(-6L),(-4L)},{0xBA747FABL,0xB96D546FL,(-4L)},{4L,0xCF339FD2L,0x6CDF6292L},{1L,9L,0x05C6FB27L},{4L,0x301C8E77L,8L},{0xBA747FABL,0x28220F40L,4L},{(-1L),0L,0L},{0xE885E439L,0x7AC51D76L,0x7AC51D76L}},{{0xCF339FD2L,0x9B745613L,0x20AF4157L},{0x2B39689EL,(-3L),0xE885E439L},{(-10L),0x0C47EFC1L,6L},{(-3L),0xB96D546FL,0x28220F40L},{(-1L),0x0C47EFC1L,(-6L)},{1L,(-3L),0xC54F3900L},{0xC0858DD3L,0x9B745613L,8L},{0xB96D546FL,0x7AC51D76L,0xE4F7FA0BL}},{{0L,0L,0xCF339FD2L},{0x7085AA06L,0x28220F40L,0xF46FF3C9L},{0xCF339FD2L,0x301C8E77L,0x930F5A2FL},{0x2A0E2F99L,9L,0xE885E439L},{0xE30DA511L,0xCF339FD2L,0x930F5A2FL},{2L,0xB96D546FL,0xF46FF3C9L},{0x1801E895L,(-6L),0xCF339FD2L},{1L,1L,0xE4F7FA0BL}},{{8L,(-4L),8L},{0xC9619119L,(-4L),0xC54F3900L},{0xEF4FC547L,0L,(-6L)},{0x9BB809B8L,1L,0x28220F40L},{0xCF339FD2L,0x51500EF7L,6L},{0x9BB809B8L,0x2B909333L,0xE885E439L},{0xEF4FC547L,0x6CDF6292L,0x20AF4157L},{0xC9619119L,0xB96D546FL,0x7AC51D76L}},{{8L,0L,0L},{0x2A0E2F99L,0xC9619119L,0x2B909333L},{0x930F5A2FL,0xEF4FC547L,6L},{0x28220F40L,0x9BB809B8L,0x4059FABFL},{0x0C47EFC1L,0xCF339FD2L,0x1801E895L},{4L,0x9BB809B8L,0x7085AA06L},{(-1L),0xEF4FC547L,0x51500EF7L},{0xC54F3900L,0xC9619119L,0x05C6FB27L}},{{0xCF339FD2L,8L,(-4L)},{1L,1L,0x2A0E2F99L},{(-4L),0x1801E895L,4L},{0x2A0E2F99L,2L,(-3L)},{0x20AF4157L,0xE30DA511L,6L},{0xF46FF3C9L,0x2A0E2F99L,(-3L)},{0x6CDF6292L,0xCF339FD2L,4L},{(-1L),0x7085AA06L,0x2A0E2F99L}},{{(-1L),0L,(-4L)},{0x05C6FB27L,0xB96D546FL,0x05C6FB27L},{(-6L),0xC0858DD3L,0x51500EF7L},{0x7AC51D76L,1L,0x7085AA06L},{0xB192890FL,(-1L),0x1801E895L},{0x2A0E2F99L,(-3L),0x4059FABFL},{0xB192890FL,(-10L),6L},{0x7AC51D76L,0x2B39689EL,0x2B909333L}},{{(-6L),0xCF339FD2L,8L},{0x05C6FB27L,0xE885E439L,0xE885E439L},{(-1L),(-1L),0x301C8E77L},{(-1L),0xBA747FABL,0x05C6FB27L},{0x6CDF6292L,4L,0x9B745613L},{0xF46FF3C9L,1L,0x2B39689EL},{0x20AF4157L,4L,0xC0858DD3L},{0x2A0E2F99L,0xBA747FABL,9L}},{{(-4L),(-1L),6L},{1L,0xE885E439L,1L},{0xCF339FD2L,0xCF339FD2L,(-1L)},{0xC54F3900L,0x2B39689EL,0x9BB809B8L},{(-1L),(-10L),1L},{4L,(-3L),0x05C6FB27L},{0x0C47EFC1L,(-1L),1L},{0x28220F40L,1L,0x9BB809B8L}}}; + uint8_t l_1661 = 0x91L; + uint8_t l_1672 = 0x8AL; + int i, j, k; + for (i = 0; i < 10; i++) + { + for (j = 0; j < 1; j++) + l_1612[i][j] = 0xADEAL; + } + if (p_53) + goto lbl_1575; + for (g_813 = 1; (g_813 <= 4); g_813 += 1) + { /* block id: 720 */ + int16_t l_1610[5]; + int32_t l_1628 = 1L; + int32_t l_1631 = 0x2FD5F7A3L; + int32_t l_1632 = 0x49EF7935L; + int32_t l_1634 = 0xBFA600F1L; + int32_t l_1639 = 0xDFC860C3L; + int32_t l_1647 = 0x7A248064L; + int32_t l_1648 = 0x06A924C2L; + int32_t l_1651 = 0x3BAFF8AFL; + int32_t l_1652 = 0xE4B57DEBL; + int32_t l_1653 = 0x330A2A19L; + int32_t l_1654 = 0xF11007C4L; + int32_t l_1655 = 1L; + int32_t l_1656[6]; + uint8_t l_1658 = 0x6DL; + int32_t l_1675 = 8L; + uint16_t l_1676 = 0x29D9L; + int i; + for (i = 0; i < 5; i++) + l_1610[i] = 0xB1EEL; + for (i = 0; i < 6; i++) + l_1656[i] = 1L; + if (((safe_mul_func_uint8_t_u_u((((l_1612[9][0] = ((safe_sub_func_uint8_t_u_u(((++(*g_1251)) & 0x55C69D38L), (((*g_94) , (safe_lshift_func_int16_t_s_u((safe_sub_func_int32_t_s_s(((+(safe_lshift_func_int8_t_s_s((safe_add_func_int8_t_s_s((*l_1517), ((*l_1535) ^= ((safe_mul_func_uint8_t_u_u((safe_add_func_int32_t_s_s((safe_sub_func_int8_t_s_s((((l_1596 & (*l_1517)) || (((*l_1514) = ((safe_mul_func_int8_t_s_s(0xBAL, (p_57 > (!((safe_add_func_int8_t_s_s(((safe_sub_func_uint32_t_u_u((safe_unary_minus_func_int16_t_s(((safe_lshift_func_uint8_t_u_s(0xB1L, 6)) == (safe_rshift_func_uint8_t_u_s(((safe_sub_func_int16_t_s_s((0x08L == p_57), l_1610[4])) , (*g_1457)), 7))))), p_53)) , (**g_1027)), (*l_1518))) | l_1596))))) && (*l_1517))) , p_56)) >= g_1611), l_1596)), 0UL)), l_1596)) < (**g_1027))))), 4))) > (*g_1457)), p_53)), p_54))) ^ l_1596))) | p_57)) || 1UL) , p_55), l_1610[4])) == 8L)) + { /* block id: 725 */ + int32_t *l_1613 = &g_89; + int32_t *l_1614 = &g_1555; + int32_t *l_1615 = &g_1555; + int32_t *l_1616 = &l_1568[5]; + int32_t *l_1618 = &g_101[0][1][4]; + int32_t *l_1619 = &g_1555; + int32_t *l_1620 = &g_10; + int32_t *l_1621 = &l_1568[3]; + int32_t *l_1622 = &g_1555; + int32_t *l_1623 = &l_1617; + int32_t *l_1624 = &g_89; + int32_t *l_1625[8][10][3] = {{{&g_1555,NULL,&g_89},{&l_1568[5],&l_1568[1],&g_89},{&g_89,&l_1568[1],&l_1568[5]},{&l_1568[5],NULL,NULL},{&g_1555,&l_1568[1],&g_89},{&l_1568[1],&l_1568[1],NULL},{&g_89,NULL,&l_1568[5]},{&l_1568[1],NULL,&g_89},{&g_1555,NULL,&g_89},{&l_1568[5],&l_1568[1],&g_89}},{{&g_89,&l_1568[1],&l_1568[5]},{&l_1568[5],NULL,NULL},{&g_1555,&l_1568[1],&g_89},{&l_1568[1],&l_1568[1],NULL},{&g_89,NULL,&l_1568[5]},{&l_1568[1],NULL,&g_89},{&g_1555,NULL,&g_89},{&l_1568[5],&l_1568[1],&g_89},{&g_89,&l_1568[1],&l_1568[5]},{&l_1568[5],NULL,NULL}},{{&g_1555,&l_1568[1],&g_89},{&l_1568[1],&l_1568[1],NULL},{&g_89,NULL,&l_1568[5]},{&l_1568[1],NULL,&g_89},{&g_1555,NULL,&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555}},{{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617},{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555},{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617}},{{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555},{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617},{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617}},{{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555},{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617},{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555}},{{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555},{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617},{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555}},{{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617},{NULL,&l_1568[4],&g_101[0][1][4]},{&l_1568[1],&l_1568[1],&l_1617},{&l_1568[5],NULL,NULL},{&l_1568[1],&g_1555,&g_1555},{NULL,NULL,&g_101[0][1][4]},{NULL,&l_1568[1],&g_1555},{&l_1568[5],&l_1568[4],NULL},{NULL,&g_1555,&l_1617}}}; + int32_t l_1633[6][3][5] = {{{0x54E12B57L,(-1L),(-1L),0x54E12B57L,0x549A8D90L},{0x54E12B57L,0xD8394710L,0x67A448C4L,0x55C0B040L,0L},{0L,(-1L),0x67A448C4L,0xC213F2D5L,(-1L)}},{{0x2BAA21AFL,0xA4F12C09L,(-1L),0x55C0B040L,(-1L)},{8L,1L,1L,0x54E12B57L,0L},{0L,0x2BAA21AFL,6L,1L,(-1L)}},{{0x5288A55AL,6L,0L,1L,(-4L)},{0L,8L,8L,0L,(-1L)},{0L,0x55C0B040L,0xC213F2D5L,0x9E74C91AL,6L}},{{0x5288A55AL,8L,0xC213F2D5L,(-5L),0xFDBFCCF4L},{0L,6L,8L,0x9E74C91AL,0xFDBFCCF4L},{1L,0x2BAA21AFL,0L,0L,6L}},{{0L,0x2BAA21AFL,6L,1L,(-1L)},{0x5288A55AL,6L,0L,1L,(-4L)},{0L,8L,8L,0L,(-1L)}},{{0L,0x55C0B040L,0xC213F2D5L,0x9E74C91AL,6L},{0x5288A55AL,8L,0xC213F2D5L,(-5L),0xFDBFCCF4L},{0L,6L,8L,0x9E74C91AL,0xFDBFCCF4L}}}; + int i, j, k; + --l_1658; + l_1661++; + (*l_1623) &= (safe_div_func_uint32_t_u_u((*l_1517), p_54)); + if (p_57) + continue; + } + else + { /* block id: 730 */ + if (p_57) + break; + } + (*g_1463) = (-4L); + for (l_1648 = 4; (l_1648 >= 1); l_1648 -= 1) + { /* block id: 736 */ + int32_t *l_1666 = &l_1654; + int32_t *l_1667 = &l_1634; + int32_t *l_1668 = NULL; + int32_t *l_1669 = &l_1629[1][0]; + int32_t *l_1670[3][6] = {{&l_1628,&l_1636,&l_1636,&l_1628,NULL,&l_1628},{&l_1628,NULL,&l_1628,&l_1636,&l_1636,&l_1628},{NULL,NULL,&l_1636,&l_1629[1][0],&l_1636,NULL}}; + int i, j; + l_1672++; + l_1676--; + } + } + } + } + } + (*l_1494) = NULL; + return (*l_1494); +} + + +/* ------------------------------------------ */ +/* + * reads : g_94 g_95 g_168 g_1457 g_1098 g_1249 g_1250 g_1251 g_534 g_1489 g_1463 g_88 g_101 g_813 + * writes: g_168 g_534 g_1486 g_1487 g_10 g_101 + */ +static int32_t * func_64(uint16_t p_65, int32_t * p_66) +{ /* block id: 664 */ + int32_t *l_1470 = &g_8[0]; + int32_t **l_1471 = &l_1470; + int32_t l_1472 = 8L; + uint16_t *l_1473[2][3] = {{&g_813,&g_168,&g_168},{&g_813,&g_168,&g_168}}; + int32_t l_1482 = 4L; + int32_t **l_1483[8][2] = {{&g_88,NULL},{&g_88,&g_88},{NULL,&g_88},{&g_88,NULL},{&g_88,&g_88},{NULL,&g_88},{&g_88,NULL},{&g_88,&g_88}}; + int32_t **l_1485 = &g_1463; + int32_t ***l_1484[7]; + uint16_t *l_1488 = &g_168; + int i, j; + for (i = 0; i < 7; i++) + l_1484[i] = &l_1485; + (*g_88) |= (safe_sub_func_int16_t_s_s(((((safe_add_func_int8_t_s_s((((safe_rshift_func_uint16_t_u_s(((((*l_1471) = l_1470) != ((l_1472 , (((g_168 ^= (*g_94)) , (safe_lshift_func_int16_t_s_u((safe_mul_func_uint8_t_u_u((*g_1457), ((safe_div_func_uint32_t_u_u((++(***g_1249)), ((*g_1463) = (((((l_1482 ^= l_1472) && (l_1482 , ((l_1483[2][0] == (g_1487 = (g_1486 = &p_66))) , (((((((~((l_1488 == NULL) == p_65)) , (int16_t******) NULL) == g_1489) <= 0xAAB5L) , l_1488) == l_1488) == p_65)))) & (*g_94)) <= p_65) ^ p_65)))) <= p_65))), 11))) > 0xF0D8L)) , p_66)) < 65535UL), p_65)) != 4UL) <= p_65), p_65)) , (***g_1249)) == 0xE4B2D116L) | 7L), p_65)); + return p_66; +} + + +/* ------------------------------------------ */ +/* + * reads : g_14 g_735 g_101 g_1250 g_1251 g_94 g_95 g_534 g_679 g_1029 g_207 g_208 g_691 g_88 g_1463 g_813 + * writes: g_14 g_534 g_1028 g_1452 g_101 g_1456 g_735 g_175 + */ +static int32_t * func_69(int8_t p_70) +{ /* block id: 646 */ + uint8_t *l_1419[9] = {&g_177,&g_1098,&g_177,&g_177,&g_1098,&g_177,&g_177,&g_1098,&g_177}; + int32_t l_1420 = 0x8112C32BL; + int32_t l_1421 = 0x5D192EC3L; + int32_t l_1422 = (-2L); + int32_t l_1423 = 3L; + int32_t l_1424[1][7][9] = {{{0xA557835BL,0x13D4A42FL,0x65F5FA38L,0x65F5FA38L,0x13D4A42FL,0xA557835BL,0x11973284L,(-3L),3L},{0L,(-3L),1L,(-1L),1L,0x2B1E312BL,0xA557835BL,0x65F5FA38L,0xD082371BL},{(-1L),1L,(-3L),0L,0x11973284L,(-10L),0x11973284L,0L,(-3L)},{0x65F5FA38L,0x65F5FA38L,0x13D4A42FL,0xA557835BL,0x11973284L,(-3L),3L,0xD082371BL,7L},{0xCC668815L,0x7AE882F6L,0xD082371BL,(-6L),1L,(-1L),0x2B1E312BL,0x11973284L,0x11973284L},{7L,0x5A5A6D7DL,0x13D4A42FL,1L,0x13D4A42FL,0x5A5A6D7DL,7L,(-1L),4L},{7L,0x2B1E312BL,(-3L),0x5A5A6D7DL,0L,1L,(-1L),(-10L),0xA557835BL}}}; + int16_t ***** const l_1427 = &g_1102; + int16_t *****l_1428 = &g_1102; + int16_t ******l_1429 = &l_1428; + int16_t *l_1442 = &g_175; + int32_t l_1443 = 0xCFA03042L; + int8_t ***l_1450 = &g_1029; + int8_t ****l_1451[8][6][5] = {{{&g_1028,&l_1450,NULL,NULL,NULL},{&g_1028,&l_1450,&l_1450,&g_1028,&l_1450},{&g_1028,&g_1028,NULL,&l_1450,&g_1028},{&l_1450,&l_1450,&l_1450,&g_1028,&g_1028},{&g_1028,&g_1028,&g_1028,&g_1028,&g_1028},{&g_1028,&l_1450,&g_1028,&l_1450,&g_1028}},{{NULL,&g_1028,&l_1450,&g_1028,&l_1450},{NULL,&l_1450,&g_1028,&g_1028,&l_1450},{NULL,&g_1028,&l_1450,&l_1450,&l_1450},{&g_1028,&g_1028,&g_1028,&l_1450,&g_1028},{&g_1028,NULL,&l_1450,NULL,&l_1450},{&l_1450,NULL,&g_1028,&g_1028,&l_1450}},{{&g_1028,NULL,&g_1028,&l_1450,&l_1450},{&l_1450,&g_1028,&l_1450,&g_1028,&g_1028},{&g_1028,&g_1028,&l_1450,NULL,&g_1028},{&l_1450,&l_1450,&g_1028,&l_1450,&g_1028},{&g_1028,&g_1028,&l_1450,&l_1450,&g_1028},{&l_1450,&l_1450,&l_1450,&g_1028,&g_1028}},{{&g_1028,&g_1028,&g_1028,&g_1028,&g_1028},{&g_1028,&l_1450,&g_1028,&l_1450,&g_1028},{NULL,&g_1028,&l_1450,&g_1028,&l_1450},{NULL,&l_1450,&g_1028,&g_1028,&l_1450},{NULL,&g_1028,&l_1450,&l_1450,&l_1450},{&g_1028,&g_1028,&g_1028,&l_1450,&g_1028}},{{&g_1028,NULL,&l_1450,NULL,&l_1450},{&l_1450,NULL,&g_1028,&g_1028,&l_1450},{&g_1028,NULL,&g_1028,&l_1450,&l_1450},{&l_1450,&g_1028,&l_1450,&g_1028,&g_1028},{&g_1028,&g_1028,&l_1450,NULL,&g_1028},{&l_1450,&l_1450,&g_1028,&l_1450,&g_1028}},{{&g_1028,&g_1028,&l_1450,&l_1450,&g_1028},{&l_1450,&l_1450,&l_1450,&g_1028,&g_1028},{&g_1028,&g_1028,&g_1028,&g_1028,&g_1028},{&g_1028,&l_1450,&g_1028,&l_1450,&g_1028},{NULL,&g_1028,&l_1450,&g_1028,&l_1450},{NULL,&l_1450,&g_1028,&g_1028,&l_1450}},{{NULL,&g_1028,&l_1450,&l_1450,&l_1450},{&g_1028,&g_1028,&g_1028,&l_1450,&g_1028},{&g_1028,NULL,&l_1450,NULL,&l_1450},{&l_1450,NULL,&g_1028,&g_1028,&l_1450},{&g_1028,NULL,&g_1028,&l_1450,&g_1028},{&l_1450,&g_1028,&g_1028,&g_1028,&l_1450}},{{&g_1028,&l_1450,&g_1028,&g_1028,&g_1028},{&l_1450,&l_1450,&l_1450,&l_1450,&l_1450},{&g_1028,&g_1028,&g_1028,&l_1450,&g_1028},{&l_1450,&l_1450,&g_1028,&l_1450,&l_1450},{&l_1450,&g_1028,&g_1028,&g_1028,&g_1028},{&g_1028,&l_1450,&g_1028,&l_1450,&l_1450}}}; + int32_t **l_1453 = &g_735; + uint8_t **l_1455[5][6][8]; + uint8_t ***l_1454[4][4][6] = {{{&l_1455[0][4][6],&l_1455[0][4][6],&l_1455[4][5][0],NULL,&l_1455[0][1][4],&l_1455[1][2][1]},{&l_1455[4][5][0],&l_1455[3][2][5],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][0]},{NULL,&l_1455[4][5][0],&l_1455[4][5][0],NULL,&l_1455[0][4][6],&l_1455[1][2][1]},{&l_1455[3][0][2],NULL,&l_1455[4][5][0],&l_1455[4][5][6],&l_1455[4][5][0],&l_1455[4][5][6]}},{{&l_1455[4][5][6],&l_1455[4][5][0],&l_1455[4][5][6],&l_1455[4][5][0],NULL,&l_1455[3][0][2]},{&l_1455[1][2][1],&l_1455[0][4][6],NULL,&l_1455[4][5][0],&l_1455[4][5][0],NULL},{&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[3][2][5],&l_1455[4][5][0]},{&l_1455[1][2][1],&l_1455[0][1][4],NULL,&l_1455[4][5][0],&l_1455[0][4][6],&l_1455[0][4][6]}},{{&l_1455[4][5][6],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][6],&l_1455[1][2][3],&l_1455[4][5][0]},{&l_1455[3][0][2],NULL,&l_1455[4][5][6],NULL,NULL,&l_1455[4][5][0]},{NULL,&l_1455[0][4][6],&l_1455[0][1][4],&l_1455[4][5][0],NULL,NULL},{&l_1455[4][5][0],NULL,&l_1455[2][0][1],NULL,&l_1455[1][2][3],&l_1455[4][5][0]}},{{&l_1455[0][4][6],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[0][4][6],&l_1455[4][5][0]},{&l_1455[4][5][0],&l_1455[0][1][4],NULL,&l_1455[4][5][6],&l_1455[3][2][5],&l_1455[4][5][0]},{&l_1455[4][5][0],&l_1455[4][5][0],&l_1455[4][5][6],&l_1455[0][1][4],&l_1455[4][5][0],&l_1455[4][5][0]},{NULL,&l_1455[0][4][6],NULL,&l_1455[2][0][1],NULL,&l_1455[4][5][0]}}}; + int16_t l_1459 = 5L; + int i, j, k; + for (i = 0; i < 5; i++) + { + for (j = 0; j < 6; j++) + { + for (k = 0; k < 8; k++) + l_1455[i][j][k] = &l_1419[0]; + } + } + l_1423 |= ((safe_add_func_int32_t_s_s(0L, ((**g_1250) = (safe_lshift_func_int8_t_s_u(((safe_div_func_uint8_t_u_u((g_14++), (((l_1427 == ((*l_1429) = l_1428)) ^ (-6L)) && p_70))) != (safe_rshift_func_uint8_t_u_u(((safe_rshift_func_int16_t_s_u((((l_1443 = (safe_div_func_uint32_t_u_u((safe_add_func_int32_t_s_s((*g_735), ((l_1424[0][5][3] <= ((safe_mod_func_uint16_t_u_u(p_70, ((l_1442 == NULL) , 0x8830L))) < p_70)) & p_70))), p_70))) && 0L) > l_1422), p_70)) ^ 0x24L), l_1420))), l_1421))))) == l_1420); + (*g_735) = ((*g_94) && (safe_rshift_func_int8_t_s_s((((((((safe_rshift_func_int16_t_s_s((p_70 == ((((*l_1429) != (*l_1429)) , ((l_1423 <= (((**g_1250) , (((safe_div_func_int16_t_s_s(((g_1452 = (g_1028 = l_1450)) != NULL), p_70)) , (*g_94)) || 0x2E08L)) >= l_1421)) && p_70)) , l_1420)), 7)) <= g_679[0][4]) == 0x8AD548DCL) || (**g_1029)) , l_1453) != NULL) && p_70), 1))); + if (((g_1456 = &l_1419[0]) != NULL)) + { /* block id: 656 */ + int32_t *l_1458[3][9][3] = {{{NULL,NULL,&l_1422},{&l_1421,&l_1420,&g_89},{NULL,&g_101[0][0][0],&g_10},{&l_1443,&l_1443,&l_1422},{NULL,&l_1443,&g_89},{NULL,&g_101[0][0][0],&l_1443},{&l_1422,&l_1420,&g_89},{&g_10,NULL,&l_1443},{&g_10,&g_89,&g_89}},{{&g_89,&l_1421,&l_1422},{&g_89,&l_1422,&g_10},{&g_10,NULL,&g_89},{&g_10,&l_1422,&l_1422},{&l_1422,NULL,NULL},{NULL,&l_1422,NULL},{NULL,&l_1421,NULL},{&l_1443,&g_89,NULL},{NULL,NULL,&l_1422}},{{&l_1421,&l_1420,&g_89},{NULL,&g_101[0][0][0],&l_1421},{&g_10,&g_10,&l_1420},{&g_89,&g_10,&l_1422},{&l_1423,&l_1443,&g_10},{&g_101[0][0][0],&l_1422,NULL},{&l_1421,&l_1423,&g_10},{&g_89,&l_1422,&l_1422},{&g_89,&g_10,&l_1420}}}; + uint8_t l_1460[9][9][3] = {{{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL}},{{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL}},{{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL}},{{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL}},{{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL}},{{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL},{255UL,255UL,255UL},{250UL,0UL,0UL},{250UL,250UL,0UL},{255UL,0UL,0UL},{0UL,255UL,0UL}},{{255UL,255UL,255UL},{250UL,0UL,0UL},{0UL,0UL,255UL},{0UL,255UL,255UL},{255UL,250UL,255UL},{0UL,250UL,0UL},{0UL,255UL,255UL},{0UL,0UL,255UL},{0UL,255UL,255UL}},{{255UL,250UL,255UL},{0UL,250UL,0UL},{0UL,255UL,255UL},{0UL,0UL,255UL},{0UL,255UL,255UL},{255UL,250UL,255UL},{0UL,250UL,0UL},{0UL,255UL,255UL},{0UL,0UL,255UL}},{{0UL,255UL,255UL},{255UL,250UL,255UL},{0UL,250UL,0UL},{0UL,255UL,255UL},{0UL,0UL,255UL},{0UL,255UL,255UL},{255UL,250UL,255UL},{0UL,250UL,0UL},{0UL,255UL,255UL}}}; + int i, j, k; + (*l_1453) = l_1458[0][6][1]; + --l_1460[3][2][1]; + } + else + { /* block id: 659 */ + (*g_88) = (((*g_691) = p_70) <= 65534UL); + } + return g_1463; +} + + +/* ------------------------------------------ */ +/* + * reads : g_912 + * writes: g_735 g_88 + */ +static uint8_t func_76(uint8_t p_77, const int32_t * const p_78, int32_t * p_79) +{ /* block id: 640 */ + int32_t **l_1411 = &g_735; + int32_t **l_1412 = &g_88; + (*l_1412) = func_80(((*l_1411) = p_79)); + (*l_1412) = p_79; + return g_912; +} + + +/* ------------------------------------------ */ +/* + * reads : + * writes: + */ +static int32_t * const func_80(int32_t * p_81) +{ /* block id: 638 */ + return p_81; +} + + +/* ------------------------------------------ */ +/* + * reads : + * writes: + */ +static int32_t * func_82(int32_t p_83, uint16_t p_84, int32_t * p_85) +{ /* block id: 13 */ + int32_t l_592[2]; + const int32_t l_595[2][2][1] = {{{(-1L)},{(-1L)}},{{(-1L)},{(-1L)}}}; + const int8_t l_598 = 0xC0L; + uint16_t *l_610 = &g_168; + int8_t l_655 = 1L; + int32_t l_656[8][1][1] = {{{4L}},{{4L}},{{0xD2B475C6L}},{{4L}},{{4L}},{{0xD2B475C6L}},{{4L}},{{4L}}}; + uint32_t l_663 = 0UL; + int16_t l_678 = 0x00A6L; + int16_t l_680 = 0L; + int32_t ***l_715 = NULL; + int16_t * const *l_864[10]; + uint32_t l_907[10] = {0x8FD9B42AL,0xCB637439L,0x8FD9B42AL,0x8FD9B42AL,0xCB637439L,0x8FD9B42AL,0x8FD9B42AL,0xCB637439L,0x8FD9B42AL,0x8FD9B42AL}; + int8_t l_911 = (-9L); + int32_t l_964 = 0xA692B646L; + int32_t l_1012 = (-9L); + int32_t l_1093[4][3][8] = {{{2L,9L,(-3L),9L,2L,0L,0x9A570B86L,1L},{0L,0x56E35751L,2L,(-1L),0xB912FE8EL,0L,9L,9L},{0x9BC7F200L,0x19546F1DL,2L,2L,0x19546F1DL,0x9BC7F200L,0x9A570B86L,0xB912FE8EL}},{{0xB912FE8EL,0x68511652L,(-3L),1L,9L,(-1L),0x9BC7F200L,0L},{(-3L),0x67113F6AL,0L,1L,0L,0x67113F6AL,(-3L),0xB912FE8EL},{0x19546F1DL,0L,0x56E35751L,2L,(-1L),0xB912FE8EL,0L,9L}},{{1L,0xE0D73146L,0x33C53D7FL,(-1L),(-1L),0x33C53D7FL,0xE0D73146L,1L},{0x19546F1DL,1L,0x67113F6AL,9L,0L,0xE0D73146L,0x56E35751L,0x68511652L},{(-3L),0x9BC7F200L,4L,0xE0D73146L,9L,0xE0D73146L,4L,0x9BC7F200L}},{{0xB912FE8EL,1L,0x68511652L,0x9A570B86L,0x19546F1DL,0x33C53D7FL,0L,4L},{0x9BC7F200L,0xE0D73146L,(-1L),0L,0xB912FE8EL,0xB912FE8EL,0L,(-1L)},{0L,0L,0x68511652L,0x33C53D7FL,2L,0x67113F6AL,(-1L),1L}}}; + int32_t l_1120 = 0x0B67F3DBL; + uint16_t l_1130 = 7UL; + uint8_t l_1193[7][9][3] = {{{0x19L,0x45L,251UL},{246UL,1UL,0x9BL},{255UL,0UL,0UL},{0x90L,255UL,0x37L},{0x96L,0x19L,255UL},{0x96L,0xE8L,253UL},{0x90L,0xC2L,250UL},{255UL,255UL,251UL},{246UL,0xB5L,0xABL}},{{0x19L,255UL,0x90L},{1UL,0xC2L,4UL},{255UL,0xE8L,0x42L},{8UL,0x19L,0x42L},{249UL,255UL,4UL},{0UL,0UL,0x90L},{8UL,1UL,0xABL},{0UL,0x45L,251UL},{8UL,0x73L,250UL}},{{0UL,246UL,253UL},{249UL,8UL,255UL},{8UL,8UL,0x37L},{255UL,246UL,0UL},{1UL,0x73L,0x9BL},{0x19L,0x45L,251UL},{246UL,1UL,0x9BL},{255UL,0UL,0UL},{0x90L,255UL,0x37L}},{{0x96L,0x19L,255UL},{0x96L,0xE8L,253UL},{0x90L,0xC2L,250UL},{255UL,255UL,251UL},{246UL,0xB5L,0xABL},{0x19L,255UL,0x90L},{1UL,0xC2L,4UL},{255UL,0xE8L,0x42L},{8UL,0x19L,0x42L}},{{249UL,255UL,4UL},{0UL,0UL,0x90L},{8UL,1UL,0xABL},{0UL,0x45L,251UL},{8UL,0x73L,250UL},{0UL,246UL,253UL},{249UL,8UL,255UL},{8UL,8UL,0x37L},{255UL,246UL,0UL}},{{1UL,0x73L,0x9BL},{0x19L,0x45L,251UL},{246UL,1UL,0x9BL},{255UL,0UL,0UL},{0x90L,255UL,0x37L},{0x96L,0x19L,255UL},{0x96L,0xE8L,253UL},{0x90L,0xC2L,250UL},{255UL,255UL,251UL}},{{246UL,0xB5L,0xABL},{0x19L,255UL,0x90L},{1UL,0xC2L,4UL},{255UL,0xE8L,0x42L},{8UL,0x19L,0x42L},{249UL,255UL,4UL},{0UL,0UL,0x90L},{8UL,1UL,0xABL},{0UL,0x45L,251UL}}}; + uint32_t l_1214 = 0xA67816D7L; + int8_t **l_1230 = &g_207[2]; + int32_t *l_1239 = &l_656[3][0][0]; + int16_t ** const *l_1292 = &g_435; + int16_t ** const **l_1291 = &l_1292; + int32_t l_1329 = 0L; + int16_t ***l_1339 = &g_435; + uint32_t l_1340 = 0xE0FECC7EL; + const uint32_t ***l_1369 = NULL; + int i, j, k; + for (i = 0; i < 2; i++) + l_592[i] = 0x6EF68121L; + for (i = 0; i < 10; i++) + l_864[i] = NULL; + for (p_84 = 14; (p_84 == 60); p_84 = safe_add_func_int16_t_s_s(p_84, 4)) + { /* block id: 16 */ + int32_t *l_594[4]; + int32_t **l_593 = &l_594[2]; + int32_t l_616 = (-1L); + int32_t l_619 = 1L; + int16_t * const l_648[5] = {&g_175,&g_175,&g_175,&g_175,&g_175}; + int32_t l_653[4][1]; + uint32_t l_681 = 1UL; + int8_t **l_876 = NULL; + int8_t l_904 = 0x2AL; + uint32_t l_908 = 0xDB682572L; + int32_t l_910 = (-10L); + int16_t l_1180[6]; + int8_t l_1233 = (-9L); + int16_t l_1234 = 1L; + int32_t l_1306 = 1L; + int32_t l_1323 = 1L; + uint8_t l_1400[3][9]; + int i, j; + for (i = 0; i < 4; i++) + l_594[i] = &g_8[0]; + for (i = 0; i < 4; i++) + { + for (j = 0; j < 1; j++) + l_653[i][j] = (-2L); + } + for (i = 0; i < 6; i++) + l_1180[i] = 0x47ABL; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 9; j++) + l_1400[i][j] = 0x4EL; + } + } + return &g_10; +} + + +/* ------------------------------------------ */ +/* + * reads : g_88 g_89 + * writes: + */ +static int32_t func_92(const uint16_t * p_93) +{ /* block id: 17 */ + uint8_t l_96 = 0x79L; + uint8_t l_135 = 0xE2L; + int32_t l_145 = 0x9B5C0F6DL; + const int32_t *l_153 = NULL; + int32_t l_157 = 0xF2D310D2L; + int32_t *l_182[6] = {&g_8[2],NULL,&g_8[2],&g_8[2],NULL,&g_8[2]}; + int32_t **l_181 = &l_182[3]; + int32_t l_195 = 0x4882324AL; + uint8_t l_196[9] = {0x74L,0xD3L,0x74L,0xD3L,0x74L,0xD3L,0x74L,0xD3L,0x74L}; + uint8_t l_241 = 0x45L; + int32_t *l_244 = &l_195; + uint16_t *l_266 = NULL; + int32_t ***l_312 = &l_181; + uint16_t l_333 = 65532UL; + uint16_t l_407 = 0UL; + uint8_t l_455 = 1UL; + int16_t **l_473 = NULL; + const int32_t *l_494 = &l_145; + int32_t l_513 = (-1L); + int16_t l_567 = 0x6F4BL; + int32_t *l_589 = &l_513; + int i; + return (*g_88); +} + + + + +/* ---------------------------------------- */ +int main (int argc, char* argv[]) +{ + int i, j, k; + int print_hash_value = 0; + if (argc == 2 && strcmp(argv[1], "1") == 0) print_hash_value = 1; + platform_main_begin(); + crc32_gentab(); + func_1(); + for (i = 0; i < 4; i++) + { + transparent_crc(g_8[i], "g_8[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_10, "g_10", print_hash_value); + transparent_crc(g_14, "g_14", print_hash_value); + transparent_crc(g_68, "g_68", print_hash_value); + transparent_crc(g_89, "g_89", print_hash_value); + transparent_crc(g_95, "g_95", print_hash_value); + for (i = 0; i < 1; i++) + { + for (j = 0; j < 2; j++) + { + for (k = 0; k < 5; k++) + { + transparent_crc(g_101[i][j][k], "g_101[i][j][k]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d][%d]\n", i, j, k); + + } + } + } + transparent_crc(g_168, "g_168", print_hash_value); + transparent_crc(g_175, "g_175", print_hash_value); + transparent_crc(g_177, "g_177", print_hash_value); + transparent_crc(g_208, "g_208", print_hash_value); + transparent_crc(g_263, "g_263", print_hash_value); + for (i = 0; i < 4; i++) + { + for (j = 0; j < 1; j++) + { + for (k = 0; k < 5; k++) + { + transparent_crc(g_324[i][j][k], "g_324[i][j][k]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d][%d]\n", i, j, k); + + } + } + } + transparent_crc(g_369, "g_369", print_hash_value); + transparent_crc(g_490, "g_490", print_hash_value); + transparent_crc(g_532, "g_532", print_hash_value); + transparent_crc(g_534, "g_534", print_hash_value); + for (i = 0; i < 1; i++) + { + for (j = 0; j < 5; j++) + { + transparent_crc(g_679[i][j], "g_679[i][j]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d]\n", i, j); + + } + } + transparent_crc(g_813, "g_813", print_hash_value); + transparent_crc(g_906, "g_906", print_hash_value); + transparent_crc(g_912, "g_912", print_hash_value); + transparent_crc(g_1098, "g_1098", print_hash_value); + transparent_crc(g_1555, "g_1555", print_hash_value); + transparent_crc(g_1566, "g_1566", print_hash_value); + transparent_crc(g_1611, "g_1611", print_hash_value); + for (i = 0; i < 8; i++) + { + transparent_crc(g_1671[i], "g_1671[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_1726, "g_1726", print_hash_value); + for (i = 0; i < 2; i++) + { + for (j = 0; j < 2; j++) + { + transparent_crc(g_1781[i][j], "g_1781[i][j]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d]\n", i, j); + + } + } + for (i = 0; i < 4; i++) + { + transparent_crc(g_1846[i], "g_1846[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + for (i = 0; i < 9; i++) + { + for (j = 0; j < 9; j++) + { + for (k = 0; k < 3; k++) + { + transparent_crc(g_1878[i][j][k], "g_1878[i][j][k]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d][%d]\n", i, j, k); + + } + } + } + transparent_crc(g_2002, "g_2002", print_hash_value); + platform_main_end(crc32_context ^ 0xFFFFFFFFUL, print_hash_value); + return 0; +} + +/************************ statistics ************************* +XXX max struct depth: 0 +breakdown: + depth: 0, occurrence: 489 +XXX total union variables: 0 + +XXX non-zero bitfields defined in structs: 0 +XXX zero bitfields defined in structs: 0 +XXX const bitfields defined in structs: 0 +XXX volatile bitfields defined in structs: 0 +XXX structs with bitfields in the program: 0 +breakdown: +XXX full-bitfields structs in the program: 0 +breakdown: +XXX times a bitfields struct's address is taken: 0 +XXX times a bitfields struct on LHS: 0 +XXX times a bitfields struct on RHS: 0 +XXX times a single bitfield on LHS: 0 +XXX times a single bitfield on RHS: 0 + +XXX max expression depth: 60 +breakdown: + depth: 1, occurrence: 97 + depth: 2, occurrence: 14 + depth: 3, occurrence: 5 + depth: 4, occurrence: 1 + depth: 8, occurrence: 1 + depth: 9, occurrence: 1 + depth: 18, occurrence: 2 + depth: 19, occurrence: 2 + depth: 20, occurrence: 1 + depth: 22, occurrence: 1 + depth: 24, occurrence: 2 + depth: 26, occurrence: 1 + depth: 28, occurrence: 1 + depth: 31, occurrence: 1 + depth: 33, occurrence: 2 + depth: 35, occurrence: 1 + depth: 39, occurrence: 1 + depth: 40, occurrence: 1 + depth: 41, occurrence: 1 + depth: 60, occurrence: 1 + +XXX total number of pointers: 435 + +XXX times a variable address is taken: 1134 +XXX times a pointer is dereferenced on RHS: 320 +breakdown: + depth: 1, occurrence: 285 + depth: 2, occurrence: 27 + depth: 3, occurrence: 8 +XXX times a pointer is dereferenced on LHS: 267 +breakdown: + depth: 1, occurrence: 244 + depth: 2, occurrence: 16 + depth: 3, occurrence: 6 + depth: 4, occurrence: 1 +XXX times a pointer is compared with null: 45 +XXX times a pointer is compared with address of another variable: 4 +XXX times a pointer is compared with another pointer: 14 +XXX times a pointer is qualified to be dereferenced: 7978 + +XXX max dereference level: 6 +breakdown: + level: 0, occurrence: 0 + level: 1, occurrence: 1190 + level: 2, occurrence: 134 + level: 3, occurrence: 79 + level: 4, occurrence: 27 + level: 5, occurrence: 11 + level: 6, occurrence: 13 +XXX number of pointers point to pointers: 171 +XXX number of pointers point to scalars: 264 +XXX number of pointers point to structs: 0 +XXX percent of pointers has null in alias set: 25.5 +XXX average alias set size: 1.48 + +XXX times a non-volatile is read: 1625 +XXX times a non-volatile is write: 810 +XXX times a volatile is read: 0 +XXX times read thru a pointer: 0 +XXX times a volatile is write: 0 +XXX times written thru a pointer: 0 +XXX times a volatile is available for access: 0 +XXX percentage of non-volatile access: 100 + +XXX forward jumps: 1 +XXX backward jumps: 5 + +XXX stmts: 92 +XXX max block depth: 5 +breakdown: + depth: 0, occurrence: 28 + depth: 1, occurrence: 11 + depth: 2, occurrence: 6 + depth: 3, occurrence: 9 + depth: 4, occurrence: 16 + depth: 5, occurrence: 22 + +XXX percentage a fresh-made variable is used: 15.8 +XXX percentage an existing variable is used: 84.2 +********************* end of statistics **********************/ + diff --git a/tests/fuzz/20.cpp.txt b/tests/fuzz/20.cpp.txt new file mode 100644 index 00000000..3bff09b8 --- /dev/null +++ b/tests/fuzz/20.cpp.txt @@ -0,0 +1 @@ +checksum = D5BDABA9 diff --git a/tests/fuzz/21.c b/tests/fuzz/21.c new file mode 100644 index 00000000..28720f01 --- /dev/null +++ b/tests/fuzz/21.c @@ -0,0 +1,2332 @@ +/* + * This is a RANDOMLY GENERATED PROGRAM. + * + * Generator: csmith 2.2.0 + * Git version: bf42ffd + * Options: --no-volatiles --no-packed-struct + * Seed: 642934944 + */ + +#include "csmith.h" + + +static long __undefined; + +/* --- Struct/Union Declarations --- */ +union U0 { + int8_t f0; + int8_t f1; + int16_t f2; + int8_t f3; +}; + +/* --- GLOBAL VARIABLES --- */ +static int32_t g_4[5] = {0x21DED680L,0x21DED680L,0x21DED680L,0x21DED680L,0x21DED680L}; +static int32_t g_20 = 0L; +static int32_t g_67[7] = {2L,2L,2L,2L,2L,2L,2L}; +static int32_t g_75[3] = {2L,2L,2L}; +static uint16_t g_78 = 0x7081L; +static int64_t g_91 = 0xAECDC9E869F92A77LL; +static int64_t g_128[2][4][3] = {{{4L,(-7L),4L},{4L,0x14A00EA68498C81BLL,(-7L)},{0x14A00EA68498C81BLL,4L,4L},{(-7L),4L,0L}},{{(-1L),0x14A00EA68498C81BLL,1L},{(-7L),(-7L),1L},{0x14A00EA68498C81BLL,(-1L),0L},{4L,(-7L),4L}}}; +static int64_t *g_127 = &g_128[0][3][1]; +static uint8_t g_130 = 8UL; +static uint64_t g_132 = 18446744073709551615UL; +static uint64_t g_133 = 1UL; +static int32_t g_135 = 1L; +static int32_t g_146 = 0x0234A52FL; +static uint32_t g_147 = 0x4143BCCAL; +static uint32_t g_159 = 0x38252909L; +static uint16_t g_177 = 1UL; +static uint8_t g_183 = 0xB9L; +static uint32_t g_204 = 6UL; +static uint8_t g_206 = 0UL; +static union U0 g_209 = {0xF0L}; +static int64_t g_253 = 0xFB460BE9092F00DDLL; +static uint32_t g_254 = 0xA3D898C3L; +static uint32_t g_258[8] = {18446744073709551615UL,0x8629A8D4L,18446744073709551615UL,0x8629A8D4L,18446744073709551615UL,0x8629A8D4L,18446744073709551615UL,0x8629A8D4L}; +static const int32_t *g_268 = &g_4[3]; +static const int32_t **g_267 = &g_268; +static const uint16_t g_274 = 0xF497L; +static int64_t **g_277[1] = {&g_127}; +static int64_t ***g_276 = &g_277[0]; +static uint64_t *g_333[8][2] = {{&g_133,&g_132},{&g_133,&g_132},{&g_133,&g_133},{(void*)0,(void*)0},{(void*)0,&g_133},{&g_133,&g_132},{&g_133,&g_132},{&g_133,&g_133}}; +static uint16_t g_380 = 0x0529L; +static int16_t g_383 = 1L; +static int16_t g_384 = 0xD1D2L; +static int16_t g_408 = 0x2866L; +static uint16_t g_409[1][4] = {{0xA1F1L,0xA1F1L,0xA1F1L,0xA1F1L}}; +static uint8_t *g_442 = (void*)0; +static uint8_t **g_441 = &g_442; +static union U0 g_458 = {0x3BL}; +static union U0 *g_457 = &g_458; +static int32_t g_471 = 0L; +static uint16_t g_578 = 0UL; +static uint64_t g_629 = 0UL; +static uint16_t *g_643 = &g_177; +static uint16_t **g_642 = &g_643; +static uint32_t *g_648 = &g_258[5]; +static uint32_t **g_647[9][8] = {{(void*)0,(void*)0,&g_648,(void*)0,(void*)0,&g_648,&g_648,&g_648},{(void*)0,&g_648,(void*)0,&g_648,&g_648,(void*)0,&g_648,(void*)0},{&g_648,&g_648,(void*)0,&g_648,&g_648,(void*)0,&g_648,&g_648},{&g_648,&g_648,&g_648,&g_648,&g_648,(void*)0,(void*)0,(void*)0},{(void*)0,&g_648,&g_648,&g_648,&g_648,(void*)0,&g_648,&g_648},{(void*)0,&g_648,(void*)0,&g_648,&g_648,&g_648,(void*)0,&g_648},{&g_648,(void*)0,(void*)0,&g_648,&g_648,&g_648,&g_648,&g_648},{&g_648,&g_648,&g_648,&g_648,&g_648,&g_648,&g_648,(void*)0},{(void*)0,&g_648,(void*)0,&g_648,(void*)0,&g_648,(void*)0,&g_648}}; +static int8_t g_708 = (-6L); +static int64_t g_746 = 0xB223B77F3AA8293ALL; +static int64_t g_778 = 0x798751D9133BB1D3LL; +static uint64_t ** const g_856 = &g_333[7][0]; +static uint64_t ** const *g_855 = &g_856; +static uint16_t g_888 = 0x8340L; +static uint8_t *g_983 = &g_130; +static int32_t *g_1000 = &g_20; +static int32_t **g_999 = &g_1000; +static int64_t g_1086 = 8L; +static int32_t ***g_1175 = &g_999; +static const union U0 ***g_1185 = (void*)0; +static int8_t g_1326 = 0x8EL; +static int64_t **g_1334 = (void*)0; +static const int64_t g_1337 = 0L; +static int8_t g_1413 = (-3L); +static uint64_t **g_1569[9] = {(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}; +static uint64_t ***g_1568[5][3] = {{&g_1569[6],&g_1569[6],&g_1569[5]},{&g_1569[5],&g_1569[2],&g_1569[6]},{&g_1569[1],&g_1569[6],&g_1569[1]},{&g_1569[1],&g_1569[5],&g_1569[6]},{&g_1569[5],&g_1569[1],&g_1569[1]}}; +static uint64_t ****g_1567 = &g_1568[4][0]; +static uint16_t * const *g_1574 = &g_643; +static uint16_t * const **g_1573[3] = {&g_1574,&g_1574,&g_1574}; +static uint64_t g_1585 = 0x597575CF89740C88LL; +static const int8_t g_1622 = 8L; +static int32_t g_1679 = (-2L); +static uint32_t *g_1701 = &g_254; +static uint32_t **g_1700 = &g_1701; +static int32_t *g_1707 = (void*)0; +static const int16_t *g_1739 = &g_384; +static const int16_t ** const g_1738[3][1][7] = {{{&g_1739,&g_1739,&g_1739,&g_1739,(void*)0,&g_1739,&g_1739}},{{&g_1739,&g_1739,&g_1739,&g_1739,&g_1739,&g_1739,&g_1739}},{{&g_1739,&g_1739,(void*)0,&g_1739,&g_1739,&g_1739,&g_1739}}}; +static const int16_t **g_1744 = &g_1739; +static uint32_t g_1860 = 0x5534D26BL; +static uint32_t ***g_1926[3] = {(void*)0,(void*)0,(void*)0}; +static int32_t g_1962 = (-2L); +static int32_t g_2033[10] = {0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L,0x3E7186E9L}; +static uint32_t ** const ***g_2089 = (void*)0; +static union U0 g_2193 = {0xBDL}; +static int16_t **g_2230 = (void*)0; +static int64_t g_2307 = 0L; +static uint32_t g_2497 = 0xD94C2BE8L; +static int32_t g_2508 = 0xB8F83451L; +static int32_t * const *g_2622 = &g_1000; +static int32_t * const **g_2621 = &g_2622; +static int32_t * const ***g_2620 = &g_2621; +static const uint16_t *g_2632 = &g_380; +static const uint16_t **g_2631 = &g_2632; +static const uint16_t ***g_2630[9] = {&g_2631,&g_2631,&g_2631,&g_2631,&g_2631,&g_2631,&g_2631,&g_2631,&g_2631}; +static uint32_t g_2648 = 0x9D64EF08L; +static int32_t g_2767 = 0x9B96E27FL; +static uint64_t g_2797 = 18446744073709551615UL; +static uint64_t g_2866 = 0x116C815868EB1DEBLL; +static uint32_t g_2895 = 8UL; +static int32_t ****g_2978 = &g_1175; +static uint16_t *** const *g_2981 = (void*)0; +static uint16_t *** const ** const g_2980 = &g_2981; +static uint16_t **g_3116 = &g_643; +static uint8_t g_3176[4] = {251UL,251UL,251UL,251UL}; +static int8_t g_3254 = 0xDDL; +static int64_t g_3261 = 8L; +static uint32_t ***g_3310 = &g_647[5][0]; +static uint32_t ***g_3311 = &g_647[5][0]; +static uint32_t g_3322[7] = {0x55EF5714L,0x55EF5714L,0x55EF5714L,0x55EF5714L,0x55EF5714L,0x55EF5714L,0x55EF5714L}; +static int8_t *g_3328 = (void*)0; +static uint16_t g_3340 = 0x2720L; +static const uint16_t **** const g_3349 = &g_2630[4]; +static const uint16_t **** const *g_3348 = &g_3349; +static int32_t g_3407 = 0xDAD5159FL; +static uint32_t g_3485 = 0xEE071645L; +static int32_t g_3515 = 0xC406C7B2L; +static int32_t g_3578 = 8L; +static int16_t **** const g_3593 = (void*)0; +static uint32_t ****g_3601 = &g_1926[2]; +static uint32_t *****g_3600[7][3][8] = {{{&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601},{&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601,(void*)0,(void*)0},{&g_3601,(void*)0,&g_3601,(void*)0,&g_3601,(void*)0,(void*)0,&g_3601}},{{&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601},{&g_3601,&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,(void*)0},{(void*)0,&g_3601,(void*)0,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601}},{{&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,(void*)0,&g_3601,&g_3601},{&g_3601,(void*)0,&g_3601,&g_3601,(void*)0,(void*)0,&g_3601,&g_3601},{(void*)0,&g_3601,(void*)0,(void*)0,&g_3601,&g_3601,&g_3601,(void*)0}},{{(void*)0,(void*)0,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601},{&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601},{&g_3601,&g_3601,&g_3601,&g_3601,(void*)0,(void*)0,&g_3601,&g_3601}},{{&g_3601,&g_3601,(void*)0,&g_3601,(void*)0,&g_3601,(void*)0,&g_3601},{&g_3601,&g_3601,&g_3601,(void*)0,&g_3601,(void*)0,&g_3601,&g_3601},{&g_3601,&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601}},{{(void*)0,(void*)0,&g_3601,(void*)0,&g_3601,&g_3601,(void*)0,&g_3601},{&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,(void*)0,&g_3601,&g_3601},{&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601}},{{&g_3601,&g_3601,&g_3601,&g_3601,&g_3601,(void*)0,&g_3601,&g_3601},{&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601},{&g_3601,&g_3601,(void*)0,&g_3601,&g_3601,&g_3601,&g_3601,&g_3601}}}; +static int16_t *g_3706 = (void*)0; +static int16_t **g_3705 = &g_3706; +static const uint32_t *g_3714 = &g_1860; +static const uint32_t **g_3713[3] = {&g_3714,&g_3714,&g_3714}; +static uint64_t *****g_3772 = &g_1567; +static uint64_t ******g_3771 = &g_3772; +static uint32_t g_3815 = 18446744073709551615UL; +static const uint32_t g_3847 = 4294967293UL; +static int16_t g_3879 = 0x5935L; +static int32_t g_3880 = 0x2FDB7342L; +static int64_t * const g_3913 = &g_253; + + +/* --- FORWARD DECLARATIONS --- */ +static int16_t func_1(void); +static int32_t * func_13(uint8_t p_14); +static uint64_t func_34(int32_t p_35, uint64_t p_36, int8_t p_37, int32_t * p_38); +static union U0 func_48(int32_t * p_49, int32_t p_50); +static int32_t * func_51(int8_t p_52, uint16_t p_53, uint16_t p_54, int32_t * p_55, int32_t * p_56); +static int32_t * func_57(int32_t * p_58, const int32_t * p_59, int32_t * p_60, int32_t p_61, int32_t * p_62); +static int32_t * func_63(uint32_t p_64, int32_t * p_65); +static int32_t func_68(int32_t p_69, uint32_t p_70, int8_t p_71, int16_t p_72, int64_t p_73); +static union U0 func_97(const int32_t * p_98); +static const int32_t * func_99(uint16_t p_100, int16_t p_101, union U0 p_102, int64_t * const p_103, int64_t * p_104); + + +/* --- FUNCTIONS --- */ +/* ------------------------------------------ */ +/* + * reads : g_4 g_999 g_1000 g_1175 g_983 g_130 g_457 g_458 g_642 g_1744 g_1739 g_384 g_578 g_2621 g_2622 g_20 g_276 g_277 g_2620 g_2797 g_1700 g_1701 g_254 g_253 g_127 g_128 g_2497 g_1574 g_643 g_177 g_146 g_2631 g_2632 g_380 g_648 g_258 g_274 g_268 g_209.f1 g_133 g_458.f1 g_3261 g_629 g_458.f3 g_2033 g_3322 g_132 g_3340 g_2895 g_3348 g_888 g_2193.f1 g_441 g_442 g_267 g_746 g_3116 g_408 g_471 g_209 g_3485 g_75 g_2978 g_2980 g_2981 g_3349 g_1738 g_147 g_78 g_458.f2 g_1679 g_91 g_159 g_135 g_67 g_183 g_206 g_204 g_209.f0 g_209.f3 g_856 g_333 g_458.f0 g_3593 g_778 g_3176 g_3578 g_1337 g_2630 g_409 g_1086 g_3713 g_3771 g_3714 g_1860 g_1567 g_1568 g_1185 g_3515 g_3815 g_3847 g_3310 g_647 g_3879 g_3772 g_3913 g_3407 + * writes: g_4 g_20 g_1000 g_643 g_277 g_2797 g_3176 g_146 g_254 g_177 g_128 g_2193.f1 g_209.f1 g_130 g_133 g_629 g_458.f3 g_441 g_3328 g_132 g_3340 g_2895 g_3348 g_888 g_268 g_457 g_75 g_408 g_3485 g_1744 g_458.f2 g_1567 g_1679 g_127 g_147 g_159 g_183 g_135 g_204 g_206 g_258 g_267 g_333 g_3515 g_3600 g_209 g_3578 g_384 g_1086 g_3705 g_3713 g_1568 g_91 g_3879 g_3407 g_3254 g_458 + */ +static int16_t func_1(void) +{ /* block id: 0 */ + uint32_t l_2 = 4294967295UL; + int32_t l_5 = 0x8A527335L; + int32_t l_6 = 0x11BC383CL; + int32_t l_7 = 0x79041289L; + uint16_t ** const *l_3150 = &g_642; + int8_t *l_3158 = &g_2193.f1; + union U0 *l_3298 = &g_209; + uint32_t ***l_3308 = &g_647[7][6]; + uint32_t **l_3346[6][8] = {{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701}}; + int32_t l_3362 = 0x16A6D5DAL; + int32_t l_3363 = 0L; + int32_t l_3368 = 1L; + int32_t l_3369 = (-1L); + int32_t l_3370 = 0x7D45392EL; + int32_t l_3371 = (-10L); + int64_t l_3374 = 0L; + uint64_t l_3375 = 0x3D38361B79A4DC58LL; + uint64_t *****l_3385 = &g_1567; + uint16_t l_3419[4]; + int8_t l_3446[6] = {2L,2L,2L,2L,2L,2L}; + uint32_t l_3495 = 18446744073709551615UL; + const union U0 *l_3532 = &g_458; + const union U0 **l_3531 = &l_3532; + const union U0 ***l_3530 = &l_3531; + int8_t l_3544 = 0L; + uint8_t l_3580 = 255UL; + int16_t * const l_3597 = &g_384; + int16_t * const *l_3596 = &l_3597; + int16_t * const **l_3595 = &l_3596; + uint64_t l_3656 = 0x5FE4D132F8BD5F31LL; + int16_t l_3664 = 0xE475L; + int16_t *l_3704 = &g_384; + int16_t **l_3703 = &l_3704; + int32_t l_3735 = 0x57B5ED23L; + int32_t l_3736 = 0xEE9E89C4L; + const uint32_t ***l_3825[2][1]; + uint8_t l_3908 = 5UL; + uint64_t **** const *l_3909[6]; + int32_t l_3912[4]; + int32_t l_3944 = 0x194E005FL; + uint32_t l_3950 = 0UL; + uint32_t ******l_3989 = &g_3600[3][1][4]; + uint16_t l_4017 = 0x3BADL; + int i, j; + for (i = 0; i < 4; i++) + l_3419[i] = 0x9737L; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 1; j++) + l_3825[i][j] = &g_3713[1]; + } + for (i = 0; i < 6; i++) + l_3909[i] = &g_1567; + for (i = 0; i < 4; i++) + l_3912[i] = (-2L); + if ((l_2 & 0x3E90A624CDB8FAAALL)) + { /* block id: 1 */ + int32_t *l_3[8][10][2]; + uint16_t l_8[9] = {0x26AFL,0x26AFL,0x26AFL,0x26AFL,0x26AFL,0x26AFL,0x26AFL,0x26AFL,0x26AFL}; + uint32_t ** const *l_3144[9][2][5] = {{{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700},{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700}},{{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700},{&g_1700,&g_1700,&g_1700,&g_1700,(void*)0}},{{&g_1700,(void*)0,&g_1700,&g_1700,&g_1700},{&g_1700,(void*)0,&g_1700,&g_1700,&g_1700}},{{&g_1700,(void*)0,&g_1700,(void*)0,(void*)0},{&g_1700,(void*)0,&g_1700,&g_1700,&g_1700}},{{&g_1700,&g_1700,&g_1700,&g_1700,(void*)0},{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700}},{{&g_1700,&g_1700,&g_1700,(void*)0,&g_1700},{&g_1700,&g_1700,&g_1700,(void*)0,(void*)0}},{{&g_1700,&g_1700,&g_1700,(void*)0,&g_1700},{&g_1700,&g_1700,&g_1700,(void*)0,&g_1700}},{{&g_1700,(void*)0,&g_1700,(void*)0,&g_1700},{&g_1700,&g_1700,&g_1700,(void*)0,&g_1700}},{{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700},{&g_1700,&g_1700,&g_1700,&g_1700,&g_1700}}}; + uint32_t ** const **l_3143 = &l_3144[0][0][3]; + uint32_t ** const ***l_3142 = &l_3143; + union U0 l_3228 = {0x13L}; + uint64_t *l_3240 = &g_133; + uint32_t * const *l_3315 = &g_648; + uint32_t * const * const *l_3314 = &l_3315; + int32_t l_3388 = 1L; + uint64_t *****l_3389 = &g_1567; + uint8_t *l_3426 = (void*)0; + union U0 *l_3438 = &l_3228; + uint64_t l_3523 = 0x5F8208EF81CF263DLL; + union U0 **l_3534[7] = {&g_457,&g_457,&g_457,&g_457,&g_457,&g_457,&g_457}; + union U0 ***l_3533 = &l_3534[5]; + int16_t *l_3542[5]; + int16_t l_3554 = 3L; + int8_t l_3590[9] = {(-8L),(-8L),(-8L),(-8L),(-8L),(-8L),(-8L),(-8L),(-8L)}; + uint32_t *****l_3598 = (void*)0; + int64_t l_3625 = 9L; + uint16_t l_3626 = 65535UL; + uint32_t *l_3659 = &g_258[6]; + int32_t l_3790[2][8] = {{0xFAB70EA6L,0L,0x05281176L,0L,0xFAB70EA6L,0xFAB70EA6L,0L,0x05281176L},{0xFAB70EA6L,0xFAB70EA6L,0L,0x05281176L,0L,0xFAB70EA6L,0xFAB70EA6L,0L}}; + uint64_t l_3812 = 3UL; + uint64_t l_3814 = 18446744073709551608UL; + uint16_t **l_3827[3]; + uint64_t l_3829 = 18446744073709551615UL; + uint32_t l_3846 = 1UL; + uint16_t *****l_3857 = (void*)0; + const uint16_t ****l_3859 = &g_2630[5]; + const uint16_t *****l_3858 = &l_3859; + int i, j, k; + for (i = 0; i < 8; i++) + { + for (j = 0; j < 10; j++) + { + for (k = 0; k < 2; k++) + l_3[i][j][k] = &g_4[3]; + } + } + for (i = 0; i < 5; i++) + l_3542[i] = &g_383; + for (i = 0; i < 3; i++) + l_3827[i] = &g_643; +lbl_3151: + l_8[1]++; + for (l_6 = (-2); (l_6 > 15); l_6 = safe_add_func_uint8_t_u_u(l_6, 6)) + { /* block id: 5 */ + uint64_t l_3138 = 0x57C7955DEB977126LL; + union U0 **l_3154 = &g_457; + const int64_t *l_3156 = &g_128[1][0][1]; + const int64_t **l_3155[2][2][6] = {{{&l_3156,&l_3156,&l_3156,&l_3156,&l_3156,&l_3156},{&l_3156,&l_3156,&l_3156,&l_3156,&l_3156,&l_3156}},{{&l_3156,&l_3156,&l_3156,&l_3156,&l_3156,&l_3156},{&l_3156,&l_3156,&l_3156,&l_3156,&l_3156,&l_3156}}}; + const int64_t ***l_3157 = &l_3155[0][1][3]; + uint16_t l_3165[8] = {1UL,1UL,1UL,1UL,1UL,1UL,1UL,1UL}; + int i, j, k; + for (l_7 = 8; (l_7 >= 1); l_7 -= 1) + { /* block id: 8 */ + uint32_t l_3141 = 18446744073709551615UL; + uint32_t * const ***l_3146 = (void*)0; + uint32_t * const *** const *l_3145 = &l_3146; + union U0 **l_3147 = &g_457; + int i; + g_4[3] |= l_8[l_7]; + (**g_1175) = func_13(g_4[2]); + if (l_8[l_7]) + { /* block id: 1459 */ + uint16_t *l_3133 = &l_8[8]; + uint16_t *l_3139 = &l_8[l_7]; + int32_t l_3140 = 0xF695A281L; + uint16_t ***l_3149 = &g_3116; + uint16_t ****l_3148 = &l_3149; + (***g_2621) &= (safe_mod_func_uint8_t_u_u((((*l_3148) = ((((((safe_mod_func_int16_t_s_s((((safe_rshift_func_int8_t_s_u((((((safe_lshift_func_uint8_t_u_u((*g_983), (safe_rshift_func_uint16_t_u_u(l_8[l_7], (((*g_457) , ((((safe_rshift_func_int8_t_s_u(((((*g_642) = l_3133) != (((safe_mul_func_uint8_t_u_u(0x6AL, 0xD8L)) || (safe_rshift_func_uint16_t_u_s(l_3138, (**g_1744)))) , l_3139)) < 0xC0D6B72D1B8F337DLL), 1)) , l_3140) > 0L) & g_578)) >= l_3138))))) ^ l_3141) < (*g_983)) , l_3142) != l_3145), (*g_983))) > l_6) , (**g_1744)), l_6)) ^ l_3140) , (**g_1744)) , l_3147) != (void*)0) , &g_3116)) == l_3150), 0x4FL)); + } + else + { /* block id: 1463 */ + (**g_999) ^= l_7; + if (l_7) + goto lbl_3151; + } + } + (****g_2620) = (safe_rshift_func_int16_t_s_s((((((void*)0 != l_3154) , ((*g_276) = (*g_276))) == ((*l_3157) = l_3155[0][1][3])) < (l_3158 == (void*)0)), 0)); + for (g_2797 = 0; (g_2797 >= 54); ++g_2797) + { /* block id: 1473 */ + int32_t l_3166[8][8][3] = {{{0x36A42BD7L,0x08DAE5F5L,0L},{0x3FB3DE0AL,0xDD914932L,(-5L)},{7L,7L,0xD3200B0DL},{1L,(-5L),0xB59C95F6L},{9L,7L,(-5L)},{0xDD914932L,0xC624916FL,0x3FB3DE0AL},{0x36A42BD7L,9L,(-5L)},{0x97CD9E59L,0xB59C95F6L,0xB59C95F6L}},{{0L,(-1L),0x08DAE5F5L},{0L,0x08DAE5F5L,0x36A42BD7L},{0x97CD9E59L,1L,0x7D66C06FL},{0x36A42BD7L,0xDD914932L,7L},{0xDD914932L,1L,0x63FDB9F2L},{9L,0x08DAE5F5L,9L},{1L,(-1L),9L},{(-5L),0xB59C95F6L,0x63FDB9F2L}},{{0x63FDB9F2L,9L,7L},{(-1L),0xC624916FL,0x7D66C06FL},{0x63FDB9F2L,7L,0x36A42BD7L},{(-5L),(-5L),0x08DAE5F5L},{1L,(-5L),0xB59C95F6L},{9L,7L,(-5L)},{0xDD914932L,0xC624916FL,0x3FB3DE0AL},{0x36A42BD7L,9L,(-5L)}},{{0x97CD9E59L,0xB59C95F6L,0xB59C95F6L},{0L,(-1L),0x08DAE5F5L},{0L,0x08DAE5F5L,0x36A42BD7L},{0x97CD9E59L,1L,0x7D66C06FL},{0x36A42BD7L,0xDD914932L,7L},{0xDD914932L,1L,0x63FDB9F2L},{9L,0x08DAE5F5L,9L},{1L,(-1L),9L}},{{(-5L),0xB59C95F6L,0x63FDB9F2L},{0x63FDB9F2L,9L,7L},{(-1L),0xC624916FL,0x7D66C06FL},{0x63FDB9F2L,7L,0x36A42BD7L},{(-5L),(-5L),0x08DAE5F5L},{1L,(-5L),0xB59C95F6L},{9L,7L,(-5L)},{0xDD914932L,0xC624916FL,0x3FB3DE0AL}},{{0x36A42BD7L,9L,(-5L)},{0x97CD9E59L,0xB59C95F6L,0xB59C95F6L},{0L,(-1L),0x08DAE5F5L},{0L,0x08DAE5F5L,0x36A42BD7L},{0x97CD9E59L,1L,0x7D66C06FL},{0x36A42BD7L,0xDD914932L,7L},{0xDD914932L,1L,0x63FDB9F2L},{9L,0x08DAE5F5L,9L}},{{1L,(-1L),9L},{(-5L),0xB59C95F6L,0x63FDB9F2L},{0x63FDB9F2L,9L,7L},{(-1L),0xC624916FL,0x7D66C06FL},{0x63FDB9F2L,7L,0x36A42BD7L},{(-5L),(-5L),0x08DAE5F5L},{1L,(-5L),0xB59C95F6L},{9L,7L,(-5L)}},{{0xDD914932L,0xC624916FL,0x3FB3DE0AL},{0x36A42BD7L,9L,(-5L)},{0x97CD9E59L,0xB59C95F6L,0xB59C95F6L},{0L,(-1L),0x08DAE5F5L},{0L,0x08DAE5F5L,0x36A42BD7L},{0x97CD9E59L,1L,0x7D66C06FL},{0x36A42BD7L,0xDD914932L,7L},{0xDD914932L,1L,0x63FDB9F2L}}}; + union U0 *l_3167 = (void*)0; + uint32_t l_3175[10]; + int i, j, k; + for (i = 0; i < 10; i++) + l_3175[i] = 0UL; + g_3176[0] = (((safe_div_func_int32_t_s_s(l_2, ((**g_999) , (safe_mul_func_int8_t_s_s((l_3165[1] != (l_3166[1][2][2] < (((l_3165[5] , (void*)0) != l_3167) >= ((safe_mod_func_uint16_t_u_u((safe_unary_minus_func_int32_t_s(((*g_983) , ((***g_2621) |= (safe_div_func_int32_t_s_s(((safe_add_func_uint32_t_u_u(((*g_983) > 0UL), (**g_1700))) >= 4UL), 1UL)))))), l_3165[1])) && 0x27EDL)))), g_253))))) , 0xCDD9L) && l_3175[6]); + } + } + if ((***g_2621)) + { /* block id: 1478 */ + uint32_t **l_3185 = &g_1701; + int32_t l_3186 = 0xDDB13C5AL; + uint64_t *****l_3198 = &g_1567; + uint64_t ******l_3197 = &l_3198; + int32_t l_3229 = 0xCC934D37L; + uint32_t **l_3282 = &g_648; + uint64_t l_3352 = 18446744073709551615UL; + int32_t l_3408 = 1L; + int32_t l_3409 = 8L; + uint32_t l_3410 = 0UL; + int32_t l_3413 = 0x1B38E9A0L; + int64_t l_3414 = 1L; + int32_t l_3415 = 0L; + int32_t l_3416 = (-10L); + int32_t l_3417 = 0x826CAA3AL; + int32_t l_3418 = (-10L); + if (((((safe_add_func_uint8_t_u_u((safe_rshift_func_int8_t_s_s((((*g_457) , (***g_276)) ^ 0x90099C64A4CC214BLL), 4)), g_2497)) , l_3186) & 0xD30FF6655B03D0F7LL) < (**g_1574))) + { /* block id: 1480 */ + uint32_t l_3187[3][8] = {{0x13CA3311L,5UL,0x6BA18EA5L,5UL,0x13CA3311L,0x13CA3311L,5UL,0x6BA18EA5L},{5UL,5UL,18446744073709551615UL,18446744073709551615UL,18446744073709551615UL,5UL,5UL,18446744073709551615UL},{0x6BA18EA5L,18446744073709551615UL,18446744073709551615UL,0x6BA18EA5L,0x13CA3311L,0x6BA18EA5L,18446744073709551615UL,18446744073709551615UL}}; + int8_t l_3205 = 0x03L; + int16_t *l_3217 = &g_408; + int16_t * const l_3219 = (void*)0; + int32_t l_3230[4] = {(-8L),(-8L),(-8L),(-8L)}; + uint8_t l_3231 = 0x75L; + int8_t l_3257[10][5][5] = {{{0L,0x77L,(-7L),0xFBL,0xFBL},{0L,3L,0L,(-4L),(-2L)},{0L,(-7L),1L,0x4AL,1L},{(-10L),0xB6L,(-4L),0x50L,(-1L)},{(-1L),0x33L,1L,1L,0xD2L}},{{0x0CL,0x18L,0L,(-1L),(-7L)},{(-1L),(-1L),(-7L),0x8FL,7L},{5L,0x0CL,0x2DL,5L,0x6AL},{1L,7L,0x56L,0x79L,0x1DL},{0x15L,0x9DL,(-1L),0x42L,0xE5L}},{{0xEDL,(-1L),0L,(-8L),1L},{0L,0x8CL,(-2L),(-2L),0x8CL},{0L,0L,0x05L,0x77L,0x3EL},{0L,(-1L),0L,0x2DL,(-4L)},{0xFBL,0x08L,0xE9L,6L,(-5L)}},{{0L,(-10L),0L,8L,0x81L},{0L,(-9L),0xEDL,0x3EL,(-1L)},{0L,0x93L,1L,0xB6L,5L},{0xEDL,0xEDL,0xF1L,0xD6L,(-9L)},{0x15L,(-1L),(-1L),0x8CL,3L}},{{1L,0x66L,0x24L,0x10L,0x56L},{5L,0x34L,0L,0xB1L,8L},{(-1L),(-5L),(-5L),(-1L),(-6L)},{0x0CL,0x50L,8L,0L,5L},{(-1L),6L,0x10L,1L,(-1L)}},{{(-10L),0x67L,0xE5L,0L,0x0FL},{0L,0x4AL,0xE8L,(-1L),(-1L)},{0L,(-1L),(-7L),0xB1L,0L},{0L,(-1L),1L,0x10L,0x8FL},{0xE5L,0x2DL,(-1L),0x8CL,0x67L}},{{(-8L),(-1L),0x33L,0xD6L,0L},{0x50L,0x6AL,0L,0xB6L,0x9DL},{(-1L),1L,0x66L,0x3EL,0x66L},{1L,1L,(-10L),8L,4L},{(-9L),(-7L),(-6L),(-9L),(-1L)}},{{0x93L,0x33L,0x12L,(-1L),1L},{(-1L),(-7L),0xEDL,1L,0x77L},{4L,0x0FL,0x50L,0x93L,0x0CL},{0xE9L,0x10L,0xD8L,0xF1L,0x8FL},{(-2L),(-1L),(-10L),0L,0L}},{{(-7L),1L,0x42L,7L,(-6L)},{(-10L),(-1L),0x13L,(-4L),0x67L},{0x04L,0xEDL,0x3EL,(-6L),7L},{0L,0x15L,0L,0x15L,0L},{0xD2L,(-6L),0xF1L,(-1L),0x3EL}},{{8L,0L,5L,(-7L),(-2L)},{0x77L,(-9L),(-1L),(-6L),0x3EL},{(-1L),(-7L),0L,(-1L),0L},{0x3EL,0x06L,0x77L,(-1L),7L},{(-1L),0x12L,(-1L),0x50L,0x67L}}}; + const int64_t **l_3264 = (void*)0; + uint32_t **l_3281 = &g_648; + int i, j, k; + for (g_146 = 0; (g_146 <= 1); g_146 += 1) + { /* block id: 1483 */ + uint32_t l_3192 = 1UL; + union U0 *l_3214[3]; + int32_t l_3255 = (-1L); + int i; + for (i = 0; i < 3; i++) + l_3214[i] = &g_458; + ++l_3187[2][6]; + if ((safe_sub_func_int64_t_s_s(((*g_127) = (!(l_3192 < ((((--(**g_1700)) | ((safe_div_func_int16_t_s_s((((void*)0 != l_3197) > (l_3186 & l_3186)), ((**g_642) = (safe_mul_func_int8_t_s_s((safe_sub_func_uint16_t_u_u(((**g_2631) , l_2), ((safe_mod_func_uint16_t_u_u(((*g_648) , 4UL), (**g_2631))) >= g_274))), 1UL))))) > 0x8E3D84382D7D5000LL)) ^ 0x34L) >= 0UL)))), l_3205))) + { /* block id: 1488 */ + int8_t l_3213 = 0xEEL; + int16_t **l_3218 = &l_3217; + int32_t l_3232 = (-1L); + int32_t l_3233 = 1L; + if (l_3192) + break; + l_3232 &= ((safe_add_func_uint8_t_u_u((safe_div_func_int8_t_s_s((safe_rshift_func_uint16_t_u_s(((safe_unary_minus_func_uint16_t_u(((g_254 & l_3213) > ((void*)0 == l_3214[1])))) > (safe_mul_func_int8_t_s_s((((*l_3218) = l_3217) == l_3219), (safe_rshift_func_int8_t_s_s(((*l_3158) = ((safe_div_func_uint32_t_u_u(((safe_mod_func_int16_t_s_s(((l_3230[2] = ((safe_rshift_func_uint8_t_u_u((((l_3187[2][6] & (((l_3228 , (*g_457)) , 253UL) || l_3192)) != l_3229) & l_3192), 1)) != (***g_2621))) > l_3192), (**g_1744))) == (*g_268)), 0xFC91D86FL)) != l_3231)), l_7))))), (*g_1739))), 248UL)), 250UL)) < 255UL); + return l_3233; + } + else + { /* block id: 1495 */ + (*g_999) = (**g_1175); + } + if (l_2) + continue; + for (g_209.f1 = 0; (g_209.f1 <= 1); g_209.f1 += 1) + { /* block id: 1501 */ + uint8_t *l_3241[9][8][3] = {{{&l_3231,&l_3231,&l_3231},{&g_3176[3],(void*)0,&g_183},{&l_3231,(void*)0,&l_3231},{&g_183,&g_3176[3],&g_3176[3]},{&g_206,(void*)0,(void*)0},{&g_183,&g_183,&g_206},{&l_3231,&g_3176[0],&g_206},{&g_3176[3],&g_183,&g_3176[3]}},{{&l_3231,(void*)0,&g_3176[0]},{(void*)0,&g_3176[3],&g_3176[3]},{&g_3176[0],(void*)0,&g_206},{&g_183,(void*)0,&g_206},{&g_3176[0],&l_3231,(void*)0},{(void*)0,&g_183,&g_3176[3]},{&l_3231,&l_3231,&l_3231},{&g_3176[3],(void*)0,&g_183}},{{&l_3231,(void*)0,&l_3231},{&g_183,&g_3176[3],&g_3176[3]},{&g_206,(void*)0,(void*)0},{&g_183,&g_183,&g_206},{&l_3231,&g_3176[0],&g_206},{&g_3176[3],&g_183,&g_3176[3]},{&l_3231,(void*)0,&g_3176[0]},{(void*)0,&g_3176[3],&g_3176[3]}},{{&g_3176[0],(void*)0,&g_206},{&g_183,(void*)0,&g_206},{&g_3176[0],&l_3231,(void*)0},{(void*)0,&g_183,&g_3176[3]},{&l_3231,&l_3231,&l_3231},{&g_3176[3],(void*)0,&g_183},{&l_3231,(void*)0,&l_3231},{&g_183,&g_3176[3],&g_3176[3]}},{{&g_206,(void*)0,(void*)0},{&g_183,&g_183,&g_206},{&l_3231,&g_3176[0],&g_206},{&g_3176[3],&g_183,&g_3176[3]},{&l_3231,(void*)0,&g_3176[0]},{&g_3176[3],&g_183,&g_183},{&g_183,&g_3176[0],(void*)0},{&g_3176[3],&g_3176[3],&g_183}},{{&g_183,(void*)0,&g_3176[0]},{&g_3176[3],&g_3176[3],&g_206},{&g_206,(void*)0,&g_206},{&g_183,&g_3176[3],&g_206},{&l_3231,&g_3176[0],&g_206},{&g_206,&g_183,&g_206},{&g_206,(void*)0,&g_3176[0]},{&g_206,&g_206,&g_183}},{{&l_3231,(void*)0,(void*)0},{&g_183,&g_206,&g_183},{&g_206,(void*)0,&g_183},{&g_3176[3],&g_183,&g_183},{&g_183,&g_3176[0],(void*)0},{&g_3176[3],&g_3176[3],&g_183},{&g_183,(void*)0,&g_3176[0]},{&g_3176[3],&g_3176[3],&g_206}},{{&g_206,(void*)0,&g_206},{&g_183,&g_3176[3],&g_206},{&l_3231,&g_3176[0],&g_206},{&g_206,&g_183,&g_206},{&g_206,(void*)0,&g_3176[0]},{&g_206,&g_206,&g_183},{&l_3231,(void*)0,(void*)0},{&g_183,&g_206,&g_183}},{{&g_206,(void*)0,&g_183},{&g_3176[3],&g_183,&g_183},{&g_183,&g_3176[0],(void*)0},{&g_3176[3],&g_3176[3],&g_183},{&g_183,(void*)0,&g_3176[0]},{&g_3176[3],&g_3176[3],&g_206},{&g_206,(void*)0,&g_206},{&g_183,&g_3176[3],&g_206}}}; + uint64_t l_3242[8] = {0xB6412F7D8489259FLL,1UL,1UL,0xB6412F7D8489259FLL,1UL,1UL,0xB6412F7D8489259FLL,1UL}; + uint64_t l_3253 = 18446744073709551606UL; + int32_t l_3256 = 0x6AE19F0EL; + uint32_t l_3258 = 4294967295UL; + int i, j, k; + l_6 = (safe_mod_func_uint16_t_u_u((l_3230[2] , (safe_mul_func_int8_t_s_s(((safe_add_func_int8_t_s_s(((((*l_3240) |= (((0x9CL ^ ((void*)0 != l_3240)) >= (l_3242[0] = ((*g_983) &= l_3187[2][6]))) <= l_6)) > (((safe_rshift_func_int8_t_s_u((safe_rshift_func_uint8_t_u_s((((*g_127) = (safe_rshift_func_uint8_t_u_s(g_177, ((1L <= ((safe_mul_func_uint16_t_u_u((safe_add_func_uint32_t_u_u((**g_1700), (**g_1700))), (-5L))) & l_3192)) != l_7)))) == 0x94128C946CC5AD13LL), g_458.f1)), l_3186)) < 0xBBL) , (-1L))) >= 250UL), l_3253)) >= 1UL), l_3187[0][2]))), 65535UL)); + l_3258++; + if (g_3261) + continue; + } + } + l_3[7][8][1] = ((*g_999) = &l_3230[0]); + for (g_629 = 0; (g_629 < 23); ++g_629) + { /* block id: 1515 */ + uint32_t l_3271 = 1UL; + int32_t l_3274 = (-8L); + uint8_t l_3294[4][3][2] = {{{0x30L,0x30L},{0xECL,253UL},{0x6AL,9UL}},{{0UL,0xECL},{255UL,0UL},{5UL,0UL}},{{5UL,0UL},{255UL,0xECL},{0UL,9UL}},{{0x6AL,253UL},{0xECL,0x30L},{0x30L,0x30L}}}; + uint32_t ****l_3309[2][8]; + int i, j, k; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 8; j++) + l_3309[i][j] = (void*)0; + } + } + } + else + { /* block id: 1537 */ + uint64_t l_3321 = 0xDDE7A297B90E42B9LL; + int32_t l_3323 = 0L; + int8_t *l_3329 = (void*)0; + uint32_t l_3330[6][7][6] = {{{18446744073709551615UL,1UL,0xB6573154L,18446744073709551615UL,0xAB8E7E60L,0xD5EF4BC4L},{18446744073709551615UL,0xAB8E7E60L,0xD5EF4BC4L,1UL,1UL,0xD5EF4BC4L},{18446744073709551614UL,18446744073709551614UL,0xB6573154L,1UL,1UL,0x8128DDD9L},{1UL,0xAB8E7E60L,0x812AD54AL,1UL,0xAB8E7E60L,0xB6573154L},{18446744073709551614UL,1UL,0x812AD54AL,1UL,18446744073709551614UL,0x8128DDD9L},{18446744073709551615UL,1UL,0xB6573154L,18446744073709551615UL,0xAB8E7E60L,0xD5EF4BC4L},{18446744073709551615UL,0xAB8E7E60L,0xD5EF4BC4L,1UL,1UL,0xD5EF4BC4L}},{{18446744073709551614UL,18446744073709551614UL,0xB6573154L,1UL,1UL,0x8128DDD9L},{1UL,0xAB8E7E60L,0x812AD54AL,1UL,0xAB8E7E60L,0xB6573154L},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL},{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL},{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL}},{{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL},{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL},{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL}},{{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL},{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL},{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL}},{{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL},{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL},{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL}},{{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,1UL},{0UL,0x269CFCD7L,1UL,0x8BF1BB38L,0x8BF1BB38L,1UL},{0xCE918E94L,0xCE918E94L,18446744073709551615UL,0x991B26EDL,0x8BF1BB38L,1UL},{0x8BF1BB38L,0x269CFCD7L,0xAB8E7E60L,0x991B26EDL,0x269CFCD7L,18446744073709551615UL},{0xCE918E94L,0x8BF1BB38L,0xAB8E7E60L,0x8BF1BB38L,0xCE918E94L,1UL},{0UL,0x8BF1BB38L,18446744073709551615UL,0UL,0x269CFCD7L,0x991B26EDL},{0xE15135D8L,0xB6573154L,0x991B26EDL,0x812AD54AL,0x812AD54AL,0x991B26EDL}}}; + int32_t l_3333[3]; + uint32_t l_3335[8][1][9] = {{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}},{{0x30091A38L,0UL,0x30B5CAEFL,0xE11A6A21L,0xE11A6A21L,0x30B5CAEFL,0UL,0x30091A38L,0x30B5CAEFL}}}; + int i, j, k; + for (i = 0; i < 3; i++) + l_3333[i] = 3L; +lbl_3355: + for (g_458.f3 = 0; (g_458.f3 <= 9); g_458.f3 += 1) + { /* block id: 1540 */ + uint8_t ***l_3320 = &g_441; + int i; + (*g_1000) |= (l_3323 = (safe_add_func_int8_t_s_s(g_2033[g_458.f3], ((((l_3229 ^= (safe_mod_func_int64_t_s_s((((*g_643) = ((*g_457) , (0x159FL != (((((*g_457) , (void*)0) == ((*l_3320) = &g_442)) <= (l_3321 < g_3322[2])) || g_2033[g_458.f3])))) <= l_5), l_7))) >= (-1L)) > l_3321) ^ l_2)))); + return g_2033[g_458.f3]; + } + if ((safe_lshift_func_uint16_t_u_s(((safe_rshift_func_uint8_t_u_u((((*g_983) = (*g_983)) < 0xDCL), g_629)) && ((g_3328 = &g_3254) == l_3329)), 4))) + { /* block id: 1550 */ + int8_t l_3339 = 7L; + for (g_132 = 0; (g_132 <= 7); g_132 += 1) + { /* block id: 1553 */ + int16_t l_3334 = (-2L); + int32_t l_3338[7] = {(-9L),(-9L),0xA9A03672L,(-9L),(-9L),0xA9A03672L,(-9L)}; + int i; + l_3330[3][1][3]++; + l_3335[2][0][3]--; + g_3340++; + if (g_258[g_132]) + break; + } + } + else + { /* block id: 1559 */ + uint32_t **l_3345 = &g_1701; + for (g_2895 = 0; (g_2895 <= 9); g_2895 += 1) + { /* block id: 1562 */ + uint32_t ***l_3347 = &l_3346[3][0]; + const uint16_t **** const **l_3350 = &g_3348; + int32_t l_3351 = 3L; + int i; + (**g_2622) ^= (safe_mul_func_int8_t_s_s((((l_3345 == ((*l_3347) = (g_2033[g_2895] , l_3346[2][3]))) , ((*l_3350) = g_3348)) == &g_2981), g_2033[g_2895])); + l_3352--; + if (g_458.f3) + goto lbl_3355; + } + return l_3352; + } + } + for (l_3228.f0 = 26; (l_3228.f0 > (-21)); l_3228.f0--) + { /* block id: 1574 */ + int64_t l_3358[10] = {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L}; + int32_t l_3359 = (-5L); + int32_t l_3360 = 1L; + int32_t l_3364 = (-1L); + int32_t l_3367 = 0xBCDBA61AL; + int32_t l_3372 = (-1L); + int32_t l_3373 = 0x8C5B084EL; + int i; + l_3358[7] = l_6; + for (g_146 = 2; (g_146 >= 0); g_146 -= 1) + { /* block id: 1578 */ + int64_t l_3361 = 0x9285272348967190LL; + int16_t l_3365 = 0xD941L; + int32_t l_3366 = 1L; + uint32_t l_3382[4][5][9] = {{{1UL,18446744073709551614UL,1UL,18446744073709551615UL,18446744073709551613UL,0x2E5E3E5AL,18446744073709551607UL,0x71493D5FL,4UL},{18446744073709551611UL,0xE6880DAFL,2UL,0xDDD702C7L,0xA6C66844L,0xC0E85E58L,0xA6C66844L,0xDDD702C7L,2UL},{4UL,4UL,18446744073709551614UL,18446744073709551615UL,0x204CB92DL,1UL,2UL,1UL,6UL},{1UL,1UL,0xC0E85E58L,18446744073709551615UL,18446744073709551606UL,18446744073709551606UL,18446744073709551615UL,0xC0E85E58L,1UL},{18446744073709551615UL,18446744073709551606UL,18446744073709551614UL,0x57A19FA0L,0UL,18446744073709551615UL,4UL,2UL,18446744073709551613UL}},{{0xDDD702C7L,1UL,2UL,1UL,18446744073709551615UL,1UL,2UL,1UL,0xDDD702C7L},{0UL,18446744073709551606UL,1UL,0xD37B812EL,4UL,18446744073709551607UL,6UL,18446744073709551614UL,0x2E5E3E5AL},{0x17F27A6EL,1UL,0x5030D5BFL,0xC0E85E58L,0xC0E85E58L,0x5030D5BFL,1UL,0x17F27A6EL,0xC51F3F36L},{0UL,4UL,6UL,0x204CB92DL,0x71493D5FL,18446744073709551615UL,18446744073709551613UL,0xD37B812EL,0xD37B812EL},{0xDDD702C7L,0xE6880DAFL,18446744073709551615UL,0x17F27A6EL,18446744073709551615UL,0xE6880DAFL,0xDDD702C7L,18446744073709551606UL,0xC51F3F36L}},{{18446744073709551615UL,18446744073709551614UL,1UL,18446744073709551606UL,4UL,0x204CB92DL,0xD37B812EL,1UL,0xD37B812EL},{18446744073709551615UL,0xA6C66844L,0xE6880DAFL,0xE6880DAFL,0xA6C66844L,18446744073709551615UL,18446744073709551606UL,0x5030D5BFL,0x17F27A6EL},{1UL,2UL,1UL,0x204CB92DL,18446744073709551615UL,18446744073709551614UL,4UL,4UL,18446744073709551614UL},{0xE6880DAFL,18446744073709551615UL,0x17F27A6EL,18446744073709551615UL,0xE6880DAFL,0xDDD702C7L,18446744073709551606UL,0xC51F3F36L,1UL},{18446744073709551613UL,4UL,1UL,0x2E5E3E5AL,2UL,18446744073709551607UL,0xD37B812EL,18446744073709551607UL,2UL}},{{18446744073709551606UL,2UL,2UL,18446744073709551606UL,0x4809426DL,0xDDD702C7L,0x17F27A6EL,18446744073709551615UL,0xC0E85E58L},{18446744073709551615UL,6UL,0UL,1UL,0x71493D5FL,18446744073709551614UL,18446744073709551614UL,0x71493D5FL,1UL},{0x616EDC88L,1UL,0x616EDC88L,0x3258CFFDL,0x4809426DL,18446744073709551615UL,1UL,18446744073709551611UL,0xDDD702C7L},{1UL,18446744073709551613UL,0x71493D5FL,18446744073709551606UL,2UL,0x204CB92DL,2UL,18446744073709551606UL,0x71493D5FL},{0xDDD702C7L,0xDDD702C7L,1UL,0x3258CFFDL,0xE6880DAFL,0x616EDC88L,0xC0E85E58L,0x17F27A6EL,2UL}}}; + int i, j, k; + l_3375++; + if ((*g_268)) + continue; + l_3229 = (l_3361 != (~((safe_rshift_func_int16_t_s_s(((safe_mod_func_uint32_t_u_u(((l_6 , &g_3348) != &g_2980), (~(!l_3382[3][3][1])))) , (safe_sub_func_int64_t_s_s((((*l_3197) = l_3385) == (l_3370 , (((((safe_lshift_func_uint8_t_u_u(l_3374, (l_3360 != l_3382[2][2][5]))) , 1L) , l_3388) != l_3365) , l_3389))), l_2))), 2)) || l_3352))); + for (g_888 = 0; (g_888 <= 2); g_888 += 1) + { /* block id: 1585 */ + uint64_t *l_3398 = &g_629; + uint32_t l_3405 = 0x14A9940BL; + int32_t l_3406[9] = {1L,1L,1L,1L,1L,1L,1L,1L,1L}; + int i, j; + l_3406[8] ^= ((((safe_add_func_uint64_t_u_u(((*l_3240)--), ((((safe_add_func_int16_t_s_s((((safe_lshift_func_uint16_t_u_u((((((*l_3398) = 0x4D91C8663151B76CLL) != 0x073A0058EBEA58B1LL) | l_3374) >= (safe_mul_func_int8_t_s_s((safe_sub_func_uint32_t_u_u(((*l_3185) == (void*)0), (safe_div_func_uint8_t_u_u((((*l_3158) |= l_3369) < 6UL), (l_3366 | (l_5 > 9UL)))))), l_3358[5]))), 9)) , &g_1567) == &g_1567), 0x1CACL)) == (*g_268)) < 0x93C5L) , l_3405))) >= l_3367) == (**g_1700)) ^ (*g_127)); + if (l_3382[0][0][4]) + continue; + } + } + if (l_3373) + continue; + l_3410--; + } + l_3419[2]--; + } + else + { /* block id: 1597 */ + int32_t *l_3429 = &g_75[0]; + uint16_t ***l_3481 = &g_642; + uint16_t ****l_3480[8] = {(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}; + int64_t l_3488[4][1][5] = {{{7L,6L,7L,6L,7L}},{{0L,0L,1L,1L,0L}},{{(-1L),6L,(-1L),6L,(-1L)}},{{0L,1L,1L,0L,0L}}}; + union U0 l_3502 = {0x32L}; + int16_t *l_3543 = &g_408; + int64_t l_3545 = 0xCC9D81739EE3B76CLL; + int32_t l_3548 = 0xFEF003C0L; + int32_t l_3551 = 2L; + int32_t l_3553[10] = {(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L),(-7L)}; + uint8_t l_3555 = 1UL; + int8_t l_3624 = (-4L); + int16_t l_3665 = 0L; + int32_t l_3689 = 0x13D17FE3L; + uint64_t l_3693 = 1UL; + uint32_t **l_3716 = (void*)0; + uint32_t l_3753 = 0xBFB92AF7L; + uint8_t l_3758 = 0xDAL; + int64_t l_3759[1]; + int8_t l_3828 = 0xBFL; + int32_t ** const ****l_3840 = (void*)0; + int32_t l_3856 = (-8L); + const uint32_t l_3872 = 3UL; + uint32_t *****l_3934 = &g_3601; + int i, j, k; + for (i = 0; i < 1; i++) + l_3759[i] = 0x4C49DDF402E1B26ALL; + if (((-4L) > (((l_3368 = 0L) > (safe_sub_func_uint16_t_u_u(((*g_441) != l_3426), (safe_lshift_func_uint8_t_u_u(1UL, 3))))) > ((**g_1175) == l_3429)))) + { /* block id: 1599 */ + (*g_267) = &l_3388; + return l_3369; + } + else + { /* block id: 1602 */ + int16_t l_3436[5] = {0x12A2L,0x12A2L,0x12A2L,0x12A2L,0x12A2L}; + uint32_t ****l_3437 = &l_3308; + int32_t l_3482 = 1L; + int32_t l_3483 = 0xF7B6D19CL; + int32_t l_3489 = 0x50343D68L; + int32_t l_3494[2][7] = {{0xB2700B47L,(-2L),0x382AAF93L,0x34F800FAL,0x34F800FAL,0x382AAF93L,(-2L)},{0xB2700B47L,(-2L),0x382AAF93L,0x34F800FAL,0x34F800FAL,0x382AAF93L,(-2L)}}; + const uint64_t *l_3516[4][3] = {{&g_132,&l_3375,&g_132},{&g_132,&l_3375,&g_132},{&g_132,&l_3375,&g_132},{&g_132,&l_3375,&g_132}}; + uint64_t ***** const *l_3537 = &l_3385; + int64_t l_3538 = 0xB72394C9ED776906LL; + int8_t l_3552 = 0xE5L; + uint16_t *****l_3635[9] = {&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2],&l_3480[2]}; + uint16_t ******l_3634 = &l_3635[2]; + int8_t *l_3654 = &l_3590[8]; + int8_t *l_3655 = &l_3544; + int i, j; +lbl_3541: + if ((0xC5581AAEL > (((&g_647[5][0] == ((*l_3437) = (((safe_sub_func_int64_t_s_s(((***g_276) = ((((safe_rshift_func_int16_t_s_s((((safe_mul_func_int8_t_s_s(((****g_2620) == ((((void*)0 != &l_3298) || 6L) ^ ((*g_1701) , 0x42C35DDFL))), 0x63L)) >= 0x1412F895L) < 0x6480L), 3)) , l_3436[4]) <= 0x67879153L) || 0x1F4B0C28L)), 18446744073709551615UL)) == 1UL) , l_3308))) != l_3436[4]) || g_746))) + { /* block id: 1605 */ + union U0 **l_3439 = (void*)0; + int32_t l_3453[4][8][4] = {{{0xA9A0789AL,0x9149705AL,0x36D971D7L,0xD6172A53L},{0x36D971D7L,0xD6172A53L,0x252D9B84L,0xD6172A53L},{1L,0x9149705AL,1L,0x36D971D7L},{0x90B9288CL,0x2C266790L,0xD6172A53L,(-1L)},{1L,1L,1L,1L},{0xD6172A53L,0xD6172A53L,0xA9A0789AL,0x2C266790L},{0x36D971D7L,1L,0xD6172A53L,0x9149705AL},{(-1L),(-4L),0x90B9288CL,0xD6172A53L}},{{0x5A1350BCL,(-4L),0x5A1350BCL,0x9149705AL},{(-4L),1L,0x252D9B84L,0x2C266790L},{0x2C266790L,0xD6172A53L,(-1L),1L},{1L,(-1L),(-1L),1L},{0x2C266790L,0x9149705AL,0x252D9B84L,0x5A1350BCL},{(-4L),(-4L),0x5A1350BCL,0xA9A0789AL},{0x5A1350BCL,0xA9A0789AL,0x90B9288CL,0xA9A0789AL},{(-1L),(-4L),0xD6172A53L,0x5A1350BCL}},{{0x36D971D7L,0x9149705AL,0xA9A0789AL,1L},{0xD6172A53L,(-1L),1L,1L},{0xD6172A53L,0xD6172A53L,0xA9A0789AL,0x2C266790L},{0x36D971D7L,1L,0xD6172A53L,0x9149705AL},{(-1L),(-4L),0x90B9288CL,0xD6172A53L},{0x5A1350BCL,(-4L),0x5A1350BCL,0x9149705AL},{(-4L),1L,0x252D9B84L,0x2C266790L},{0x2C266790L,0xD6172A53L,(-1L),1L}},{{1L,(-1L),(-1L),1L},{0x2C266790L,0x9149705AL,0x252D9B84L,0x5A1350BCL},{(-4L),(-4L),0x5A1350BCL,0xA9A0789AL},{0x5A1350BCL,0xA9A0789AL,0x90B9288CL,0xA9A0789AL},{(-1L),(-4L),0xD6172A53L,0x5A1350BCL},{0x36D971D7L,0x9149705AL,0xA9A0789AL,1L},{0xD6172A53L,(-1L),1L,1L},{0xD6172A53L,0xD6172A53L,0xA9A0789AL,0x2C266790L}}}; + uint16_t ***l_3479 = &g_3116; + uint16_t ****l_3478 = &l_3479; + int i, j, k; + g_457 = l_3438; + (***g_2621) |= (((*l_3429) = (l_3453[2][7][1] = ((*g_983) == (safe_div_func_int16_t_s_s((safe_mul_func_int8_t_s_s((((void*)0 == &g_3349) != (safe_add_func_uint8_t_u_u(l_3446[0], ((((*g_457) = (*g_457)) , ((safe_rshift_func_uint8_t_u_u(0x6FL, 0)) && (**g_642))) ^ ((safe_mod_func_int64_t_s_s((safe_sub_func_uint64_t_u_u(18446744073709551607UL, l_3453[2][7][1])), (***g_276))) <= l_3436[0]))))), l_3419[2])), l_3436[4]))))) < l_3436[4]); + if (l_3446[2]) + { /* block id: 1611 */ + int16_t *l_3472 = &g_408; + int32_t l_3474 = 0L; + int32_t l_3477 = (-1L); + int64_t l_3484 = (-1L); + int16_t l_3490 = 8L; + uint32_t l_3491 = 0UL; + (***g_2621) = (l_3436[4] ^ ((((((safe_div_func_uint32_t_u_u((0L | (safe_div_func_int32_t_s_s(((l_3453[2][7][1] ^ ((++(**g_3116)) , (safe_add_func_int64_t_s_s((+((((safe_lshift_func_uint8_t_u_s(((+(safe_add_func_uint32_t_u_u((safe_lshift_func_int16_t_s_s(((((*l_3438) , (safe_add_func_uint64_t_u_u((safe_div_func_int64_t_s_s(((((*l_3472) &= 0x0CC3L) > (*g_1739)) || (safe_unary_minus_func_uint32_t_u((l_3474 = (*g_1701))))), (safe_rshift_func_int8_t_s_s(((0x2FF5L | ((**g_1574) ^= ((*g_127) | 18446744073709551615UL))) | 0x1D00L), l_3477)))), (-6L)))) | g_471) , l_3436[4]), l_3477)), l_3477))) < 0L), l_3375)) >= l_3375) , l_3478) == l_3480[2])), 18446744073709551615UL)))) & l_5), (**g_1700)))), (*g_1701))) , (*l_3298)) , l_3436[4]) || l_3477) && l_3477) ^ l_3453[2][7][1])); + g_3485--; + --l_3491; + } + else + { /* block id: 1619 */ + uint32_t *l_3498 = &g_3322[2]; + l_3495--; + (***g_1175) = (func_97((((*l_3429) && (l_3498 != (void*)0)) , func_57(func_57((***g_2978), func_13((safe_add_func_uint64_t_u_u((*l_3429), ((*g_2980) == (*g_3348))))), (***g_2978), l_3453[2][7][1], (*g_999)), (***g_2978), l_3429, (*g_268), &l_3453[1][3][0]))) , l_3489); + (****g_2620) = 7L; + return (*g_1739); + } + } + else + { /* block id: 1625 */ + const int32_t *l_3501 = &g_75[0]; + int64_t *l_3514[1]; + int i; + for (i = 0; i < 1; i++) + l_3514[i] = &l_3374; + (****g_2620) = ((((((l_3502 , (-1L)) == 0x94D1ECE486E951AELL) , (*l_3501)) , (**g_267)) < l_3494[1][1]) & (**g_267)); + l_3370 &= ((safe_rshift_func_uint8_t_u_s(((((safe_mod_func_uint32_t_u_u(((safe_sub_func_uint8_t_u_u((l_3483 ^= (l_6 , ((safe_rshift_func_int16_t_s_u((safe_unary_minus_func_int16_t_s((((*g_127) == ((*l_3429) > (*l_3429))) & (((*g_856) = (*g_856)) == ((l_3363 &= (g_3515 = l_5)) , l_3516[0][0]))))), (((safe_add_func_uint32_t_u_u(((safe_div_func_int8_t_s_s((safe_lshift_func_uint8_t_u_s((*g_983), (((*g_1000) = ((*l_3429) || l_3523)) < (*g_1701)))), g_458.f0)) > (*g_268)), 0xE7B98EBDL)) ^ l_3446[0]) <= (*g_127)))) | l_3482))), (*l_3501))) ^ 1L), l_3489)) ^ (***g_276)) ^ 0x6712AC90L) & (*l_3429)), 4)) ^ (*g_127)); + } + if (((safe_rshift_func_int8_t_s_u((*l_3429), 4)) & (((l_3369 &= l_3375) | (((**g_1700) = (((l_3419[2] , (safe_rshift_func_uint8_t_u_s((+(safe_lshift_func_uint16_t_u_s(((g_458.f1 , l_3530) != l_3533), 3))), 5))) && (l_3502 , l_3538)) >= 5L)) && 0x5B78E17CL)) || (*g_127)))) + { /* block id: 1636 */ + int32_t l_3546 = (-2L); + int32_t l_3547 = 0x4E086909L; + int64_t l_3549 = (-3L); + int32_t l_3550 = 0L; + int8_t l_3574 = 0x5FL; + uint32_t *l_3575[4][4][2] = {{{&g_1860,&g_204},{&g_1860,&g_3322[2]},{&g_204,&g_3322[2]},{&g_1860,&g_204}},{{&g_1860,&g_3322[2]},{&g_204,&g_3322[2]},{&g_1860,&g_204},{&g_1860,&g_3322[2]}},{{&g_204,&g_3322[2]},{&g_1860,&g_204},{&g_1860,&g_3322[2]},{&g_204,&g_3322[2]}},{{&g_1860,&g_204},{&g_1860,&g_3322[2]},{&g_204,&g_3322[2]},{&g_1860,&g_204}}}; + int8_t l_3579 = 0L; + int16_t ***l_3594[6][5][1]; + int i, j, k; + for (i = 0; i < 6; i++) + { + for (j = 0; j < 5; j++) + { + for (k = 0; k < 1; k++) + l_3594[i][j][k] = &g_2230; + } + } + for (l_3495 = 13; (l_3495 > 19); ++l_3495) + { /* block id: 1639 */ + if (l_3228.f0) + goto lbl_3541; + (***g_2621) = (l_3542[2] != l_3543); + (****g_2620) = 0xA5091839L; + } + --l_3555; + l_3547 ^= ((((***g_1175) | (safe_mod_func_int8_t_s_s((safe_rshift_func_int16_t_s_s((safe_add_func_uint64_t_u_u((safe_sub_func_int64_t_s_s((l_3426 != (void*)0), l_3482)), (***g_276))), 5)), (safe_add_func_int32_t_s_s((safe_lshift_func_int16_t_s_s(((((*l_3429) = (*g_1000)) >= l_3550) || (safe_add_func_uint32_t_u_u((safe_sub_func_uint64_t_u_u(((*g_1700) != ((l_3574 = (l_3436[4] || l_3544)) , l_3575[0][2][0])), (*l_3429))), l_3436[2]))), (**g_1744))), l_3549))))) >= 6L) <= 0xC7L); + (**g_2622) = ((safe_mul_func_uint16_t_u_u((*g_643), (l_3580++))) == (safe_add_func_int64_t_s_s(((l_3590[3] = (((--(*l_3240)) <= ((***g_276) = l_3574)) == (safe_mul_func_int16_t_s_s(0xD1B3L, (safe_unary_minus_func_uint32_t_u((**g_1700))))))) | (safe_lshift_func_int16_t_s_u(0L, 13))), ((((((*l_3543) ^= ((void*)0 == g_3593)) < (*g_1739)) == ((l_3594[4][4][0] != l_3595) < 0x384FL)) , g_746) , 0L)))); + } + else + { /* block id: 1654 */ + uint32_t ******l_3599[8]; + int32_t l_3609 = (-2L); + int32_t *l_3610 = &l_3551; + int8_t l_3622 = 3L; + int i; + for (i = 0; i < 8; i++) + l_3599[i] = &l_3598; + (***g_2978) = func_51(((*l_3158) ^= (!((g_3600[3][1][4] = (g_778 , l_3598)) == (((*l_3298) = (*g_457)) , (void*)0)))), ((((safe_add_func_uint16_t_u_u(((safe_mul_func_int8_t_s_s((((safe_lshift_func_uint8_t_u_s(((*g_983) = (((***g_1175) == (!((safe_unary_minus_func_int32_t_s(0x9CE8AE23L)) < 0xF4L))) || ((*g_983) , (l_3609 | g_135)))), l_3538)) > 3UL) & 0xE0A3L), l_3370)) , 65534UL), l_3363)) < l_3609) & (**g_2631)) ^ g_3176[0]), l_3489, &l_3388, l_3610); + (****g_2620) = l_3436[4]; + for (g_3578 = 28; (g_3578 <= (-29)); --g_3578) + { /* block id: 1663 */ + const uint32_t l_3615 = 0x1A635137L; + int32_t l_3623 = 0xFC5CCCB4L; + (****g_2978) ^= (**g_267); + (*g_267) = func_99(l_3482, (((**g_3116) = (!(((l_3494[0][2] <= (***g_1175)) && 0xCCDC2293L) , 1UL))) >= (l_3623 |= (safe_add_func_int64_t_s_s((*l_3610), ((l_3615 && (safe_mul_func_int16_t_s_s(l_3494[0][2], (safe_lshift_func_int8_t_s_u((((*l_3158) = (!(safe_mod_func_uint64_t_u_u((((*l_3429) | l_3622) , (*l_3610)), 2UL)))) > g_1337), (*l_3610)))))) , l_3489))))), (*g_457), (**g_276), (**g_276)); + ++l_3626; + } + } + (**g_999) = (safe_rshift_func_uint16_t_u_u((((*l_3429) = l_3489) >= ((safe_mul_func_int8_t_s_s(((safe_unary_minus_func_uint64_t_u(((void*)0 != l_3634))) > ((safe_add_func_uint32_t_u_u((1UL > (safe_lshift_func_int8_t_s_s((safe_lshift_func_int8_t_s_s((safe_mul_func_uint16_t_u_u((((safe_sub_func_uint32_t_u_u((((***l_3595) = ((((*l_3437) = &g_647[5][0]) != (void*)0) > (((((l_3362 , ((safe_lshift_func_int8_t_s_s(((*l_3655) = (((-5L) == ((safe_div_func_uint16_t_u_u(((**g_1574)++), (safe_lshift_func_uint16_t_u_u((((((*l_3654) = ((*l_3158) = 0xE9L)) >= g_2033[0]) , l_3483) && 18446744073709551614UL), (*****g_3348))))) | 65528UL)) , l_3489)), g_133)) | 0xE2CB313EB04FFBB3LL)) && (**g_1700)) || 254UL) > 0xAC2D93AAL) <= l_3538))) , 0UL), l_3656)) < l_3375) , l_3580), l_3369)), g_409[0][0])), l_3436[4]))), (****g_2620))) , l_3489)), (*g_983))) < l_3371)), 9)); + (*g_999) = &l_3553[5]; + } + if ((safe_sub_func_int32_t_s_s(0x09312BA0L, ((l_3659 == (void*)0) <= (safe_sub_func_int64_t_s_s((((*g_983) = (+((l_5 ^ ((*l_3429) |= ((*g_1000) = ((safe_mod_func_int16_t_s_s(((*g_457) , ((func_97(&l_3551) , (**g_1574)) , (l_3446[4] != l_3664))), l_3665)) && 0L)))) && (-1L)))) || (*g_983)), l_3363)))))) + { /* block id: 1685 */ + for (l_3228.f1 = 0; (l_3228.f1 <= 19); l_3228.f1++) + { /* block id: 1688 */ + for (g_1086 = 29; (g_1086 > (-2)); g_1086--) + { /* block id: 1691 */ + if ((****g_2978)) + break; + } + } + for (l_3624 = 0; (l_3624 < (-21)); --l_3624) + { /* block id: 1697 */ + if ((*l_3429)) + break; + } + } + else + { /* block id: 1700 */ + int64_t ** const l_3680 = &g_127; + int32_t l_3690 = (-9L); + int32_t l_3691 = (-9L); + uint32_t l_3692 = 0x6CBB8C67L; + int16_t *l_3700[6]; + int16_t l_3748 = 0xD93AL; + int16_t l_3792 = (-6L); + uint64_t * const * const ***l_3794 = (void*)0; + uint64_t * const * const **** const l_3793 = &l_3794; + int64_t l_3795 = 0x2DEEDFD4EC26300BLL; + int16_t l_3813 = 0x5ABEL; + uint32_t ***l_3824 = &g_1700; + int32_t *****l_3839 = &g_2978; + int32_t ******l_3838 = &l_3839; + int i; + for (i = 0; i < 6; i++) + l_3700[i] = &g_408; + (**g_999) = (g_78 != (*l_3429)); + if (l_3523) + goto lbl_3862; + if (((*l_3429) = (safe_mul_func_int8_t_s_s(g_146, ((*g_983) = ((safe_rshift_func_int16_t_s_u((l_3693 &= (((*g_1701) , (0xE5L <= ((safe_mod_func_uint16_t_u_u((((*g_1739) > l_3371) || ((safe_sub_func_int8_t_s_s(((l_3680 != ((((safe_mul_func_uint16_t_u_u((****g_3349), (safe_sub_func_int32_t_s_s((l_3690 = ((**g_2622) = (l_5 ^ (safe_sub_func_uint64_t_u_u(((~(safe_lshift_func_int8_t_s_s((-1L), l_3371))) != 0x1357C7A0L), l_3689))))), l_3419[2])))) != (**g_3116)) , 1L) , (void*)0)) , (*l_3429)), l_3691)) > l_3446[1])), (*g_1739))) >= l_3692))) || (*l_3429))), 6)) | 0x8AD29F6C6A38AA53LL)))))) + { /* block id: 1707 */ + int64_t l_3694 = 1L; + int32_t l_3695 = 3L; + uint8_t *l_3699 = &l_3555; + union U0 ***l_3711 = &l_3534[0]; + if ((((((((*l_3298) , 1L) <= ((*l_3699) = ((0L ^ (l_3695 = l_3694)) && (safe_unary_minus_func_uint8_t_u((--(*g_983))))))) <= ((l_3694 <= (((((l_3700[3] != (void*)0) < ((**g_3116) = (**g_1574))) , (**g_267)) || 4294967287UL) ^ 0x0D56CD8E1D75A02ELL)) | 0xF31DCA78L)) <= l_3690) , (**g_3348)) != (void*)0)) + { /* block id: 1712 */ + (****g_2620) &= (safe_rshift_func_uint16_t_u_s(((g_3705 = l_3703) == &l_3543), l_3695)); + return (*g_1739); + } + else + { /* block id: 1716 */ + int16_t l_3712[8][6][5] = {{{(-1L),0x482FL,0x4D1EL,0xA893L,0x63D4L},{(-1L),0x00CCL,0x00CCL,(-1L),(-9L)},{1L,0xA893L,(-6L),(-1L),0x4207L},{(-9L),0x00CCL,0x189DL,(-9L),(-9L)},{0xA2F2L,0x482FL,0xA2F2L,(-1L),0x4D1EL},{0xD746L,(-1L),(-9L),(-1L),0xD746L}},{{0xA2F2L,(-1L),(-1L),0xA893L,(-1L)},{(-9L),(-9L),(-9L),0xD746L,0xB2A8L},{1L,(-1L),0xA2F2L,(-1L),(-1L)},{(-1L),0xD746L,0x189DL,0x189DL,0x189DL},{0x63D4L,0xA893L,0x4D1EL,0x482FL,(-1L)},{0xD746L,0xB2A8L,0xD746L,(-9L),(-9L)}},{{(-6L),(-1L),(-1L),(-1L),(-6L)},{0xD746L,0x00CCL,0xB2A8L,0x189DL,0xB2A8L},{0x63D4L,(-1L),(-1L),(-1L),1L},{0x00CCL,0xD746L,0xD746L,0x00CCL,0xB2A8L},{0xA2F2L,(-1L),0x4D1EL,0x4A24L,(-6L)},{0xB2A8L,0xD746L,(-9L),(-9L),(-9L)}},{{0x4207L,(-1L),0x4207L,0x4A24L,(-1L)},{0x189DL,0x00CCL,(-9L),0x00CCL,0x189DL},{0x4207L,(-1L),0x63D4L,(-1L),0x63D4L},{0xB2A8L,0xB2A8L,(-9L),0x189DL,(-1L)},{0xA2F2L,0xA893L,0x4207L,(-1L),0x63D4L},{0x00CCL,0x189DL,(-9L),(-9L),0x189DL}},{{0x63D4L,0xA893L,0x4D1EL,0x482FL,(-1L)},{0xD746L,0xB2A8L,0xD746L,(-9L),(-9L)},{(-6L),(-1L),(-1L),(-1L),(-6L)},{0xD746L,0x00CCL,0xB2A8L,0x189DL,0xB2A8L},{0x63D4L,(-1L),(-1L),(-1L),1L},{0x00CCL,0xD746L,0xD746L,0x00CCL,0xB2A8L}},{{0xA2F2L,(-1L),0x4D1EL,0x4A24L,(-6L)},{0xB2A8L,0xD746L,(-9L),(-9L),(-9L)},{0x4207L,(-1L),0x4207L,0x4A24L,(-1L)},{0x189DL,0x00CCL,(-9L),0x00CCL,0x189DL},{0x4207L,(-1L),0x63D4L,(-1L),0x63D4L},{0xB2A8L,0xB2A8L,(-9L),0x189DL,(-1L)}},{{0xA2F2L,0xA893L,0x4207L,(-1L),0x63D4L},{0x00CCL,0x189DL,(-9L),(-9L),0x189DL},{0x63D4L,0xA893L,0x4D1EL,0x482FL,(-1L)},{0xD746L,0xB2A8L,0xD746L,(-9L),(-9L)},{(-6L),(-1L),(-1L),(-1L),(-6L)},{0xD746L,0x00CCL,0xB2A8L,0x189DL,0xB2A8L}},{{0x63D4L,(-1L),(-1L),(-1L),1L},{0x00CCL,0xD746L,0xD746L,0x00CCL,0xB2A8L},{0xA2F2L,(-1L),0x4D1EL,0x4A24L,(-6L)},{0xB2A8L,0xD746L,(-9L),(-9L),(-9L)},{0x4207L,(-1L),0x4207L,0x4A24L,(-1L)},{0x189DL,0x00CCL,(-9L),0x00CCL,(-9L)}}}; + const uint32_t ***l_3715 = &g_3713[0]; + int i, j, k; + (*l_3429) &= (**g_2622); + (**g_2622) = ((((((void*)0 == (*l_3314)) , &g_3349) == &g_2981) > ((safe_mod_func_int64_t_s_s((((((((((void*)0 == l_3711) == ((l_3712[7][5][4] | (((*l_3715) = (((-4L) <= (0x4E8EA59DL != l_3690)) , g_3713[1])) != l_3716)) <= (*g_983))) , l_3690) || 1UL) || 0x80L) ^ l_6) & l_3712[7][5][4]) && (*l_3429)), 2UL)) > 0xD7L)) ^ (*l_3429)); + (***g_1175) = ((safe_mod_func_uint8_t_u_u((safe_mul_func_int16_t_s_s(l_3690, ((*l_3543) = (((0x7EL ^ (*l_3429)) , ((l_3736 = (((**g_1700) = (safe_mul_func_int16_t_s_s((((l_3363 & 0x91F6L) | (*l_3429)) && (safe_lshift_func_uint16_t_u_s(((safe_rshift_func_int16_t_s_s(((*l_3429) = 7L), (((*g_457) , (((~(safe_sub_func_int8_t_s_s((safe_lshift_func_int8_t_s_s((safe_add_func_int32_t_s_s(((safe_mul_func_int16_t_s_s(l_3694, 1L)) >= l_3580), l_3735)), 0)), 0UL))) , l_3690) & 0x6822B2381C627CA9LL)) != l_3695))) && 18446744073709551606UL), 12))), (*g_1739)))) <= l_3664)) & l_3690)) == l_3691)))), (*g_983))) , 1L); + } + if ((safe_unary_minus_func_uint32_t_u((safe_unary_minus_func_int32_t_s((!((g_133 , ((safe_mul_func_int8_t_s_s((safe_mul_func_int16_t_s_s(((safe_sub_func_int64_t_s_s(0x26C8E728EBABCF00LL, (safe_sub_func_uint16_t_u_u(1UL, l_3736)))) <= l_3695), (safe_unary_minus_func_int32_t_s((l_3748 ^ (++(**g_1700))))))), (safe_sub_func_uint64_t_u_u(l_3753, (*l_3429))))) || ((safe_lshift_func_uint8_t_u_s((safe_lshift_func_int16_t_s_s(l_3758, l_3695)), l_3495)) , l_3759[0]))) >= l_3695))))))) + { /* block id: 1727 */ + int32_t **l_3760 = &l_3[7][8][1]; + (*l_3760) = (**g_2621); + } + else + { /* block id: 1729 */ + int64_t l_3791 = (-7L); + (**g_2622) = ((((safe_lshift_func_int16_t_s_s((safe_mod_func_int64_t_s_s((((-9L) == (((*l_3543) = (safe_sub_func_uint32_t_u_u(((**g_1700) ^= l_3748), (((((safe_mul_func_int8_t_s_s((((safe_mul_func_uint16_t_u_u((g_3771 != (((safe_lshift_func_int16_t_s_s((((((safe_mul_func_uint8_t_u_u(l_3694, (8L && (4294967293UL & (*g_3714))))) & ((safe_mul_func_uint8_t_u_u((safe_unary_minus_func_uint8_t_u((!(safe_add_func_int32_t_s_s((4L ^ ((safe_mod_func_int8_t_s_s(((safe_div_func_uint32_t_u_u((safe_add_func_int16_t_s_s(((safe_mod_func_int8_t_s_s(((((((**l_3385) = (**l_3389)) != (void*)0) & 0x33A3L) && l_3790[0][4]) || 0x233F04E3L), 0x28L)) || (**g_999)), l_3694)), l_3791)) >= 0xB1L), l_3691)) ^ 0x3CBEL)), l_3792))))), l_3791)) <= 0x7B71L)) < (*g_1000)) != 1L) > (*g_127)), 6)) , l_3748) , l_3793)), (*l_3429))) & l_3368) || 0x36914F2FD50638ECLL), 0xD0L)) > 0L) , (void*)0) == g_1185) , (*l_3429))))) >= (-5L))) > l_3419[2]), l_3695)), 4)) | (*l_3429)) | l_3495) ^ l_3795); + return l_3791; + } + } + else + { /* block id: 1736 */ + uint64_t * const l_3798 = &l_3656; + int32_t l_3803[8][4][1] = {{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}},{{(-1L)},{1L},{(-1L)},{1L}}}; + const uint32_t ****l_3826 = &l_3825[0][0]; + union U0 ***l_3837 = &l_3534[4]; + int32_t l_3853[9][7][4] = {{{0xB571F11DL,9L,(-1L),1L},{0xD0FA9223L,4L,(-2L),8L},{8L,1L,2L,1L},{0x489591CBL,(-5L),0x84DAE1CFL,0x1225A671L},{9L,1L,0xC3ACAE87L,0xF1EB5902L},{1L,(-1L),0x91EB2A23L,7L},{(-1L),0L,0L,(-1L)}},{{(-1L),0xE828EEB4L,3L,1L},{4L,0xBB7E3BACL,0xE28983ADL,0x10FCC4E9L},{0xBB7E3BACL,0L,0x1225A671L,0x053AB736L},{(-1L),1L,0xE8131784L,0xF1EB5902L},{0x7A8086E9L,0x84DAE1CFL,0xC416942FL,9L},{7L,(-5L),7L,(-1L)},{9L,(-10L),(-10L),8L}},{{0x0C547A2AL,1L,0x7D2C2085L,(-10L)},{0x1AB709E8L,9L,0x7D2C2085L,(-1L)},{0x0C547A2AL,7L,(-10L),(-1L)},{9L,(-1L),7L,0x0C547A2AL},{7L,0x0C547A2AL,0xC416942FL,0xB571F11DL},{0x7A8086E9L,0x1FB3E971L,0xE8131784L,0x7A8086E9L},{(-1L),(-1L),0x1225A671L,0x662EFE13L}},{{0xBB7E3BACL,1L,0xE28983ADL,(-1L)},{4L,(-3L),3L,1L},{(-1L),0xC416942FL,0L,0x662EFE13L},{(-1L),0x10FCC4E9L,0x91EB2A23L,0xE28983ADL},{1L,0x1FB3E971L,0xC3ACAE87L,0xD0FA9223L},{9L,1L,0x84DAE1CFL,0x0C547A2AL},{0x489591CBL,1L,2L,0x21B8CC8CL}},{{8L,7L,(-2L),0x1FB3E971L},{0xD0FA9223L,0L,(-1L),(-10L)},{0xB571F11DL,4L,0x21B8CC8CL,0L},{8L,(-10L),0L,1L},{0x2502D502L,0x73A90A79L,0x84DAE1CFL,9L},{0L,1L,1L,1L},{1L,1L,(-7L),7L}},{{0x1FB3E971L,7L,0L,0x10FCC4E9L},{0x91EB2A23L,0xE828EEB4L,1L,0L},{4L,0xE828EEB4L,8L,0x10FCC4E9L},{0xE828EEB4L,7L,0x1225A671L,7L},{(-1L),1L,1L,0x003CE246L},{0xC416942FL,(-1L),(-3L),0x7D2C2085L},{1L,0xC3ACAE87L,0x6D7917C2L,0x68B24717L}},{{0x57110039L,0xBB7E3BACL,6L,0xE8131784L},{0x1AB709E8L,0x84DAE1CFL,0xA66F9617L,0xBB7E3BACL},{0x489591CBL,6L,0x13596ED7L,0xB571F11DL},{0L,1L,6L,1L},{0x7D2C2085L,7L,(-10L),0x1AB709E8L},{1L,0L,0L,0x053AB736L},{(-1L),0xB571F11DL,1L,(-1L)}},{{0L,0L,1L,0x21B8CC8CL},{0x91EB2A23L,0L,(-1L),7L},{0xE49BE893L,(-1L),0L,0xCA2FA527L},{0L,2L,0x7A8086E9L,0x21B8CC8CL},{0xB571F11DL,1L,(-10L),0xC416942FL},{(-1L),0xB571F11DL,0x003CE246L,0x71246B4AL},{0x1225A671L,0x1AB709E8L,0x10FCC4E9L,0x1AB709E8L}},{{0x73A90A79L,0xCA2FA527L,(-1L),(-1L)},{0xE8131784L,1L,1L,1L},{0x053AB736L,0x1225A671L,0L,0xBB7E3BACL},{0x053AB736L,0xE49BE893L,1L,(-1L)},{0xE8131784L,0xBB7E3BACL,(-1L),(-1L)},{0x73A90A79L,1L,0x10FCC4E9L,0x7D2C2085L},{0x1225A671L,0x807C8DCEL,0x003CE246L,(-1L)}}}; + int i, j, k; + (*g_999) = func_13((*g_983)); + (***g_1175) = (((((safe_sub_func_int64_t_s_s((&l_3693 == l_3798), (*l_3429))) != ((((((safe_mul_func_uint8_t_u_u((((((safe_add_func_uint8_t_u_u(0UL, 0L)) < (((l_3690 < l_3803[5][2][0]) , ((safe_mod_func_uint32_t_u_u((safe_add_func_uint64_t_u_u((safe_div_func_int16_t_s_s(((&g_3600[3][1][4] != (func_97(func_13(((*g_983)--))) , (void*)0)) >= l_3812), l_3419[2])), l_3795)), (*l_3429))) == 1L)) ^ l_3813)) , (**g_642)) <= 0x2027L) <= (*l_3429)), g_3515)) && 0xCFL) ^ l_7) & l_3814) & 0x0B8C30BBDC12EE56LL) , l_3691)) || g_3815) <= (-1L)) && l_3690); + if ((l_3803[5][2][0] | (((0x85L || l_3691) < ((((**l_3680) = (~((safe_sub_func_int32_t_s_s(0x8D33576CL, (safe_rshift_func_uint8_t_u_u((safe_add_func_int8_t_s_s((((safe_lshift_func_uint16_t_u_s(((*g_127) != ((l_3824 == ((*l_3826) = (l_3748 , l_3825[0][0]))) || ((((l_3827[0] != (**g_3349)) || 0x1CL) == 0xE8B82DC7BBA9FDFCLL) && l_3828))), 2)) , 0xDDL) <= 1UL), l_3803[4][2][0])), l_3748)))) && (*l_3429)))) || 0L) , l_3664)) >= l_3829))) + { /* block id: 1742 */ + int32_t *l_3836 = &g_75[2]; + (***g_2621) |= (0x3F81L <= (safe_mul_func_int16_t_s_s((safe_lshift_func_uint16_t_u_u(((**g_642)--), 9)), 0xF858L))); + (**g_1175) = l_3836; + } + else + { /* block id: 1746 */ + int16_t l_3841 = 0x5F4CL; + int32_t l_3852 = 0L; + uint64_t *****l_3854 = &g_1567; + int32_t l_3855[6][6] = {{3L,1L,3L,3L,1L,3L},{3L,1L,3L,3L,1L,3L},{3L,1L,3L,3L,1L,3L},{3L,1L,3L,3L,1L,3L},{3L,1L,3L,3L,1L,3L},{3L,1L,3L,3L,1L,3L}}; + int i, j; + (**g_2622) = (((g_1185 == l_3837) && (l_3838 == l_3840)) < l_3803[5][1][0]); + l_3855[1][2] |= ((l_3841 != ((safe_add_func_uint64_t_u_u((((l_3853[3][3][2] ^= (safe_sub_func_uint64_t_u_u(((((*g_127) &= (l_3852 ^= (l_3846 && ((((((**l_3703) = ((******l_3838) <= ((**g_2620) == (void*)0))) , (g_3847 , (safe_rshift_func_int8_t_s_u(l_3803[5][1][0], (safe_mul_func_uint8_t_u_u((*g_983), 255UL)))))) , (***g_2621)) <= (*g_3714)) < 0xFB0546D3BB5BDDC7LL)))) , (*g_3310)) == (*g_3310)), 5L))) , l_3389) != l_3854), l_3841)) == l_3664)) || 1L); + } + } +lbl_3862: + l_3369 = ((l_3856 >= (*g_643)) & (((l_3857 = l_3857) == (((*****l_3839) = l_3580) , l_3858)) ^ (l_5 &= (safe_rshift_func_int16_t_s_u(0L, 14))))); + for (l_6 = 0; (l_6 < 6); l_6++) + { /* block id: 1762 */ + int8_t l_3869 = 0x66L; + int32_t l_3881 = 9L; + int16_t *l_3885 = (void*)0; + if ((*****l_3839)) + { /* block id: 1763 */ + int8_t **l_3870 = (void*)0; + int8_t **l_3871 = &g_3328; + uint8_t l_3882 = 1UL; + uint64_t **** const **l_3910 = &l_3909[2]; + uint8_t l_3911[4] = {0x92L,0x92L,0x92L,0x92L}; + const int32_t *l_3914 = &l_3881; + int i; + g_3879 |= (((safe_add_func_uint64_t_u_u((safe_mul_func_int16_t_s_s(l_3869, (*g_1739))), (&g_708 == ((*l_3871) = (void*)0)))) , (((((*****l_3839) == ((0x80L && ((*g_983) = (*g_983))) , l_3872)) && (safe_add_func_int64_t_s_s((((safe_div_func_int8_t_s_s((safe_mul_func_int16_t_s_s(0x5326L, (*l_3429))), (*g_983))) & 0L) ^ (*l_3429)), 1L))) > (*****l_3839)) , 0x75F6BE4B492A4C37LL)) , (**g_267)); + l_3882++; + (******l_3838) = (**g_2622); + l_3914 = func_99((*****l_3839), ((((void*)0 != l_3885) == ((safe_mod_func_uint32_t_u_u(((safe_sub_func_uint64_t_u_u((safe_add_func_int64_t_s_s(((((((safe_sub_func_int64_t_s_s(((((safe_lshift_func_uint16_t_u_s((safe_sub_func_uint16_t_u_u((safe_rshift_func_int16_t_s_s((l_3881 , (safe_mod_func_uint64_t_u_u(((safe_lshift_func_uint8_t_u_s((safe_sub_func_uint8_t_u_u((*****l_3839), (*g_983))), 4)) , ((0x433AL || ((*l_3543) = (+((l_3908 < ((((*l_3910) = l_3909[4]) != (*g_3771)) || l_3911[1])) >= 0x39BC5FC44F688776LL)))) != (*g_643))), (*g_127)))), l_3912[0])), (*g_643))), 13)) ^ l_3869) == 0x0D9A3BF5L) , l_3911[0]), (*****l_3839))) && l_3869) , (void*)0) != &g_277[0]) > (*g_2632)) & (**g_642)), (******l_3838))), 0xA445774BC6D1CC7ALL)) < 0UL), 0x210284B3L)) , l_3882)) , 0x7739L), (*l_3438), g_3913, &l_3625); + } + else + { /* block id: 1772 */ + int32_t **l_3915 = &l_3[7][8][1]; + (*l_3915) = (***g_2620); + if ((*g_268)) + break; + } + return (*l_3429); + } + } + l_3362 &= (safe_sub_func_uint64_t_u_u(((*l_3240) ^= (safe_sub_func_uint16_t_u_u((safe_rshift_func_int16_t_s_u(0L, (--(**g_1574)))), (((safe_add_func_int8_t_s_s((safe_mod_func_int64_t_s_s((((*g_1701) = (safe_rshift_func_int8_t_s_s((safe_rshift_func_int8_t_s_s((((*g_983) > ((safe_div_func_uint8_t_u_u(((&g_3601 != l_3934) & (safe_mul_func_uint8_t_u_u((safe_sub_func_int64_t_s_s((***g_276), (*g_127))), ((*****g_3348) <= (l_3419[2] > ((safe_add_func_uint8_t_u_u((l_7 != l_3912[3]), 0x03L)) == l_3912[2])))))), 3UL)) > 0x47L)) | (*l_3429)), g_2797)), 4))) != (-6L)), 2L)), l_3363)) , (*l_3429)) , 0x86BCL)))), l_3664)); + } + } + else + { /* block id: 1784 */ + int32_t l_3943[3]; + int32_t l_3954 = (-1L); + uint16_t ****l_3978 = (void*)0; + uint16_t *****l_3977[1]; + const uint32_t *l_3980 = &l_2; + uint32_t **l_3986 = &g_1701; + uint32_t *******l_3990 = &l_3989; + uint32_t *******l_3991 = (void*)0; + uint32_t ******l_3993[10] = {&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3],&g_3600[4][2][3]}; + uint32_t *******l_3992 = &l_3993[3]; + uint64_t *****l_3998[3]; + int32_t l_4006 = 0x80D0535EL; + int i; + for (i = 0; i < 3; i++) + l_3943[i] = 0x14357B69L; + for (i = 0; i < 1; i++) + l_3977[i] = &l_3978; + for (i = 0; i < 3; i++) + l_3998[i] = &g_1567; + (**g_999) &= (-1L); + for (g_3407 = 26; (g_3407 >= (-14)); g_3407--) + { /* block id: 1788 */ + uint32_t l_3947 = 1UL; + uint32_t **l_3979[8][9] = {{(void*)0,(void*)0,(void*)0,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,(void*)0,&g_1701,&g_1701,&g_1701,(void*)0,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,(void*)0,(void*)0,(void*)0,&g_1701,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,(void*)0,&g_1701,(void*)0},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,&g_1701,(void*)0,&g_1701,&g_1701,&g_1701,&g_1701,(void*)0,&g_1701},{&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701},{&g_1701,(void*)0,&g_1701,(void*)0,&g_1701,&g_1701,&g_1701,&g_1701,&g_1701}}; + int32_t l_3985 = (-6L); + int i, j; + for (l_2 = 0; (l_2 <= 5); l_2 += 1) + { /* block id: 1791 */ + int32_t l_3953 = 0x2CBB6FB6L; + int8_t *l_3968 = (void*)0; + int8_t *l_3969 = (void*)0; + int8_t *l_3970 = (void*)0; + int8_t *l_3971 = &g_458.f3; + int32_t l_3972 = 0x21880BDEL; + int i, j; + (**g_2622) = (l_3943[0] , (*g_268)); + (***g_1175) |= (l_3944 <= (safe_lshift_func_uint8_t_u_s(((l_3947 && (l_3943[0] == ((((*l_3158) |= (safe_rshift_func_uint16_t_u_u(l_3950, 13))) | (g_3254 = (safe_rshift_func_uint8_t_u_u(l_3953, 5)))) != ((*g_983)++)))) <= (safe_mod_func_uint64_t_u_u((l_3495 && (safe_lshift_func_uint8_t_u_u((safe_lshift_func_int8_t_s_s((safe_unary_minus_func_int64_t_s((safe_sub_func_uint32_t_u_u((safe_mul_func_int8_t_s_s(((*l_3971) = l_3954), (l_3943[1] | (*****g_3348)))), l_3664)))), l_3972)), l_3947))), l_3972))), 6))); + } + (**g_999) = ((((((**l_3596) = (safe_mod_func_uint8_t_u_u(((safe_lshift_func_uint16_t_u_u(((void*)0 != l_3977[0]), 7)) & (l_3979[4][5] != (((*g_457) = ((l_3947 && (l_3954 ^= ((l_3943[0] || (l_3980 != (((safe_rshift_func_int16_t_s_s(((****g_2978) | ((safe_mod_func_uint8_t_u_u(l_3947, l_3985)) != l_3943[1])), 7)) | l_3943[2]) , l_3980))) ^ 0xF710904B1728434FLL))) , (*g_457))) , l_3986))), l_3943[2]))) & (*g_2632)) < 0UL) >= 0x51L) ^ l_3944); + if (g_3515) + goto lbl_4001; + } +lbl_4001: + (***g_1175) = (safe_div_func_uint16_t_u_u(0x3752L, ((((*l_3990) = l_3989) == ((*l_3992) = &g_3600[3][1][4])) , ((((safe_add_func_uint16_t_u_u((safe_mul_func_uint16_t_u_u(l_3371, ((((l_3998[0] != (void*)0) & ((((l_3954 , (safe_mul_func_uint16_t_u_u((*g_2632), ((l_3943[0] , 0xF4L) >= 1UL)))) <= 0L) | 0xF16E067CL) < (-2L))) != 9UL) > l_3362))), (*g_643))) , (void*)0) == (void*)0) , 0x3FC4L)))); + for (g_458.f2 = 12; (g_458.f2 < 6); g_458.f2--) + { /* block id: 1810 */ + uint16_t l_4014 = 0UL; + for (g_3879 = 0; (g_3879 >= 0); g_3879++) + { /* block id: 1813 */ + int32_t *l_4007 = &l_7; + int32_t *l_4008 = &g_75[0]; + int32_t *l_4009 = &l_3362; + int32_t *l_4010 = (void*)0; + int32_t *l_4011 = (void*)0; + int32_t *l_4012[6] = {&l_3943[0],&l_3943[0],&l_3943[0],&l_3943[0],&l_3943[0],&l_3943[0]}; + int64_t l_4013 = 0x2BE90AF3ABBB321ALL; + int i; + ++l_4014; + return l_4006; + } + return l_4014; + } + } + return l_4017; +} + + +/* ------------------------------------------ */ +/* + * reads : g_20 g_999 g_1000 + * writes: g_20 + */ +static int32_t * func_13(uint8_t p_14) +{ /* block id: 10 */ + int32_t *l_15 = (void*)0; + int32_t *l_16 = (void*)0; + int32_t l_17[7][6] = {{2L,1L,0xDDB2097EL,1L,1L,0xDDB2097EL},{2L,(-1L),1L,(-3L),0xF8DE905FL,(-9L)},{0L,(-1L),1L,(-1L),1L,1L},{0x1450187EL,1L,1L,0x1450187EL,(-1L),(-9L)},{(-3L),3L,1L,0x1450187EL,(-9L),0xDDB2097EL},{0x1450187EL,(-9L),0xDDB2097EL,(-1L),(-9L),3L},{0L,3L,(-1L),(-3L),(-1L),3L}}; + int32_t *l_18[7] = {&g_4[0],&g_4[0],&g_4[0],&g_4[0],&g_4[0],&g_4[0],&g_4[0]}; + int8_t l_19 = 0xA6L; + int16_t l_21[7][4][1] = {{{0x8108L},{0x030DL},{1L},{1L}},{{1L},{0x030DL},{0x8108L},{0x030DL}},{{1L},{1L},{1L},{0x030DL}},{{0x8108L},{0x030DL},{1L},{1L}},{{1L},{0x030DL},{0x8108L},{0x030DL}},{{1L},{1L},{1L},{0x030DL}},{{0x8108L},{0x030DL},{1L},{1L}}}; + uint64_t l_22 = 18446744073709551615UL; + uint16_t l_2653 = 65530UL; + uint32_t l_3086 = 4294967289UL; + int32_t ***l_3091 = &g_999; + int i, j, k; + l_22++; + for (l_19 = 0; (l_19 <= (-1)); l_19 = safe_sub_func_uint32_t_u_u(l_19, 9)) + { /* block id: 14 */ + int32_t *l_27[5]; + int i; + for (i = 0; i < 5; i++) + l_27[i] = &l_17[3][1]; + g_20 = 0x22E85F59L; + return &g_20; + } + for (g_20 = 0; (g_20 <= 15); g_20 = safe_add_func_int64_t_s_s(g_20, 7)) + { /* block id: 20 */ + union U0 l_43[1][9][2] = {{{{-6L},{0xEAL}},{{0x1EL},{-2L}},{{0x1EL},{0xEAL}},{{-6L},{-6L}},{{0xEAL},{0x1EL}},{{-2L},{0x1EL}},{{0xEAL},{-6L}},{{-6L},{0xEAL}},{{0x1EL},{-2L}}}}; + int32_t *l_2652 = &g_4[4]; + uint64_t *l_2654 = &g_132; + const uint32_t *l_3095 = &g_254; + const uint32_t **l_3094[8][7] = {{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095},{&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095,&l_3095}}; + uint16_t **l_3114 = &g_643; + uint16_t ***l_3115 = &g_642; + uint16_t ***l_3117 = (void*)0; + uint16_t ***l_3118 = &l_3114; + int i, j, k; + } + return (**l_3091); +} + + +/* ------------------------------------------ */ +/* + * reads : g_642 g_643 g_177 g_209.f2 g_2193.f0 g_1739 g_384 g_1585 g_127 g_128 g_409 g_983 g_130 g_1175 g_999 g_1000 g_20 g_2620 g_2621 g_2622 g_267 g_268 g_4 g_135 g_2193.f1 g_1738 g_147 g_78 g_458.f2 g_1679 g_2866 g_159 g_888 g_276 g_277 g_2033 g_67 g_2895 g_2797 g_2632 g_380 g_1701 g_132 g_2307 g_1574 g_254 g_209.f3 g_2980 g_458.f3 g_2193.f3 g_458.f0 g_2978 g_206 g_1567 g_1568 g_1569 g_708 + * writes: g_647 g_209.f2 g_384 g_2193.f0 g_2193.f2 g_177 g_1000 g_268 g_383 g_78 g_1744 g_458.f2 g_130 g_1567 g_1679 g_1585 g_128 g_253 g_2895 g_254 g_132 g_209.f3 g_2978 g_2797 g_4 g_458.f3 g_2193.f3 g_67 g_206 g_1569 g_2033 g_708 g_457 + */ +static uint64_t func_34(int32_t p_35, uint64_t p_36, int8_t p_37, int32_t * p_38) +{ /* block id: 1210 */ + uint32_t l_2659 = 0xE6BBA822L; + const uint32_t *l_2661 = &l_2659; + const uint32_t **l_2660 = &l_2661; + uint32_t ***l_2662 = &g_647[5][0]; + union U0 l_2663[9][8][3] = {{{{0L},{0L},{0x70L}},{{1L},{-1L},{-4L}},{{-1L},{1L},{0x3EL}},{{1L},{0xBEL},{5L}},{{-1L},{0L},{0L}},{{0x45L},{-5L},{0x45L}},{{-1L},{0x70L},{0x62L}},{{7L},{0x50L},{0x60L}}},{{{1L},{7L},{0x69L}},{{0x43L},{8L},{-6L}},{{1L},{-5L},{-2L}},{{7L},{0x19L},{0L}},{{-1L},{0L},{0x60L}},{{0x45L},{0x70L},{0x37L}},{{-1L},{-1L},{-1L}},{{1L},{-1L},{0x0BL}}},{{{8L},{0x70L},{-6L}},{{-1L},{0L},{5L}},{{-9L},{0x19L},{0x69L}},{{0x60L},{-5L},{-1L}},{{0x45L},{8L},{1L}},{{7L},{7L},{-1L}},{{-1L},{0x50L},{0x69L}},{{0L},{0x70L},{5L}}},{{{0x37L},{-5L},{-6L}},{{-9L},{0L},{0x0BL}},{{-1L},{0xBEL},{-1L}},{{-1L},{-1L},{0x37L}},{{-9L},{7L},{0x60L}},{{0x37L},{-1L},{0L}},{{0L},{8L},{-2L}},{{-1L},{0xBEL},{-6L}}},{{{7L},{-1L},{0x69L}},{{0x45L},{0xBEL},{0x60L}},{{0x60L},{8L},{0x62L}},{{-9L},{-1L},{0x45L}},{{-1L},{7L},{0L}},{{8L},{-1L},{5L}},{{1L},{0xBEL},{5L}},{{-1L},{0L},{0L}}},{{{0x45L},{-5L},{0x45L}},{{-1L},{0x70L},{0x62L}},{{7L},{0x50L},{0x60L}},{{1L},{7L},{0x69L}},{{0x43L},{8L},{-6L}},{{1L},{-5L},{-2L}},{{7L},{0x19L},{0L}},{{-1L},{0L},{0x60L}}},{{{0x45L},{0x70L},{0x37L}},{{-1L},{-1L},{-1L}},{{1L},{-1L},{0x0BL}},{{8L},{0x70L},{-6L}},{{-1L},{0L},{5L}},{{-9L},{0x19L},{0x69L}},{{0x60L},{-5L},{-1L}},{{0x45L},{8L},{1L}}},{{{7L},{7L},{-1L}},{{-1L},{0x50L},{0x69L}},{{0L},{0x70L},{5L}},{{0x37L},{-5L},{-6L}},{{-9L},{0L},{0x0BL}},{{-1L},{0xBEL},{-1L}},{{-1L},{-1L},{0x37L}},{{-9L},{7L},{0x60L}}},{{{0x37L},{-1L},{0L}},{{0L},{8L},{-2L}},{{-1L},{-1L},{0xD9L}},{{-1L},{0x69L},{7L}},{{-1L},{-1L},{8L}},{{8L},{-1L},{1L}},{{0x42L},{8L},{-1L}},{{0x73L},{0L},{-1L}}}}; + int32_t ****l_2677[8]; + int32_t *****l_2676[1][1]; + uint64_t ****l_2686 = &g_1568[4][1]; + uint16_t ***l_2785 = &g_642; + uint16_t *** const *l_2784 = &l_2785; + uint32_t ****l_2874 = &g_1926[0]; + uint32_t *****l_2873[9][1] = {{(void*)0},{&l_2874},{(void*)0},{&l_2874},{(void*)0},{&l_2874},{(void*)0},{&l_2874},{(void*)0}}; + int8_t *l_2888[5][6] = {{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}}; + union U0 **l_2893[8] = {&g_457,&g_457,&g_457,&g_457,&g_457,&g_457,&g_457,&g_457}; + int64_t l_3030 = 6L; + uint32_t l_3043 = 1UL; + uint64_t l_3070[3]; + int8_t l_3080 = 0x9DL; + int i, j, k; + for (i = 0; i < 8; i++) + l_2677[i] = &g_1175; + for (i = 0; i < 1; i++) + { + for (j = 0; j < 1; j++) + l_2676[i][j] = &l_2677[1]; + } + for (i = 0; i < 3; i++) + l_3070[i] = 0xA9198D57D8E9CE12LL; + if ((safe_sub_func_int32_t_s_s(((p_37 <= (l_2659 >= (l_2659 , (l_2660 != ((*l_2662) = &g_648))))) == (p_37 | ((((l_2663[5][6][0] , (0UL ^ (safe_add_func_uint16_t_u_u(65527UL, l_2659)))) || 255UL) > 0xD69664490FDEA123LL) , (**g_642)))), p_36))) + { /* block id: 1212 */ + uint32_t l_2678 = 0xD9A0AAF9L; + int32_t l_2679 = 0xD6B89FB5L; + int32_t l_2729 = 0xEED0CCDFL; + int32_t l_2765 = (-4L); + int32_t l_2768[6][4][2] = {{{0L,0x5E79F3B8L},{0x77FE2768L,8L},{0x78A14A41L,8L},{0x77FE2768L,0x5E79F3B8L}},{{0L,0x35D21069L},{0L,0x5E79F3B8L},{0x77FE2768L,8L},{0x78A14A41L,8L}},{{0x77FE2768L,0x5E79F3B8L},{0L,0x35D21069L},{0L,0x5E79F3B8L},{0x77FE2768L,8L}},{{0x78A14A41L,8L},{0x77FE2768L,0x5E79F3B8L},{0L,0x35D21069L},{0L,0x5E79F3B8L}},{{0x77FE2768L,8L},{0x78A14A41L,8L},{0x77FE2768L,0x5E79F3B8L},{0L,0x35D21069L}},{{0L,0x5E79F3B8L},{0x77FE2768L,8L},{0x78A14A41L,8L},{0x77FE2768L,0x5E79F3B8L}}}; + uint64_t ****l_2800 = &g_1568[4][0]; + int64_t *l_2804 = &g_253; + uint16_t l_2820[8] = {0x422DL,65530UL,65530UL,0x422DL,65530UL,65530UL,0x422DL,65530UL}; + uint32_t l_2877 = 0x2C8835BCL; + int16_t l_2914 = 0x56BAL; + uint16_t *** const **l_2979 = &l_2784; + int64_t l_3041[4]; + int16_t *l_3062 = &g_384; + int32_t *l_3075 = &g_2033[0]; + int i, j, k; + for (i = 0; i < 4; i++) + l_3041[i] = 0xDC70C96AD5BD10D0LL; + for (g_209.f2 = 0; (g_209.f2 > 21); g_209.f2 = safe_add_func_int64_t_s_s(g_209.f2, 4)) + { /* block id: 1215 */ + const int32_t *l_2672 = (void*)0; + union U0 l_2673 = {4L}; + int32_t l_2736 = 0L; + union U0 ** const l_2753[9][8][3] = {{{(void*)0,&g_457,&g_457},{&g_457,(void*)0,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,&g_457},{(void*)0,(void*)0,&g_457},{&g_457,(void*)0,&g_457},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457}},{{(void*)0,&g_457,&g_457},{&g_457,(void*)0,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,&g_457},{(void*)0,(void*)0,&g_457},{&g_457,(void*)0,&g_457},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457}},{{(void*)0,&g_457,&g_457},{&g_457,(void*)0,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,&g_457},{(void*)0,(void*)0,&g_457},{&g_457,(void*)0,&g_457},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}},{{&g_457,&g_457,(void*)0},{&g_457,(void*)0,(void*)0},{&g_457,&g_457,&g_457},{&g_457,&g_457,(void*)0},{&g_457,&g_457,(void*)0},{&g_457,(void*)0,&g_457},{&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457}}}; + int16_t l_2816 = 9L; + int32_t ****l_2824[10][1] = {{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175},{&g_1175}}; + int i, j, k; + if ((safe_mul_func_uint8_t_u_u(0xE0L, l_2659))) + { /* block id: 1216 */ + int32_t *****l_2674 = (void*)0; + int32_t l_2735 = 1L; + union U0 *l_2739[5][7] = {{&l_2673,&g_458,&l_2673,&g_458,&l_2673,&g_458,&l_2673},{&g_458,&g_458,&g_458,&g_458,&g_458,&g_458,&g_458},{(void*)0,&g_458,(void*)0,&g_458,(void*)0,&g_458,(void*)0},{&g_458,&g_458,&g_458,&g_458,&g_458,&g_458,&g_458},{&l_2673,&g_458,&l_2673,&g_458,&l_2673,&g_458,&l_2673}}; + int32_t l_2763[5][10] = {{6L,0x397EDD9EL,0x5DA38F3AL,0x1FBBC128L,(-8L),1L,1L,0x4CB10F04L,1L,1L},{0x38C35325L,8L,0xA33152A2L,8L,0x38C35325L,0x1FBBC128L,1L,0xB1074C35L,0x02D6F10EL,0x264D6A40L},{0x1FBBC128L,1L,0xB1074C35L,0x02D6F10EL,0x264D6A40L,6L,0L,0L,6L,0x264D6A40L},{0xA33152A2L,0x02D6F10EL,0x02D6F10EL,0xA33152A2L,0x38C35325L,0x397EDD9EL,0x5DA38F3AL,0x1FBBC128L,(-8L),1L},{0x99EB6806L,0x38C35325L,0x4472C795L,6L,(-8L),0x5DA38F3AL,0x02D6F10EL,0x5DA38F3AL,(-8L),6L}}; + int32_t *l_2773 = &l_2735; + union U0 l_2802[3] = {{0x44L},{0x44L},{0x44L}}; + int64_t * const l_2803 = &g_128[0][3][1]; + int i, j; + for (g_384 = 0; (g_384 >= (-27)); g_384 = safe_sub_func_int8_t_s_s(g_384, 9)) + { /* block id: 1219 */ + int32_t ******l_2675[7]; + int16_t *l_2702 = &g_2193.f2; + int16_t ***l_2705 = (void*)0; + union U0 l_2712[6] = {{-1L},{-1L},{-1L},{-1L},{-1L},{-1L}}; + int32_t *l_2727[10] = {&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1],&g_67[1]}; + int64_t ***l_2734 = (void*)0; + int i; + for (i = 0; i < 7; i++) + l_2675[i] = &l_2674; + l_2679 |= (l_2673 , (p_35 = ((&g_2620 != (l_2676[0][0] = l_2674)) , l_2678))); + for (g_2193.f0 = (-14); (g_2193.f0 > (-17)); g_2193.f0 = safe_sub_func_uint32_t_u_u(g_2193.f0, 3)) + { /* block id: 1225 */ + uint16_t l_2695 = 65529UL; + p_35 = (safe_mul_func_int8_t_s_s(p_36, ((p_36 && ((safe_lshift_func_int16_t_s_u((*g_1739), 11)) <= (!g_1585))) || (l_2686 == ((safe_rshift_func_int16_t_s_u(((1L & (0x875FC4C2A9E98904LL >= (*g_127))) && (safe_mul_func_int16_t_s_s((safe_rshift_func_uint8_t_u_s((((1L ^ 0x59L) != g_409[0][0]) & l_2679), 5)), p_35))), 10)) , &g_1568[4][1]))))); + return l_2695; + } + if ((safe_rshift_func_int16_t_s_u(((*l_2702) = (safe_rshift_func_int8_t_s_s(p_35, (safe_sub_func_int64_t_s_s(p_35, 0xD0504981CA921F75LL))))), 8))) + { /* block id: 1230 */ + uint64_t *****l_2723 = &l_2686; + uint64_t *****l_2725 = &l_2686; + uint64_t ******l_2724 = &l_2725; + const int32_t l_2726 = 0x5342A3C5L; + int32_t l_2728 = (-1L); + int8_t l_2730[2][2] = {{0xAAL,0xAAL},{0xAAL,0xAAL}}; + int i, j; + l_2728 ^= (((safe_lshift_func_int8_t_s_s(1L, 2)) ^ ((l_2705 == (((((safe_div_func_int64_t_s_s((safe_add_func_uint16_t_u_u((~((**g_642) = 5UL)), ((-1L) | (p_37 && (255UL ^ (safe_div_func_uint16_t_u_u((l_2712[4] , (safe_rshift_func_int8_t_s_u((safe_lshift_func_int16_t_s_s((safe_lshift_func_int16_t_s_s((((safe_mod_func_uint32_t_u_u((safe_mul_func_uint16_t_u_u((l_2723 != ((*l_2724) = (void*)0)), (*g_1739))), p_37)) | p_35) == p_35), 7)), l_2726)), (*g_983)))), 0xB71CL))))))), (*g_127))) , (void*)0) != l_2727[5]) || 0x8EL) , (void*)0)) >= (*g_1739))) , (***g_1175)); + if ((****g_2620)) + break; + l_2730[1][1] = l_2729; + } + else + { /* block id: 1236 */ + return p_37; + } + if ((safe_lshift_func_uint16_t_u_u(((((*l_2702) = 0L) != p_36) | p_37), 7))) + { /* block id: 1240 */ + uint32_t l_2733 = 0x82ED76E6L; + l_2733 = (-1L); + } + else + { /* block id: 1242 */ + l_2735 &= (l_2734 == l_2734); + } + } + l_2736 |= (**g_267); + if ((safe_add_func_uint8_t_u_u((l_2736 = ((void*)0 == l_2739[3][2])), p_35))) + { /* block id: 1248 */ + uint16_t l_2740 = 1UL; + int32_t l_2761 = (-6L); + int32_t l_2762 = 0x8DFA1675L; + int32_t l_2766 = (-5L); + uint32_t l_2770[4] = {0UL,0UL,0UL,0UL}; + int i; + ++l_2740; + for (l_2740 = 27; (l_2740 != 5); l_2740 = safe_sub_func_uint16_t_u_u(l_2740, 2)) + { /* block id: 1252 */ + int16_t l_2760[10]; + int32_t l_2764 = 6L; + int32_t l_2769[3]; + int i; + for (i = 0; i < 10; i++) + l_2760[i] = (-8L); + for (i = 0; i < 3; i++) + l_2769[i] = (-6L); + (**g_1175) = &l_2736; + --l_2770[2]; + (*g_999) = (void*)0; + return l_2760[2]; + } + } + else + { /* block id: 1261 */ + uint32_t l_2796 = 9UL; + int32_t *l_2798[5] = {(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}; + int i; + if ((*g_268)) + { /* block id: 1262 */ + uint16_t *** const **l_2786 = &l_2784; + int32_t l_2795 = 0x7599A3ABL; + uint64_t ****l_2799 = &g_1568[4][0]; + int16_t *l_2801 = &l_2673.f2; + if (p_37) + break; + l_2773 = ((*g_999) = (*g_999)); + (*g_267) = func_99(p_36, ((*l_2801) = (p_37 > (safe_mul_func_uint16_t_u_u(((((safe_rshift_func_uint16_t_u_s((0xA7D8L | 0x13AAL), (((safe_sub_func_uint16_t_u_u((((p_36 < (((p_35 , (***g_2620)) != (void*)0) & p_37)) | p_35) > p_35), p_36)) , l_2799) != l_2800))) || p_35) < (**g_999)) , 0x0759L), p_37)))), l_2802[1], l_2803, l_2804); + (*g_999) = (*g_999); + } + else + { /* block id: 1271 */ + int32_t *l_2805 = &g_4[3]; + int32_t l_2819 = 0x77B6F82EL; + uint8_t *l_2821 = &g_183; + int16_t *l_2822 = &g_383; + int32_t ****l_2823 = &g_1175; + (*g_999) = &p_35; + (**g_999) |= (p_37 , 0xFCBABA69L); + (***g_1175) = (((*g_1739) >= ((&g_2630[1] == (void*)0) ^ (l_2820[0] & ((((p_37 && ((((*l_2822) = ((void*)0 == l_2821)) , ((l_2823 = &g_1175) == l_2824[5][0])) || (****l_2823))) >= (*g_1739)) ^ 1UL) == l_2678)))) >= 0xCDL); + return p_35; + } + for (g_2193.f0 = 4; (g_2193.f0 == (-22)); g_2193.f0 = safe_sub_func_int16_t_s_s(g_2193.f0, 1)) + { /* block id: 1283 */ + return p_37; + } + return p_37; + } + } + else + { /* block id: 1288 */ + uint8_t l_2841 = 255UL; + int32_t l_2855 = 0x59A23047L; + for (g_2193.f0 = 0; (g_2193.f0 <= 2); g_2193.f0 += 1) + { /* block id: 1291 */ + const int32_t *l_2842 = &g_135; + const uint64_t *l_2844 = (void*)0; + const uint64_t **l_2843 = &l_2844; + int32_t *l_2857 = &l_2736; + int i; + for (g_78 = 0; (g_78 <= 8); g_78 += 1) + { /* block id: 1294 */ + uint16_t l_2827 = 7UL; + int32_t l_2830 = 0xE016D88CL; + l_2827++; + l_2830 &= (-1L); + } + if (((safe_rshift_func_uint16_t_u_s(l_2820[(g_2193.f0 + 1)], (safe_add_func_uint16_t_u_u((l_2663[7][2][0] , (*l_2842)), p_36)))) | 0xBE527B2BDF448059LL)) + { /* block id: 1299 */ + int8_t l_2856 = 0x29L; + (*g_999) = func_57((*g_999), ((l_2843 == (void*)0) , ((safe_mod_func_uint8_t_u_u((safe_add_func_int8_t_s_s(((((safe_div_func_uint8_t_u_u((safe_mod_func_uint32_t_u_u((l_2768[3][3][1] = ((safe_add_func_uint8_t_u_u(((void*)0 != &l_2800), (p_36 , (p_37 > ((((p_35 ^ 0xB492343EL) > l_2855) || p_36) | l_2856))))) == (****g_2620))), p_36)), g_2193.f1)) && 0xE3L) && (*l_2842)) < 0xE6DA936EL), (*g_983))), 0x29L)) , (void*)0)), (*g_999), (*l_2842), l_2857); + } + else + { /* block id: 1302 */ + return l_2855; + } + } + p_35 = (**g_999); + } + for (g_1585 = 26; (g_1585 > 26); g_1585++) + { /* block id: 1310 */ + l_2768[5][3][0] ^= 0x7E03A76CL; + } + } + if ((safe_sub_func_uint8_t_u_u((*g_983), (((safe_sub_func_uint16_t_u_u((safe_mod_func_int16_t_s_s(g_2866, ((((safe_rshift_func_uint8_t_u_u(0x04L, 0)) , (((safe_mul_func_int8_t_s_s((!(((safe_rshift_func_uint8_t_u_u(p_37, p_35)) || ((((l_2873[7][0] == &l_2874) , (p_36 > (p_35 > g_159))) || (****g_2620)) != p_36)) , 0x8FL)), p_37)) , 0xC51F7467L) <= p_35)) , p_36) & p_37))), (*g_643))) && p_36) == g_888)))) + { /* block id: 1314 */ + int32_t l_2875 = 0x072117A4L; + int16_t *l_2876 = &l_2663[5][6][0].f2; + int32_t l_2896 = 0x3B26EDE4L; + uint8_t l_2905 = 0xBBL; + int32_t l_2925 = 0xF4C5A4F9L; + uint64_t *l_2935 = &g_132; + uint64_t ****l_3012[7]; + int32_t l_3036 = 0x9F84FF97L; + int32_t l_3037[3]; + int i; + for (i = 0; i < 7; i++) + l_3012[i] = (void*)0; + for (i = 0; i < 3; i++) + l_3037[i] = 0x4970F08FL; + if ((((l_2877 = ((((*l_2876) = l_2875) & (((***g_276) = p_35) > 0x1D03E76480D707F5LL)) && (-7L))) | ((((safe_mul_func_uint8_t_u_u((safe_lshift_func_uint16_t_u_u(((((*l_2804) = (0x9B49AC22L < l_2820[0])) != 18446744073709551615UL) > ((((*g_983) = (safe_mul_func_uint16_t_u_u(65535UL, l_2875))) , 0x307F9F6FL) == 0x9122E523L)), 2)), 247UL)) > 0L) <= 0xD0L) ^ (-6L))) > p_36)) + { /* block id: 1320 */ + int8_t *l_2889 = &g_458.f1; + int32_t l_2892 = 8L; + int64_t *l_2899 = &g_91; + int16_t ***l_2923 = &g_2230; + int32_t l_2924 = 4L; + int32_t l_2936 = 1L; + int32_t l_2940 = 1L; + for (g_458.f2 = 0; (g_458.f2 <= 1); g_458.f2 += 1) + { /* block id: 1323 */ + union U0 l_2897 = {0x8FL}; + int64_t * const l_2898 = (void*)0; + int16_t l_2926 = 0xAAA4L; + int16_t *l_2937 = &g_2193.f2; + int16_t *l_2938[10][6] = {{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}}; + int32_t l_2939 = 0x635F255EL; + const int16_t ** const *l_2964[8][6][5] = {{{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][6],(void*)0,&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[2][0][5],&g_1738[0][0][0],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][2],(void*)0,&g_1738[2][0][6],&g_1738[0][0][1]},{&g_1738[1][0][2],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][0],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][1],(void*)0,(void*)0,&g_1738[0][0][2]},{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][5],&g_1738[0][0][0],&g_1738[0][0][1]}},{{&g_1738[0][0][1],&g_1738[0][0][2],&g_1738[2][0][6],&g_1738[2][0][6],&g_1738[0][0][2]},{&g_1738[1][0][2],&g_1738[2][0][0],&g_1738[0][0][1],&g_1738[0][0][0],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][6],(void*)0,&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[2][0][5],&g_1738[0][0][0],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][2],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][3]}},{{&g_1738[1][0][4],&g_1738[1][0][2],&g_1738[2][0][2],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][1]},{&g_1738[1][0][4],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][3]},{&g_1738[0][0][1],&g_1738[1][0][2],&g_1738[0][0][1],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]}},{{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][2],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][3]},{&g_1738[1][0][4],&g_1738[1][0][2],&g_1738[2][0][2],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][1]},{&g_1738[1][0][4],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][3]}},{{&g_1738[0][0][1],&g_1738[1][0][2],&g_1738[0][0][1],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][2],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][3]},{&g_1738[1][0][4],&g_1738[1][0][2],&g_1738[2][0][2],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][1]}},{{&g_1738[1][0][4],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][3]},{&g_1738[0][0][1],&g_1738[1][0][2],&g_1738[0][0][1],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][2],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][3]}},{{&g_1738[1][0][4],&g_1738[1][0][2],&g_1738[2][0][2],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][1]},{&g_1738[1][0][4],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][3]},{&g_1738[0][0][1],&g_1738[1][0][2],&g_1738[0][0][1],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]}},{{&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][2],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][3]},{&g_1738[1][0][4],&g_1738[1][0][2],&g_1738[2][0][2],&g_1738[0][0][2],&g_1738[0][0][1]},{&g_1738[0][0][5],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][1]},{&g_1738[1][0][4],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[0][0][1]},{(void*)0,&g_1738[0][0][1],&g_1738[0][0][1],&g_1738[2][0][0],&g_1738[0][0][3]}}}; + int32_t ****l_2977 = (void*)0; + int i, j, k; + if ((safe_add_func_uint64_t_u_u(g_2033[(g_458.f2 + 2)], (g_67[g_458.f2] | g_2033[(g_458.f2 + 2)])))) + { /* block id: 1324 */ + int16_t *l_2894[5][3]; + int i, j; + for (i = 0; i < 5; i++) + { + for (j = 0; j < 3; j++) + l_2894[i][j] = (void*)0; + } + (*g_267) = func_99((l_2888[4][1] == l_2889), (l_2896 |= (p_36 ^ (((void*)0 == (*g_2621)) <= (g_2895 |= (((((l_2765 <= l_2892) , (void*)0) == l_2893[1]) <= l_2875) , p_36))))), l_2897, l_2898, l_2899); + l_2924 ^= (safe_sub_func_uint16_t_u_u((safe_add_func_int64_t_s_s((safe_unary_minus_func_uint32_t_u(p_35)), (((((l_2905 , (p_37 > (l_2892 , p_37))) , (safe_lshift_func_int8_t_s_u((p_37 = ((safe_div_func_uint32_t_u_u((safe_mul_func_int16_t_s_s((safe_sub_func_int16_t_s_s(((l_2765 ^= l_2914) | ((g_2797 > ((((safe_mod_func_uint64_t_u_u(l_2679, (safe_lshift_func_uint8_t_u_s((safe_div_func_int8_t_s_s((l_2923 != (void*)0), l_2892)), p_35)))) <= 0L) != (-6L)) != 18446744073709551615UL)) && p_37)), l_2897.f1)), 0UL)), p_37)) < p_37)), 2))) ^ (*g_2632)) ^ (**g_2622)) , p_36))), 0L)); + l_2925 |= l_2896; + } + else + { /* block id: 1332 */ + return p_35; + } + if ((l_2940 = ((l_2892 = (l_2926 = ((*g_1701) = p_36))) != (safe_mul_func_int16_t_s_s(((safe_rshift_func_int16_t_s_s(((g_384 ^= (safe_lshift_func_uint8_t_u_u((safe_add_func_int8_t_s_s(((p_37 , l_2935) == (void*)0), (l_2936 = (l_2924 = g_128[0][2][0])))), 7))) || (0x8B05L < (l_2939 &= p_35))), l_2940)) , (((++(*l_2935)) > p_37) , l_2877)), l_2925))))) + { /* block id: 1344 */ + const int16_t l_2973 = (-1L); + l_2939 = (***g_1175); + l_2940 = l_2940; + l_2679 &= (safe_mul_func_int8_t_s_s((g_209.f3 &= ((safe_lshift_func_int8_t_s_s((!((safe_add_func_uint64_t_u_u(l_2936, ((*l_2935) = (((safe_mul_func_int16_t_s_s((((safe_lshift_func_int16_t_s_s((safe_add_func_int32_t_s_s((l_2875 , (safe_sub_func_int8_t_s_s(p_37, (safe_mod_func_uint8_t_u_u((l_2896 |= (!((safe_unary_minus_func_uint32_t_u((((safe_sub_func_int8_t_s_s((safe_sub_func_uint16_t_u_u((0UL && ((p_35 <= ((l_2964[2][0][4] = &g_1744) == &g_2230)) && ((safe_div_func_uint64_t_u_u(((safe_div_func_uint8_t_u_u(((((safe_div_func_int16_t_s_s((safe_mul_func_uint16_t_u_u(0xA02BL, (((((***g_276) = ((&l_2804 == (*g_276)) >= p_36)) >= 18446744073709551613UL) , p_37) >= l_2925))), p_35)) == p_36) | g_2307) > (**g_2622)), l_2905)) & 248UL), p_36)) || 0xE419L))), (**g_1574))), p_36)) <= (-6L)) > l_2973))) ^ 0xA2D2L))), p_35))))), (*g_1701))), p_36)) <= 0x9B4DL) , p_37), 0x744CL)) >= (-1L)) ^ (*g_1000))))) && 0x21C8L)), 2)) > 0xFECFL)), g_4[3])); + if (l_2729) + break; + } + else + { /* block id: 1354 */ + int16_t l_2974 = 0xDE74L; + if (l_2974) + break; + (*g_267) = &p_35; + g_1679 |= 0xE00E2B68L; + l_2925 ^= (safe_mul_func_int8_t_s_s(1L, (((l_2977 == (g_2978 = (void*)0)) , l_2979) != g_2980))); + } + for (g_2797 = 0; (g_2797 <= 9); g_2797 += 1) + { /* block id: 1363 */ + int32_t l_2982 = 0L; + return l_2982; + } + } + l_2924 ^= (g_4[3] = p_36); + } + else + { /* block id: 1369 */ + uint32_t l_2989[2]; + uint32_t **l_2997 = &g_1701; + uint16_t l_3029 = 0x6DA0L; + int32_t *l_3032[6] = {&g_4[3],&g_4[3],&g_4[3],&g_4[3],&g_4[3],&g_4[3]}; + int i; + for (i = 0; i < 2; i++) + l_2989[i] = 7UL; + for (g_458.f3 = 0; (g_458.f3 == 7); g_458.f3 = safe_add_func_int8_t_s_s(g_458.f3, 1)) + { /* block id: 1372 */ + uint8_t *l_2994 = &l_2905; + const int32_t l_2998[9] = {0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL,0xD7B4CD8BL}; + int32_t l_3005 = 0xAAEA9947L; + int i; + p_35 = 0x8484AAF9L; + p_35 = (safe_rshift_func_int8_t_s_s((p_35 , ((-3L) & (safe_lshift_func_uint16_t_u_u((((!(0xD881L != l_2875)) ^ (l_2925 = (((*g_983) = (l_2989[1] | ((*g_983) == 0x98L))) != (safe_mul_func_int8_t_s_s((((*l_2994) = (0x948A6B78L < ((safe_mod_func_uint8_t_u_u(((***g_276) && 1L), l_2989[1])) >= 0L))) , 0x51L), l_2989[1]))))) & 0x515EFCB8L), 15)))), g_135)); + l_3005 |= (p_35 = (((safe_lshift_func_uint16_t_u_u(((void*)0 == l_2997), l_2998[6])) & ((&g_277[0] == (void*)0) , (safe_rshift_func_uint16_t_u_s((l_2820[0] == ((**l_2997) = (safe_mul_func_int16_t_s_s((safe_add_func_int16_t_s_s(p_36, (l_2875 , (((void*)0 == &g_1744) | l_2989[1])))), p_36)))), 14)))) != l_2729)); + for (l_2765 = 0; (l_2765 != 28); l_2765 = safe_add_func_uint32_t_u_u(l_2765, 1)) + { /* block id: 1383 */ + return p_35; + } + } + l_2679 = (safe_mul_func_uint8_t_u_u(0x51L, (p_37 &= (l_2925 = 0L)))); + if ((safe_rshift_func_int8_t_s_s((&g_1568[0][2] != l_3012[4]), 6))) + { /* block id: 1390 */ + int32_t l_3034 = (-1L); + int32_t l_3038[6] = {(-3L),(-3L),(-3L),(-3L),(-3L),(-3L)}; + int32_t l_3039[2]; + int32_t l_3040 = 1L; + int32_t l_3042 = 0x14408B26L; + int i; + for (i = 0; i < 2; i++) + l_3039[i] = (-1L); + for (g_2193.f3 = 0; (g_2193.f3 >= (-11)); --g_2193.f3) + { /* block id: 1393 */ + const uint8_t l_3028 = 0UL; + int32_t *l_3031 = &g_67[3]; + int32_t l_3033 = 0xC6523790L; + int32_t l_3035[1][8][9]; + int i, j, k; + for (i = 0; i < 1; i++) + { + for (j = 0; j < 8; j++) + { + for (k = 0; k < 9; k++) + l_3035[i][j][k] = 1L; + } + } + (*g_267) = ((safe_add_func_uint16_t_u_u(((safe_unary_minus_func_uint16_t_u((p_37 , (l_2925 != (((*l_3031) = (safe_sub_func_uint8_t_u_u(((safe_mod_func_int64_t_s_s(((*g_127) = (p_35 > ((((p_35 & (safe_mod_func_uint8_t_u_u(((l_2905 ^ ((((safe_mul_func_uint16_t_u_u(0x8184L, ((*l_2876) = (*g_1739)))) && 2L) && ((((safe_mod_func_int64_t_s_s((l_3028 < 0xC09FFC866F9194E5LL), 1UL)) , l_3029) != p_36) ^ p_37)) != p_37)) == g_458.f0), l_2875))) >= (-10L)) < l_3029) & l_3030))), p_36)) == p_36), p_36))) , (*g_1739)))))) < p_35), 0x0B16L)) , (void*)0); + (*g_267) = (l_3032[3] = ((***g_2978) = (void*)0)); + l_2896 |= (l_3033 = (7L && p_37)); + ++l_3043; + } + for (g_206 = 0; (g_206 <= 45); g_206 = safe_add_func_uint64_t_u_u(g_206, 6)) + { /* block id: 1407 */ + return p_35; + } + } + else + { /* block id: 1410 */ + (*g_267) = &l_2679; + } + } + for (g_458.f3 = 0; (g_458.f3 != 1); g_458.f3 = safe_add_func_int64_t_s_s(g_458.f3, 2)) + { /* block id: 1416 */ + return p_36; + } + } + else + { /* block id: 1419 */ + (**l_2800) = (**g_1567); + return p_36; + } + l_2765 = ((0x31F40544L >= (p_35 = ((safe_add_func_int16_t_s_s(((*l_3062) &= p_36), ((g_708 ^= ((((*l_3075) = (0x9F19L | ((l_2679 = ((safe_unary_minus_func_uint16_t_u(p_35)) , (safe_add_func_int64_t_s_s(((safe_mod_func_int32_t_s_s(l_2820[3], ((safe_div_func_uint32_t_u_u(p_35, p_35)) , (~(l_3070[1] & ((safe_rshift_func_int8_t_s_s(((safe_lshift_func_int8_t_s_u((-10L), p_37)) , (-1L)), p_35)) >= 65526UL)))))) == l_2765), p_35)))) | 0xCFL))) , l_2765) | p_37)) | 0UL))) , p_37))) , 1L); + } + else + { /* block id: 1429 */ + int32_t l_3076 = 5L; + int32_t l_3077 = 0x01390D7CL; + int32_t l_3078 = 1L; + int32_t l_3079[10][1][4]; + uint16_t l_3081 = 0xC356L; + uint32_t **l_3084[2]; + union U0 *l_3085 = (void*)0; + int i, j, k; + for (i = 0; i < 10; i++) + { + for (j = 0; j < 1; j++) + { + for (k = 0; k < 4; k++) + l_3079[i][j][k] = 0x2CFC8E74L; + } + } + for (i = 0; i < 2; i++) + l_3084[i] = &g_1701; + l_3081--; + g_457 = (((void*)0 == l_3084[0]) , l_3085); + } + return p_36; +} + + +/* ------------------------------------------ */ +/* + * reads : g_983 g_130 g_384 g_999 g_1000 g_2497 g_1700 g_1701 g_209.f0 g_648 g_258 g_1175 g_20 g_276 g_277 g_127 g_2620 g_2621 g_2622 g_2630 g_1739 g_458.f2 g_206 g_128 g_2648 + * writes: g_384 g_130 g_1000 g_2497 g_254 g_209.f0 g_128 g_408 g_2630 g_2648 + */ +static union U0 func_48(int32_t * p_49, int32_t p_50) +{ /* block id: 1167 */ + int32_t l_2545 = (-1L); + int32_t l_2546 = 0x87F12CDAL; + const int16_t **l_2547[4]; + int16_t *l_2558[1]; + int16_t **l_2559 = &l_2558[0]; + const int16_t *l_2560 = &g_383; + int16_t *l_2561 = &g_384; + int32_t l_2571 = 9L; + uint32_t l_2588 = 18446744073709551615UL; + int32_t l_2634 = 0x6D47EBBBL; + int32_t l_2639 = 0xC7967847L; + int32_t l_2640 = 0L; + int32_t l_2641[7][10] = {{(-5L),(-1L),0xF1BE8DC3L,0x401C4A67L,0x401C4A67L,0xF1BE8DC3L,(-1L),(-5L),(-1L),0xF1BE8DC3L},{0xE0B57CFEL,(-10L),0x401C4A67L,(-10L),0xE0B57CFEL,0xF1BE8DC3L,0xF1BE8DC3L,0xE0B57CFEL,(-10L),0x401C4A67L},{(-5L),(-5L),0x401C4A67L,0xE0B57CFEL,0x010A09B7L,0xE0B57CFEL,0x401C4A67L,(-5L),(-5L),0x401C4A67L},{(-10L),0xE0B57CFEL,0xF1BE8DC3L,0xF1BE8DC3L,0xE0B57CFEL,(-10L),0x401C4A67L,(-10L),0xE0B57CFEL,0xF1BE8DC3L},{(-1L),(-5L),(-1L),0xF1BE8DC3L,0x401C4A67L,0x401C4A67L,0xF1BE8DC3L,(-1L),(-5L),(-1L)},{(-1L),(-10L),(-5L),0xE0B57CFEL,(-5L),(-10L),(-1L),(-1L),(-10L),(-5L)},{(-10L),(-1L),(-1L),(-10L),(-5L),0xE0B57CFEL,(-5L),(-10L),(-1L),(-1L)}}; + int32_t l_2646 = 0xAB5CC4D6L; + union U0 l_2651[8] = {{0L},{0L},{0L},{0L},{0L},{0L},{0L},{0L}}; + int i, j; + for (i = 0; i < 4; i++) + l_2547[i] = &g_1739; + for (i = 0; i < 1; i++) + l_2558[i] = &g_408; + if ((safe_div_func_int16_t_s_s((l_2545 != l_2545), (6L && (((p_50 | l_2546) > (((l_2547[1] == (void*)0) >= ((safe_lshift_func_uint8_t_u_u(p_50, 0)) ^ ((*l_2561) ^= (safe_add_func_uint16_t_u_u((safe_div_func_int8_t_s_s((safe_lshift_func_uint16_t_u_s((safe_add_func_int16_t_s_s((((*l_2559) = l_2558[0]) == l_2560), 0xD0D4L)), l_2545)), (*g_983))), l_2545))))) , l_2546)) , p_50))))) + { /* block id: 1170 */ + const int32_t l_2566 = 0x8C4F6DEDL; + int8_t *l_2569 = &g_458.f3; + int64_t ***l_2570 = &g_277[0]; + union U0 l_2574 = {0x6BL}; + (*p_49) |= 8L; + (*p_49) &= (safe_mod_func_uint16_t_u_u(0x825FL, ((((safe_div_func_uint64_t_u_u(p_50, l_2566)) != ((*g_983)++)) <= (((1L ^ l_2546) ^ ((((l_2571 |= (((((((void*)0 != l_2569) , l_2570) != l_2570) & 0x08L) ^ p_50) | 1UL)) && l_2566) < 0UL) , p_50)) , l_2566)) & p_50))); + (*g_999) = (*g_999); + for (g_2497 = (-22); (g_2497 <= 51); g_2497 = safe_add_func_uint16_t_u_u(g_2497, 6)) + { /* block id: 1178 */ + return l_2574; + } + } + else + { /* block id: 1181 */ + const int16_t *l_2579 = &g_383; + int16_t ****l_2580 = (void*)0; + int16_t ***l_2582[8] = {&l_2559,&g_2230,&g_2230,&l_2559,&g_2230,&g_2230,&l_2559,&g_2230}; + int16_t ****l_2581 = &l_2582[4]; + int32_t l_2587 = 0x3DDB5117L; + int32_t l_2589 = 0x0C8D3A4BL; + union U0 * const l_2613 = &g_2193; + int32_t * const ***l_2623 = &g_2621; + int32_t l_2637 = 0x562CC356L; + int32_t l_2638 = (-2L); + int32_t l_2642 = 0xE1F5DA34L; + int8_t l_2643 = 1L; + int32_t l_2644 = 0x6E195AD1L; + int32_t l_2645 = 0x43E382B8L; + int32_t l_2647[6][7] = {{(-10L),(-10L),0x9007E50DL,(-10L),0x21CE23DEL,0xE2A2E5C5L,(-10L)},{0x4CDA0905L,(-1L),0xAA8B12F5L,(-4L),0xAA8B12F5L,(-1L),0x4CDA0905L},{(-1L),(-10L),0x0750F30FL,0xAA8B12F5L,0x4CDA0905L,(-1L),0xAA8B12F5L},{(-10L),0x21CE23DEL,0xE2A2E5C5L,(-10L),(-10L),0xE2A2E5C5L,0x21CE23DEL},{(-10L),0x8742E80AL,0x0750F30FL,(-4L),0x8742E80AL,0xAA8B12F5L,0x21CE23DEL},{0L,(-10L),0xAA8B12F5L,0L,0x21CE23DEL,0L,0xAA8B12F5L}}; + int i, j; + l_2589 &= (safe_add_func_int32_t_s_s((safe_add_func_int16_t_s_s((((~((**g_1700) = (((*l_2559) = (*l_2559)) == l_2579))) , (void*)0) == ((*l_2581) = (void*)0)), ((safe_mod_func_uint8_t_u_u((((((*l_2561) &= (safe_add_func_uint8_t_u_u(3UL, 250UL))) , ((void*)0 != &g_1744)) | (((p_50 && l_2571) < 5UL) , l_2587)) != l_2588), p_50)) && p_50))), l_2587)); + for (g_384 = 0; (g_384 >= (-3)); g_384 = safe_sub_func_uint64_t_u_u(g_384, 6)) + { /* block id: 1189 */ + uint16_t l_2599[6]; + int32_t * const *l_2605 = (void*)0; + int32_t * const **l_2604 = &l_2605; + union U0 *l_2612 = &g_209; + int32_t ****l_2625 = &g_1175; + int32_t *****l_2624 = &l_2625; + const uint16_t ****l_2633 = &g_2630[4]; + int32_t *l_2635 = &l_2587; + int32_t *l_2636[2][1][9] = {{{&g_75[0],&g_75[0],(void*)0,&g_75[0],&g_75[0],(void*)0,&g_75[0],&g_75[0],(void*)0}},{{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}}}; + int i, j, k; + for (i = 0; i < 6; i++) + l_2599[i] = 0x61ADL; + for (g_209.f0 = 0; (g_209.f0 == (-9)); g_209.f0--) + { /* block id: 1192 */ + int32_t l_2594 = 6L; + int32_t *l_2595 = &g_75[0]; + int32_t *l_2596 = &l_2587; + int32_t *l_2597 = &l_2587; + int32_t *l_2598[6] = {(void*)0,(void*)0,(void*)0,(void*)0,(void*)0,(void*)0}; + int i; + l_2599[3]--; + } + (*p_49) |= (((***g_276) = ((p_50 , ((*g_648) , (safe_rshift_func_uint16_t_u_s((0xE4L && (((*l_2604) = (*g_1175)) != (*g_1175))), (safe_mod_func_int64_t_s_s((safe_sub_func_int32_t_s_s((safe_mod_func_uint16_t_u_u((l_2612 == (l_2588 , l_2613)), p_50)), l_2545)), 0xBC30D72CE9D82791LL)))))) | (*g_1000))) == p_50); + (*p_49) = ((safe_add_func_int64_t_s_s((safe_div_func_uint16_t_u_u((((1UL <= (safe_sub_func_int32_t_s_s(((l_2623 = ((p_50 , 0UL) , g_2620)) != ((*l_2624) = (void*)0)), (*p_49)))) && (((**g_1700) = (l_2571 <= ((l_2634 = (safe_mod_func_int8_t_s_s(((((**l_2559) = (****l_2623)) <= (safe_lshift_func_uint8_t_u_s((((((*l_2633) = g_2630[0]) != &g_642) || (*g_1739)) == 0xE3F1882A87241F9BLL), g_458.f2))) || g_206), (****l_2623)))) == (*g_127)))) , p_50)) , p_50), l_2589)), 0L)) , 0x44DFB60CL); + ++g_2648; + } + } + return l_2651[4]; +} + + +/* ------------------------------------------ */ +/* + * reads : g_67 g_268 g_4 g_999 g_1000 g_133 g_159 g_1175 g_983 g_1701 g_147 g_1574 g_643 g_177 g_1738 g_1739 g_384 g_20 g_78 g_642 g_458.f2 g_1679 + * writes: g_183 g_130 g_254 g_1744 g_458.f2 g_1567 g_177 g_1679 g_1000 + */ +static int32_t * func_51(int8_t p_52, uint16_t p_53, uint16_t p_54, int32_t * p_55, int32_t * p_56) +{ /* block id: 22 */ + uint32_t l_66 = 0UL; + const uint32_t l_1737 = 0x5BD5EC1CL; + int16_t *l_1823 = &g_383; + int8_t l_1838 = 0L; + int32_t **** const l_1867 = &g_1175; + uint32_t ***l_1888 = (void*)0; + int64_t *l_1900[2][9] = {{&g_91,&g_91,(void*)0,&g_91,&g_91,(void*)0,&g_91,&g_91,(void*)0},{&g_91,&g_91,(void*)0,&g_91,&g_91,(void*)0,&g_91,&g_91,(void*)0}}; + union U0 *l_1912 = &g_458; + int32_t l_1970 = 0L; + uint64_t l_2017 = 0x186654FB36088AB8LL; + const int64_t l_2109 = 1L; + uint64_t *** const *l_2119 = &g_1568[4][0]; + int32_t l_2147 = 0xAFE66B6AL; + int32_t l_2148 = 0xB7803ABDL; + int32_t l_2149 = 0xD2562CEEL; + int16_t l_2150 = 0L; + int32_t l_2151[7] = {0x25F1C8C3L,0x25F1C8C3L,(-8L),0x25F1C8C3L,0x25F1C8C3L,(-8L),0x25F1C8C3L}; + uint64_t l_2152 = 0x5E2B98CD90F720CALL; + uint32_t l_2172 = 0x68E686C5L; + union U0 l_2192 = {6L}; + uint16_t ***l_2272 = &g_642; + int64_t l_2294 = 0xE3EA39F0464915B4LL; + int32_t l_2357 = 0x6F9A5C36L; + uint32_t l_2449[10] = {18446744073709551615UL,0xEC1892ABL,0xEC1892ABL,18446744073709551615UL,0xEC1892ABL,0xEC1892ABL,18446744073709551615UL,0xEC1892ABL,0xEC1892ABL,18446744073709551615UL}; + const int64_t l_2470[5] = {0L,0L,0L,0L,0L}; + int16_t l_2485 = 4L; + int i, j; + (**g_1175) = func_57(func_63(l_66, p_55), p_56, p_56, (safe_mod_func_int16_t_s_s((p_53 || (safe_mod_func_int64_t_s_s(((safe_rshift_func_uint8_t_u_s((safe_mod_func_uint16_t_u_u((l_66 , p_54), (l_1737 || 0xECL))), l_66)) | g_147), 0xEDC64461E26EA04ALL))), (**g_1574))), (*g_999)); + return p_55; +} + + +/* ------------------------------------------ */ +/* + * reads : g_1738 g_458.f2 g_1739 g_384 g_999 g_1000 g_20 g_147 g_78 g_983 g_642 g_643 g_1679 g_177 g_135 l_3230 l_8 + * writes: g_1744 g_458.f2 g_130 g_1567 g_177 g_1679 l_8 + */ +static int32_t * func_57(int32_t * p_58, const int32_t * p_59, int32_t * p_60, int32_t p_61, int32_t * p_62) +{ /* block id: 777 */ + const int16_t ***l_1740[6]; + const int16_t **l_1742 = &g_1739; + const int16_t ***l_1741[8] = {&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}; + const int16_t ***l_1743[6][4][7] = {{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,(void*)0},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}},{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,(void*)0},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}},{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,(void*)0,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}},{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}},{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,(void*)0,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742}},{{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742},{&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,&l_1742,(void*)0}}}; + union U0 *l_1746 = &g_209; + int32_t l_1754 = 1L; + int32_t l_1768 = 0x095CDAFAL; + int32_t l_1769 = 0xDB75B53DL; + int32_t l_1770 = 4L; + int32_t l_1771 = 0x9C09D373L; + int32_t l_1772 = 0x10206477L; + int32_t l_1773[7] = {(-1L),(-1L),(-1L),(-1L),(-1L),(-1L),(-1L)}; + uint8_t l_1774 = 0x9DL; + int16_t *l_1792[4] = {&g_408,&g_408,&g_408,&g_408}; + const uint32_t **l_1798 = (void*)0; + const uint32_t ***l_1797 = &l_1798; + int32_t ***l_1799 = &g_999; + int i, j, k; + for (i = 0; i < 6; i++) + l_1740[i] = (void*)0; + g_1744 = g_1738[0][0][1]; + for (g_458.f2 = 1; (g_458.f2 >= 0); g_458.f2 -= 1) + { /* block id: 781 */ + int32_t ***l_1745 = &g_999; + union U0 *l_1747 = (void*)0; + int32_t l_1762 = 1L; + int32_t *l_1763 = &l_1754; + int32_t *l_1764 = (void*)0; + int32_t *l_1765 = &g_135; + int32_t *l_1766 = &l_1762; + int32_t *l_1767[2][8]; + int i, j; + for (i = 0; i < 2; i++) + { + for (j = 0; j < 8; j++) + l_1767[i][j] = &g_135; + } + } + if (((((safe_mod_func_uint16_t_u_u((safe_mod_func_int64_t_s_s((safe_add_func_uint64_t_u_u(l_1769, (((l_1774 & (safe_sub_func_uint16_t_u_u(((((safe_mul_func_uint16_t_u_u((safe_div_func_uint32_t_u_u((((*g_1739) || (l_1772 |= l_1774)) < ((void*)0 != p_62)), p_61)), (safe_add_func_uint16_t_u_u(p_61, ((((safe_add_func_uint16_t_u_u(((p_61 , l_1797) == &l_1798), p_61)) , (void*)0) != l_1799) >= p_61))))) | p_61) , 0xEAL) || 0x64L), p_61))) , (***l_1799)) && (***l_1799)))), (***l_1799))), 0x29C2L)) >= 252UL) , (***l_1799)) || (***l_1799))) + { /* block id: 801 */ + uint64_t ****l_1808 = &g_1568[1][0]; + uint64_t *****l_1809 = &g_1567; + int32_t l_1810 = 0xF7553BC3L; + int32_t *l_1815 = &l_1754; + g_1679 ^= ((*l_1815) = (safe_lshift_func_uint16_t_u_u((((((safe_mod_func_int8_t_s_s(g_147, g_78)) == ((safe_div_func_int8_t_s_s((-1L), (safe_mul_func_int8_t_s_s(((((*g_983) = p_61) , l_1808) != ((*l_1809) = l_1808)), p_61)))) || l_1810)) , ((safe_rshift_func_int8_t_s_s((safe_add_func_uint16_t_u_u(((**g_642) = p_61), l_1810)), p_61)) | 1L)) != g_458.f2) , p_61), (***l_1799)))); + } + else + { /* block id: 807 */ + int64_t l_1816 = 5L; + l_1816 &= ((((***l_1799) <= ((*g_643) < (((-1L) != ((void*)0 == l_1792[2])) & p_61))) >= (p_61 > (***l_1799))) | p_61); + } + return (**l_1799); +} + + +/* ------------------------------------------ */ +/* + * reads : g_67 g_183 g_268 g_4 g_999 g_1000 g_133 g_159 g_1175 g_983 g_1701 l_17 g_20 g_135 g_75 l_6 l_3388 + * writes: g_183 g_130 g_254 l_17 g_135 g_75 l_6 l_3388 + */ +static int32_t * func_63(uint32_t p_64, int32_t * p_65) +{ /* block id: 23 */ + int8_t l_92 = (-1L); + union U0 l_107 = {0xFCL}; + int64_t *l_108 = &g_91; + int32_t l_1362 = (-2L); + int32_t l_1363 = 0x44B08332L; + int32_t l_1364 = 0xC342F325L; + int32_t l_1365 = 5L; + int32_t l_1366 = 1L; + int32_t l_1367 = 0L; + int32_t l_1368 = (-6L); + int32_t l_1369 = 0x025C5BA3L; + int32_t l_1370 = 0xD02642ECL; + int32_t l_1372 = 0L; + int32_t l_1373 = (-4L); + int32_t l_1374 = (-8L); + int32_t l_1375[9]; + int8_t l_1376 = (-5L); + const int32_t *l_1416 = &l_1369; + uint64_t ****l_1428 = (void*)0; + const int32_t ***l_1507 = (void*)0; + uint8_t *l_1555[8] = {&g_206,&g_206,&g_206,&g_206,&g_206,&g_206,&g_206,&g_206}; + uint64_t * const l_1584 = &g_1585; + uint64_t * const *l_1583 = &l_1584; + uint64_t * const **l_1582 = &l_1583; + uint64_t * const ***l_1581[1]; + uint32_t l_1590 = 0xF2612A68L; + uint16_t l_1636 = 0x963DL; + union U0 **l_1671[3][5] = {{&g_457,&g_457,&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457,&g_457,&g_457}}; + union U0 ***l_1718 = &l_1671[2][3]; + int32_t l_1721[9][10][2] = {{{1L,0xAE07A814L},{0L,(-5L)},{4L,0L},{0x8B11D955L,1L},{0x8B11D955L,0L},{4L,(-5L)},{0L,0xAE07A814L},{1L,(-2L)},{1L,(-5L)},{0xCA567AF2L,1L}},{{0x8B11D955L,0x74157914L},{0x2A0A03D6L,0L},{0xCA567AF2L,0x83600AB0L},{0L,(-2L)},{1L,(-2L)},{0L,0x83600AB0L},{0xCA567AF2L,0L},{0x2A0A03D6L,0x74157914L},{0x8B11D955L,1L},{0xCA567AF2L,(-5L)}},{{1L,(-2L)},{1L,0xAE07A814L},{0L,(-5L)},{4L,0L},{0x8B11D955L,1L},{0x8B11D955L,0L},{4L,(-5L)},{0L,0xAE07A814L},{1L,(-2L)},{1L,(-5L)}},{{0xCA567AF2L,1L},{0x8B11D955L,0x74157914L},{0x2A0A03D6L,0L},{0xCA567AF2L,0x83600AB0L},{0L,(-2L)},{1L,(-2L)},{0L,0x83600AB0L},{0xCA567AF2L,0L},{0x2A0A03D6L,0x74157914L},{0x8B11D955L,1L}},{{0xCA567AF2L,(-5L)},{1L,(-2L)},{1L,0xAE07A814L},{0L,(-5L)},{4L,0L},{0x8B11D955L,1L},{0x8B11D955L,0L},{4L,(-5L)},{0L,0xAE07A814L},{1L,(-2L)}},{{1L,(-5L)},{0xCA567AF2L,1L},{0x8B11D955L,0x74157914L},{0x2A0A03D6L,0L},{0xCA567AF2L,0x83600AB0L},{0L,(-2L)},{1L,(-2L)},{0L,0x83600AB0L},{0xCA567AF2L,0L},{0x2A0A03D6L,0x74157914L}},{{0x8B11D955L,1L},{0xCA567AF2L,(-5L)},{1L,(-2L)},{1L,0xAE07A814L},{0L,(-5L)},{4L,0L},{0x8B11D955L,1L},{0x8B11D955L,0L},{4L,(-5L)},{0L,0xAE07A814L}},{{1L,(-2L)},{1L,(-5L)},{0xCA567AF2L,1L},{0x8B11D955L,0x74157914L},{0x2A0A03D6L,1L},{0xD30CC12AL,0xEF7C4AB6L},{1L,1L},{(-8L),1L},{1L,0xEF7C4AB6L},{0xD30CC12AL,1L}},{{0x1648D157L,0L},{1L,0x45440744L},{0xD30CC12AL,0L},{0L,1L},{(-9L),0x4EBF4A0AL},{1L,0L},{(-3L),1L},{1L,1L},{1L,1L},{(-3L),0L}}}; + union U0 **l_1728 = &g_457; + int i, j, k; + for (i = 0; i < 9; i++) + l_1375[i] = 0L; + for (i = 0; i < 1; i++) + l_1581[i] = &l_1582; + for (p_64 = 0; (p_64 <= 6); p_64 += 1) + { /* block id: 26 */ + int32_t *l_74 = &g_75[2]; + uint16_t *l_76 = (void*)0; + uint16_t *l_77[9][7] = {{(void*)0,&g_78,(void*)0,(void*)0,(void*)0,(void*)0,&g_78},{&g_78,&g_78,&g_78,&g_78,&g_78,&g_78,&g_78},{(void*)0,(void*)0,(void*)0,(void*)0,&g_78,(void*)0,(void*)0},{(void*)0,(void*)0,&g_78,&g_78,&g_78,(void*)0,(void*)0},{(void*)0,(void*)0,&g_78,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,&g_78,(void*)0,&g_78,&g_78,(void*)0,&g_78},{(void*)0,&g_78,&g_78,&g_78,&g_78,(void*)0,&g_78},{(void*)0,&g_78,&g_78,(void*)0,&g_78,(void*)0,&g_78},{(void*)0,(void*)0,(void*)0,&g_78,(void*)0,(void*)0,(void*)0}}; + int8_t l_79 = 6L; + int32_t l_80 = (-1L); + int32_t l_81 = (-7L); + int32_t l_82 = 0x52CE760CL; + int32_t l_83 = 0L; + int32_t l_84 = (-1L); + int32_t l_85[9]; + int64_t *l_90[2]; + uint32_t l_446 = 4294967293UL; + int32_t l_1371 = 7L; + uint32_t l_1380 = 4294967295UL; + const uint32_t l_1397[10][9][2] = {{{0x24B8C904L,0x1B2BEC57L},{0UL,4294967295UL},{0x485AA879L,0x47938DEEL},{4294967292UL,0x6EBB7F7CL},{3UL,0xF30D44D8L},{4294967295UL,0UL},{1UL,1UL},{0x6E6627B8L,0UL},{4294967286UL,4294967288UL}},{{0xF30D44D8L,0xCF5DB912L},{0x486E3104L,0x9792D2F9L},{0UL,0xD58A0B2DL},{0xCF5DB912L,4294967292UL},{4294967294UL,0x58CE859BL},{4294967295UL,0xA874F9BCL},{1UL,0xA874F9BCL},{4294967295UL,0x58CE859BL},{4294967294UL,4294967292UL}},{{0xCF5DB912L,0xD58A0B2DL},{0UL,0x9792D2F9L},{0x486E3104L,0xCF5DB912L},{0xF30D44D8L,4294967288UL},{4294967286UL,0UL},{0x6E6627B8L,1UL},{1UL,0UL},{4294967295UL,0xF30D44D8L},{3UL,0x6EBB7F7CL}},{{4294967292UL,0x47938DEEL},{0x485AA879L,4294967295UL},{0UL,0x1B2BEC57L},{0x24B8C904L,4294967286UL},{0xD58A0B2DL,4294967292UL},{0x01BACA47L,0x0EB5F177L},{0x02BDCA84L,0x73AB4C3EL},{0UL,0UL},{0x47938DEEL,1UL}},{{4294967295UL,4294967295UL},{4294967286UL,4294967293UL},{0x9792D2F9L,4294967295UL},{4294967290UL,4294967286UL},{0x99258856L,4294967290UL},{4294967295UL,4294967288UL},{4294967295UL,4294967290UL},{0x99258856L,4294967286UL},{4294967290UL,4294967295UL}},{{0x9792D2F9L,4294967293UL},{4294967286UL,4294967295UL},{4294967295UL,1UL},{0x47938DEEL,4294967294UL},{0x02BDCA84L,0xFE00AE09L},{0xED55B852L,0xF30D44D8L},{4294967295UL,4294967295UL},{4294967286UL,4294967286UL},{0x47938DEEL,4294967290UL}},{{1UL,1UL},{4294967286UL,4294967288UL},{4294967295UL,4294967288UL},{0xF1A18079L,0x9792D2F9L},{0x485AA879L,0xA874F9BCL},{0xD58A0B2DL,0UL},{1UL,1UL},{4294967295UL,0UL},{0x9792D2F9L,0x486E3104L}},{{0UL,3UL},{0xA874F9BCL,4294967286UL},{0x486E3104L,4294967295UL},{0x0EB5F177L,0x0E6844C1L},{4294967295UL,4294967295UL},{0UL,4294967295UL},{4294967295UL,0x0E6844C1L},{0x0EB5F177L,4294967295UL},{0x486E3104L,4294967286UL}},{{0xA874F9BCL,3UL},{0UL,0x486E3104L},{0x9792D2F9L,0UL},{4294967295UL,1UL},{1UL,0UL},{0xD58A0B2DL,0xA874F9BCL},{0x485AA879L,0x9792D2F9L},{0xF1A18079L,4294967288UL},{4294967295UL,4294967288UL}},{{4294967286UL,1UL},{1UL,4294967290UL},{0x47938DEEL,4294967286UL},{4294967286UL,4294967295UL},{4294967295UL,0xF30D44D8L},{0xED55B852L,0xFE00AE09L},{0x02BDCA84L,4294967294UL},{4294967288UL,0xD58A0B2DL},{0x35C33860L,0x35C33860L}}}; + union U0 l_1457 = {-5L}; + union U0 *l_1469 = &g_458; + uint16_t ***l_1483 = &g_642; + int32_t l_1484 = 0x6F092448L; + int32_t l_1485 = 0xA2A7E2F9L; + int16_t l_1614 = 0L; + int8_t l_1680[8] = {0L,0L,0L,0L,0L,0L,0L,0L}; + uint32_t l_1699 = 4294967295UL; + int64_t l_1706[2]; + int i, j, k; + for (i = 0; i < 9; i++) + l_85[i] = 7L; + for (i = 0; i < 2; i++) + l_90[i] = &g_91; + for (i = 0; i < 2; i++) + l_1706[i] = 0xC7929D515FFB46B7LL; + if (g_67[p_64]) + break; + } + for (g_183 = 0; (g_183 >= 2); ++g_183) + { /* block id: 767 */ + if ((*l_1416)) + break; + if ((*g_268)) + continue; + return (*g_999); + } + (*p_65) = ((safe_lshift_func_int8_t_s_u(g_133, 7)) && ((*g_1701) = (safe_rshift_func_uint8_t_u_s(((*g_983) = (safe_rshift_func_uint8_t_u_u(((+(((((safe_lshift_func_uint8_t_u_u((((*l_1718) = &g_457) == ((!(safe_mul_func_uint8_t_u_u(((l_1721[7][2][1] & (safe_mod_func_uint8_t_u_u(((*l_1416) > (safe_sub_func_int32_t_s_s((*p_65), (((&g_1700 != ((+(safe_mul_func_int16_t_s_s(g_159, (p_64 == (&p_65 == (*g_1175)))))) , &g_1700)) == (-1L)) > p_64)))), 0x79L))) && 5L), p_64))) , l_1728)), 5)) > p_64) | (-10L)) & (*l_1416)) <= (*l_1416))) , (*l_1416)), 3))), p_64)))); + return (*g_999); +} + + +/* ------------------------------------------ */ +/* + * reads : g_209.f0 g_128 g_258 g_159 g_457 g_458 g_4 g_253 g_267 g_458.f1 g_458.f3 g_643 g_177 g_78 g_642 g_91 g_268 g_67 g_383 g_127 g_983 g_130 g_1175 g_999 g_1000 g_146 g_135 g_75 g_274 g_20 g_409 g_183 g_277 g_629 g_578 g_204 g_133 g_1326 g_276 g_206 g_1086 + * writes: g_209.f0 g_206 g_253 g_209.f2 g_268 g_458.f1 g_458.f3 g_75 g_708 g_146 g_91 g_578 g_130 g_135 g_1000 g_159 g_204 g_1326 g_1334 g_127 g_177 + */ +static int32_t func_68(int32_t p_69, uint32_t p_70, int8_t p_71, int16_t p_72, int64_t p_73) +{ /* block id: 208 */ + int8_t *l_447 = (void*)0; + int8_t *l_448 = &g_209.f0; + union U0 l_449 = {0xE9L}; + uint8_t *l_454 = &g_206; + int16_t *l_461 = &l_449.f2; + int32_t l_462[8][2] = {{9L,9L},{9L,9L},{9L,9L},{9L,9L},{9L,9L},{9L,9L},{9L,9L},{9L,9L}}; + uint16_t l_472[9][9][3] = {{{0xC221L,0xC874L,65535UL},{65535UL,1UL,0xBF13L},{0x3BF1L,3UL,0xBD1BL},{0xDEE1L,65529UL,0xBD1BL},{7UL,0xBF03L,0xBF13L},{65535UL,0xE8C6L,65535UL},{1UL,65535UL,1UL},{65535UL,0x7567L,65529UL},{0xBD1BL,0x53ECL,65535UL}},{{0x8B2AL,65535UL,0xADA0L},{1UL,65535UL,0x75E0L},{0x8B2AL,7UL,65535UL},{0xBD1BL,0x5DA5L,0x9346L},{65535UL,0xC221L,0xC874L},{1UL,0x9346L,65527UL},{65535UL,0xDEE1L,0x53ECL},{7UL,0xBF13L,5UL},{0xDEE1L,0xBF13L,65535UL}},{{0x3BF1L,0xDEE1L,0xBF03L},{65535UL,0x9346L,0xFD83L},{0xC221L,0xC221L,0x3BF1L},{0xBF03L,0x5DA5L,0xC221L},{65535UL,7UL,0xE8C6L},{0xADA0L,65535UL,0x7567L},{0xC874L,65535UL,0xE8C6L},{65535UL,0x53ECL,0xC221L},{65535UL,0x7567L,0x3BF1L}},{{65527UL,65535UL,65535UL},{0x8B2AL,65535UL,0x505FL},{6UL,0x505FL,0x7567L},{7UL,0x7C61L,0x046CL},{7UL,1UL,0x8B2AL},{6UL,0xADA0L,0xC221L},{0x8B2AL,0x53ECL,0x53ECL},{65535UL,0xFD83L,8UL},{0xE8C6L,65535UL,65535UL}},{{65535UL,5UL,65529UL},{0x53ECL,65535UL,65535UL},{65535UL,5UL,0xBF03L},{0x5DA5L,65535UL,0x7C61L},{0x505FL,0xFD83L,65535UL},{0x3BF1L,0x53ECL,0xE8C6L},{0xBD1BL,0xADA0L,3UL},{65531UL,1UL,65535UL},{65527UL,0x7C61L,65535UL}},{{1UL,0x505FL,3UL},{0xFD83L,65535UL,0xE8C6L},{65535UL,0xBF03L,65535UL},{0x7567L,0x75E0L,0x7C61L},{65535UL,0x8B2AL,0xBF03L},{0xBF13L,0x5DA5L,65535UL},{0xADA0L,0x9346L,65529UL},{0xBF13L,1UL,65535UL},{65535UL,0x1FBEL,8UL}},{{0x7567L,0x3BF1L,0x53ECL},{65535UL,8UL,0xC221L},{0xFD83L,65527UL,0x8B2AL},{1UL,3UL,0x046CL},{65527UL,3UL,0x7567L},{65531UL,65527UL,0x505FL},{0xBD1BL,8UL,65535UL},{0x3BF1L,0x3BF1L,65531UL},{0x505FL,0x1FBEL,0x3BF1L}},{{0x5DA5L,1UL,65535UL},{65535UL,0x9346L,0x75E0L},{0x53ECL,0x5DA5L,65535UL},{65535UL,0x8B2AL,0x3BF1L},{0xE8C6L,0x75E0L,65531UL},{65535UL,0xBF03L,65535UL},{0x8B2AL,65535UL,0x505FL},{6UL,0x505FL,0x7567L},{7UL,0x7C61L,0x046CL}},{{7UL,1UL,0x8B2AL},{6UL,0xADA0L,0xC221L},{0x8B2AL,0x53ECL,0x53ECL},{65535UL,0xFD83L,8UL},{0xE8C6L,65535UL,65535UL},{65535UL,5UL,65529UL},{0x53ECL,65535UL,65535UL},{65535UL,5UL,0xBF03L},{0x5DA5L,65535UL,0x7C61L}}}; + uint32_t *l_557 = &g_258[3]; + const uint32_t *l_559[5][9] = {{&g_258[3],&g_258[3],&g_258[3],(void*)0,&g_147,&g_258[3],(void*)0,&g_258[6],&g_258[3]},{&g_258[3],&g_258[0],&g_258[3],&g_258[5],&g_258[0],&g_258[3],(void*)0,&g_258[3],&g_258[0]},{&g_258[3],&g_258[3],&g_258[3],&g_258[3],&g_258[6],&g_258[0],&g_258[3],&g_258[3],&g_258[3]},{&g_258[3],&g_258[6],&g_147,&g_147,&g_258[3],&g_258[3],&g_258[6],(void*)0,(void*)0},{&g_258[0],&g_258[3],(void*)0,&g_258[3],(void*)0,&g_258[3],&g_258[0],&g_258[0],&g_258[3]}}; + uint64_t * const l_607 = &g_133; + uint8_t l_714 = 0x10L; + int16_t l_733 = 1L; + int32_t l_911[4]; + int8_t l_947 = 8L; + int32_t l_1001 = 0x805C6618L; + uint64_t l_1046[1]; + int16_t l_1059 = 7L; + int64_t * const *l_1083 = &g_127; + int64_t * const **l_1082 = &l_1083; + int64_t *l_1150 = &g_746; + union U0 **l_1163[2][6] = {{&g_457,&g_457,&g_457,&g_457,&g_457,&g_457},{&g_457,&g_457,&g_457,&g_457,&g_457,&g_457}}; + union U0 l_1198 = {-2L}; + int32_t ** const l_1203 = &g_1000; + uint32_t l_1235[9][5] = {{2UL,4294967290UL,0x2053E66BL,0xCE24B125L,0x2053E66BL},{0x466813F7L,0x466813F7L,1UL,0xCE24B125L,0x51EA397BL},{4294967290UL,2UL,0x96D42934L,4294967290UL,0x466813F7L},{4294967294UL,7UL,4294967289UL,0xFC0413B2L,7UL},{0x466813F7L,2UL,0xE2CADD70L,1UL,1UL},{0x96D42934L,0x466813F7L,0x96D42934L,4294967289UL,1UL},{0xCE24B125L,4294967290UL,7UL,4294967294UL,7UL},{2UL,4294967294UL,4294967295UL,0xCE24B125L,0x466813F7L},{0x2053E66BL,0x466813F7L,7UL,7UL,0x51EA397BL}}; + int8_t l_1237 = 0xB2L; + uint32_t *l_1292 = (void*)0; + uint32_t * const *l_1291 = &l_1292; + uint32_t l_1324[6][2] = {{18446744073709551611UL,18446744073709551611UL},{18446744073709551611UL,18446744073709551611UL},{18446744073709551611UL,18446744073709551611UL},{18446744073709551611UL,18446744073709551611UL},{18446744073709551611UL,18446744073709551611UL},{18446744073709551611UL,18446744073709551611UL}}; + int i, j, k; + for (i = 0; i < 4; i++) + l_911[i] = 1L; + for (i = 0; i < 1; i++) + l_1046[i] = 0x02E0C98E42D89AB0LL; + if (((((*l_448) ^= (-6L)) < ((!(((l_449 , ((((p_71 = (safe_rshift_func_uint8_t_u_s(((*l_454) = (safe_add_func_uint16_t_u_u(g_128[0][3][2], g_258[4]))), (((g_159 , l_449) , (safe_mod_func_uint16_t_u_u((g_457 == &g_458), ((*l_461) = (safe_lshift_func_int16_t_s_u((!(((l_449.f3 <= 0x2FL) , (*g_457)) , 1L)), 1)))))) && (-1L))))) || l_449.f3) < 6UL) > 1L)) & g_4[3]) | l_462[0][0])) != l_462[0][0])) <= (-8L))) + { /* block id: 213 */ + uint16_t l_486 = 7UL; + uint64_t l_503 = 0xC3FC38227B8D68D9LL; + int32_t l_526[9] = {1L,0x3C3F3ACAL,0x3C3F3ACAL,1L,0x3C3F3ACAL,0x3C3F3ACAL,1L,0x3C3F3ACAL,0x3C3F3ACAL}; + int i; + for (g_253 = 1; (g_253 >= 0); g_253 -= 1) + { /* block id: 216 */ + int32_t *l_463 = (void*)0; + int32_t *l_464 = (void*)0; + int32_t *l_465 = &g_75[0]; + int32_t *l_466 = &l_462[0][0]; + int32_t *l_467 = &g_75[2]; + int32_t *l_468 = &g_135; + int32_t *l_469 = (void*)0; + int32_t *l_470[10][3] = {{&l_462[0][0],&l_462[0][0],&l_462[0][0]},{&g_75[0],&l_462[2][0],(void*)0},{(void*)0,&g_75[2],&l_462[2][0]},{(void*)0,&g_4[3],&l_462[0][0]},{&g_75[0],&g_20,&g_75[0]},{&l_462[0][0],&g_4[3],(void*)0},{&l_462[2][0],&g_75[2],(void*)0},{(void*)0,&l_462[2][0],&g_75[0]},{&l_462[0][0],&l_462[0][0],&l_462[0][0]},{(void*)0,&l_462[0][0],&l_462[2][0]}}; + int16_t l_530 = (-7L); + int32_t l_535 = (-5L); + int i, j; + l_472[4][3][2]--; + for (g_209.f2 = 0; (g_209.f2 <= 1); g_209.f2 += 1) + { /* block id: 220 */ + uint32_t *l_477 = &g_258[3]; + int64_t l_480[1][10][6] = {{{(-6L),(-2L),(-6L),0x3F7C68C20FEF92FCLL,(-6L),(-2L)},{(-1L),(-6L),(-6L),(-4L),0x539AEC78E0FAAD68LL,0x3F7C68C20FEF92FCLL},{0x61375C96C76C8D7DLL,(-4L),(-2L),(-2L),(-4L),0x61375C96C76C8D7DLL},{(-2L),(-4L),0x61375C96C76C8D7DLL,0x0DB3BFBB48C1FAC4LL,0x539AEC78E0FAAD68LL,(-6L)},{(-6L),(-6L),(-1L),(-6L),(-6L),(-4L)},{(-6L),(-2L),(-6L),0x0DB3BFBB48C1FAC4LL,1L,1L},{(-2L),0x539AEC78E0FAAD68LL,0x539AEC78E0FAAD68LL,(-2L),(-1L),1L},{0x61375C96C76C8D7DLL,1L,(-6L),(-4L),0x0DB3BFBB48C1FAC4LL,(-4L)},{(-1L),(-4L),(-1L),0x3F7C68C20FEF92FCLL,0x0DB3BFBB48C1FAC4LL,(-6L)},{(-6L),1L,0x61375C96C76C8D7DLL,(-1L),(-1L),0x61375C96C76C8D7DLL}}}; + int32_t l_484 = 0x84166A81L; + int32_t *l_504[7] = {&g_75[2],&g_20,&g_20,&g_75[2],&g_20,&g_20,&g_75[2]}; + uint8_t *l_511 = (void*)0; + int32_t l_519 = 0x56952E57L; + int8_t l_524 = 0x02L; + int i, j, k; + (*g_267) = (void*)0; + } + } + } + else + { /* block id: 252 */ + int32_t l_545[4] = {0xA15CE5BAL,0xA15CE5BAL,0xA15CE5BAL,0xA15CE5BAL}; + union U0 l_606 = {0xEDL}; + int32_t *l_653 = &g_146; + int64_t l_713 = 8L; + int32_t **l_722 = &l_653; + int32_t ***l_721 = &l_722; + int i; + for (g_458.f1 = 20; (g_458.f1 == (-7)); g_458.f1 = safe_sub_func_int16_t_s_s(g_458.f1, 2)) + { /* block id: 255 */ + int32_t l_615[1]; + uint8_t l_620 = 0UL; + uint32_t **l_649 = &l_557; + int32_t *l_707 = &g_75[2]; + int32_t *l_709 = &g_146; + int32_t *l_710 = &l_545[0]; + int32_t *l_711 = &l_545[1]; + int32_t *l_712[6][1][3] = {{{&l_615[0],&g_135,&g_135}},{{&g_135,&l_462[0][0],(void*)0}},{{&l_615[0],&l_462[0][0],&l_615[0]}},{{&l_615[0],&g_135,(void*)0}},{{&l_615[0],&l_615[0],&g_135}},{{&l_615[0],&g_135,&g_135}}}; + int64_t l_726 = (-4L); + int64_t l_789 = 0xDB7474E2223FA5BCLL; + int i, j, k; + for (i = 0; i < 1; i++) + l_615[i] = (-4L); + } + } + for (g_458.f3 = 0; (g_458.f3 != 12); g_458.f3 = safe_add_func_int64_t_s_s(g_458.f3, 1)) + { /* block id: 371 */ + int32_t *l_827 = &g_75[2]; + union U0 l_834 = {0x56L}; + int8_t *l_839 = &g_708; + uint32_t l_840 = 9UL; + uint16_t **l_892[9] = {&g_643,&g_643,&g_643,&g_643,&g_643,&g_643,&g_643,&g_643,&g_643}; + int64_t **l_902 = &g_127; + int16_t l_903 = 0x0ED8L; + uint16_t l_904 = 0x826EL; + int32_t l_906 = 0L; + int32_t l_907 = (-2L); + uint32_t l_912 = 3UL; + int32_t l_917 = (-5L); + int32_t l_925 = 0xC1557A2EL; + int32_t l_926[1][4][9] = {{{0xD18E9BE1L,0xD18E9BE1L,0x900B22F3L,0x7F48F33DL,0x693ED394L,(-2L),0xD18E9BE1L,0x693ED394L,0x8757C95BL},{0xF7B5BB4CL,1L,2L,0x693ED394L,0x693ED394L,2L,1L,0xF7B5BB4CL,0x900B22F3L},{0xF7B5BB4CL,0x693ED394L,0x900B22F3L,0xF7B5BB4CL,1L,2L,0x693ED394L,0x693ED394L,2L},{0xD18E9BE1L,0x693ED394L,0x8757C95BL,0x693ED394L,0xD18E9BE1L,(-2L),0x693ED394L,0x7F48F33DL,0x900B22F3L}}}; + int64_t l_930 = 9L; + uint32_t l_935 = 1UL; + union U0 **l_971 = &g_457; + int i, j, k; + g_146 = (p_73 , (((safe_add_func_int64_t_s_s((safe_rshift_func_uint8_t_u_s(((safe_rshift_func_uint16_t_u_u(((safe_mod_func_uint32_t_u_u(1UL, ((*l_827) = l_449.f2))) || ((((*l_839) = ((safe_rshift_func_int8_t_s_u((!((*l_448) = ((((safe_mul_func_uint8_t_u_u(((safe_div_func_int8_t_s_s((l_834 , (safe_add_func_uint32_t_u_u((safe_sub_func_uint16_t_u_u((l_462[1][0] | l_462[4][1]), 0xE028L)), (-1L)))), (p_73 && p_71))) <= (*g_643)), g_78)) != p_72) && (**g_642)) && 255UL))), l_714)) >= 0xCFL)) || g_128[0][3][1]) != p_69)), 12)) >= p_71), 2)), p_73)) < l_840) , p_69)); + for (g_91 = 0; (g_91 <= (-13)); g_91 = safe_sub_func_uint32_t_u_u(g_91, 8)) + { /* block id: 378 */ + uint64_t **l_859 = &g_333[6][0]; + uint64_t ***l_858[5] = {&l_859,&l_859,&l_859,&l_859,&l_859}; + int32_t l_875 = 2L; + int32_t l_886 = (-1L); + int32_t l_908 = 1L; + int32_t l_909 = 0xA85A818CL; + int32_t l_910 = 0x9B9DDF32L; + int32_t *l_923 = &l_909; + int8_t l_927 = (-1L); + int32_t l_929[5] = {0x2105F6E1L,0x2105F6E1L,0x2105F6E1L,0x2105F6E1L,0x2105F6E1L}; + int64_t *l_948 = &g_128[0][3][1]; + union U0 **l_974 = &g_457; + uint32_t l_1073 = 8UL; + uint32_t l_1095 = 8UL; + uint64_t l_1103 = 18446744073709551615UL; + int i; + } + } + for (g_91 = 0; (g_91 <= 2); g_91 += 1) + { /* block id: 489 */ + union U0 l_1106[2][1] = {{{0xE5L}},{{0xE5L}}}; + int64_t * const l_1107[1] = {(void*)0}; + int32_t *l_1110[4][9][2] = {{{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135}},{{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135}},{{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135}},{{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135},{&g_135,&g_4[3]},{&g_135,&g_135},{&g_4[3],&g_135}}}; + uint64_t **l_1119[6][3][8] = {{{&g_333[0][0],(void*)0,&g_333[1][1],&g_333[2][0],(void*)0,&g_333[5][0],&g_333[3][1],&g_333[2][1]},{&g_333[1][1],&g_333[3][0],&g_333[1][1],&g_333[7][1],&g_333[7][1],&g_333[7][1],&g_333[7][1],&g_333[7][1]},{(void*)0,&g_333[0][0],&g_333[7][1],&g_333[7][1],&g_333[4][0],(void*)0,&g_333[7][1],&g_333[4][0]}},{{&g_333[7][1],&g_333[7][1],&g_333[5][0],(void*)0,&g_333[3][1],(void*)0,&g_333[3][0],&g_333[3][1]},{(void*)0,&g_333[7][1],(void*)0,(void*)0,&g_333[7][1],&g_333[7][1],(void*)0,&g_333[7][1]},{&g_333[4][0],&g_333[5][0],&g_333[7][1],(void*)0,(void*)0,(void*)0,(void*)0,&g_333[7][1]}},{{&g_333[7][1],&g_333[7][1],&g_333[3][0],&g_333[5][0],&g_333[3][1],&g_333[7][1],(void*)0,&g_333[1][1]},{&g_333[5][0],&g_333[0][0],&g_333[7][1],&g_333[4][0],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[1][1]},{&g_333[0][0],&g_333[7][1],&g_333[3][0],&g_333[5][0],&g_333[7][1],&g_333[7][1],&g_333[7][1],&g_333[7][1]}},{{&g_333[7][1],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[2][0],&g_333[0][0],&g_333[3][0],(void*)0},{&g_333[7][1],&g_333[7][1],&g_333[4][0],&g_333[5][0],&g_333[3][0],(void*)0,&g_333[7][1],&g_333[3][0]},{&g_333[1][1],&g_333[2][1],(void*)0,(void*)0,&g_333[3][0],&g_333[5][0],(void*)0,&g_333[4][1]}},{{&g_333[7][1],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[7][1],&g_333[7][1],&g_333[7][1],&g_333[7][1]},{&g_333[7][1],&g_333[7][1],&g_333[5][0],&g_333[1][0],(void*)0,&g_333[7][1],&g_333[4][1],&g_333[7][1]},{&g_333[7][1],(void*)0,&g_333[7][1],&g_333[0][0],(void*)0,&g_333[7][1],(void*)0,(void*)0}},{{&g_333[7][1],&g_333[1][1],&g_333[5][1],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[7][1],&g_333[4][0]},{&g_333[7][1],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[3][0],(void*)0,&g_333[7][1],(void*)0},{&g_333[1][1],&g_333[7][1],&g_333[7][1],(void*)0,&g_333[3][0],&g_333[7][1],&g_333[1][1],&g_333[7][1]}}}; + uint64_t ***l_1118 = &l_1119[1][0][4]; + int32_t l_1125 = (-7L); + uint16_t ***l_1129 = &g_642; + int16_t l_1159 = 0x354CL; + int64_t l_1215 = 6L; + uint64_t l_1239[5]; + const uint16_t l_1271 = 65533UL; + int16_t l_1272 = 0x065AL; + int64_t *l_1331 = &g_778; + int i, j, k; + for (i = 0; i < 5; i++) + l_1239[i] = 0xE1DC6819E6A1D5B8LL; + for (g_578 = 0; (g_578 <= 0); g_578 += 1) + { /* block id: 492 */ + int i; + for (l_449.f3 = 0; (l_449.f3 <= 0); l_449.f3 += 1) + { /* block id: 495 */ + (*g_267) = (*g_267); + } + return g_67[(g_91 + 3)]; + } + (*g_267) = func_99((0xD0B072D2L || l_1046[0]), g_383, l_1106[1][0], l_1107[0], &p_73); + p_69 = (safe_rshift_func_int8_t_s_u(l_1106[1][0].f3, 2)); + for (g_130 = 0; (g_130 <= 0); g_130 += 1) + { /* block id: 504 */ + uint64_t l_1111[6][3] = {{0xB02A9711D519CD71LL,0UL,0UL},{0xB02A9711D519CD71LL,0UL,0UL},{0xB02A9711D519CD71LL,0UL,0UL},{0xB02A9711D519CD71LL,0UL,0UL},{0xB02A9711D519CD71LL,0UL,0UL},{0xB02A9711D519CD71LL,0UL,0UL}}; + int32_t l_1124 = 0x5544602EL; + int32_t l_1126 = 0x0C53A3EEL; + const union U0 l_1137 = {1L}; + int64_t ***l_1226 = &g_277[0]; + uint32_t l_1325 = 0xB38004C2L; + int i, j; + ++l_1111[1][0]; + for (g_135 = 0; (g_135 <= 1); g_135 += 1) + { /* block id: 508 */ + uint32_t l_1122 = 18446744073709551615UL; + int32_t l_1123 = 1L; + uint16_t ***l_1131[10] = {&g_642,&g_642,&g_642,&g_642,&g_642,&g_642,&g_642,&g_642,&g_642,&g_642}; + uint16_t ** const *l_1132[2][3] = {{(void*)0,(void*)0,(void*)0},{&g_642,&g_642,&g_642}}; + uint32_t l_1154 = 0x0F03542AL; + int32_t l_1158 = 0x24F7942FL; + int64_t ***l_1170[1][1][7]; + union U0 l_1204 = {0x3DL}; + const uint16_t l_1227 = 65535UL; + int i, j, k; + for (i = 0; i < 1; i++) + { + for (j = 0; j < 1; j++) + { + for (k = 0; k < 7; k++) + l_1170[i][j][k] = (void*)0; + } + } + l_1126 ^= (p_70 == ((l_1125 ^= (((safe_mul_func_int8_t_s_s(((p_69 , 6L) & (l_1124 = ((safe_sub_func_int8_t_s_s((l_1118 != (void*)0), ((safe_add_func_uint8_t_u_u((6L != (((l_1122 &= (p_73 &= (*g_127))) | 18446744073709551615UL) ^ g_209.f0)), 9UL)) == l_1123))) | 1UL))), (*g_983))) , l_1124) | p_70)) < (*g_268))); + } + if (p_73) + { /* block id: 588 */ + int32_t * const l_1274 = &g_75[2]; + int32_t **l_1275 = &g_1000; + (*l_1275) = l_1274; + (**g_1175) = l_1110[0][1][1]; + for (g_159 = 0; (g_159 <= 0); g_159 += 1) + { /* block id: 593 */ + uint8_t l_1276[6][9] = {{0xECL,5UL,0xECL,5UL,0xECL,5UL,0xECL,5UL,0xECL},{250UL,0xC6L,0xC6L,250UL,250UL,0xC6L,0xC6L,250UL,250UL},{0UL,5UL,0UL,5UL,0UL,5UL,0UL,5UL,0UL},{250UL,250UL,0xC6L,0xC6L,250UL,250UL,0xC6L,0xC6L,250UL},{0xECL,5UL,0xECL,5UL,0xECL,5UL,0xECL,5UL,0xECL},{250UL,0xC6L,0xC6L,250UL,250UL,0xC6L,0xC6L,250UL,250UL}}; + int i, j; + if ((*g_1000)) + break; + (*l_1274) ^= (p_69 = ((**l_1275) && p_72)); + (*g_267) = func_99(((1UL > 65535UL) , l_1276[5][6]), g_274, l_1137, (*l_1083), (p_69 , &p_73)); + } + } + else + { /* block id: 599 */ + uint32_t *l_1283 = &g_204; + int32_t l_1284 = 9L; + (*g_267) = func_99(((safe_lshift_func_int8_t_s_s((g_458.f1 = (**l_1203)), 1)) || g_159), (((safe_sub_func_int64_t_s_s((safe_div_func_uint32_t_u_u(((*l_1283) = l_1137.f1), g_177)), (((((*l_448) = l_1284) , ((((safe_div_func_uint32_t_u_u((p_71 && 0xB48FL), (safe_lshift_func_int16_t_s_u(((*l_461) = (((((+((safe_div_func_uint16_t_u_u((((g_409[0][1] , l_1126) < 1UL) , 0x1B93L), p_72)) , (-1L))) ^ l_1126) , (void*)0) != (void*)0) == 0x15F9L)), 13)))) && l_1137.f0) != p_71) != l_1111[1][0])) , p_69) == g_183))) || (**g_642)) & p_72), l_1137, &l_1215, (**l_1226)); + } + for (g_159 = 0; (g_159 <= 2); g_159 += 1) + { /* block id: 608 */ + int32_t l_1322 = 1L; + int32_t l_1327 = (-7L); + if (((*g_457) , p_73)) + { /* block id: 609 */ + uint32_t * const **l_1293 = &l_1291; + int32_t l_1318 = 0x0E5EFF82L; + uint16_t l_1328 = 0xE7BCL; + (*l_1293) = l_1291; + for (l_1198.f3 = 0; (l_1198.f3 <= 0); l_1198.f3 += 1) + { /* block id: 613 */ + uint32_t **l_1321 = &l_557; + int32_t l_1323 = 9L; + int i; + g_1326 &= (safe_mod_func_uint32_t_u_u((safe_lshift_func_uint8_t_u_s(((safe_mul_func_uint8_t_u_u((safe_mul_func_int16_t_s_s(((*l_461) = (((safe_mod_func_int64_t_s_s((safe_add_func_int16_t_s_s(0x728EL, (((**l_1203) >= ((safe_lshift_func_int16_t_s_s(g_629, 12)) , (safe_mod_func_int16_t_s_s((p_72 <= (safe_sub_func_int8_t_s_s((safe_lshift_func_int8_t_s_s((safe_mul_func_int8_t_s_s(g_75[2], (g_578 | (3UL ^ (safe_mod_func_uint32_t_u_u((+((l_1318 < (l_1126 = ((safe_sub_func_int8_t_s_s((((*l_1321) = l_557) != (void*)0), p_71)) | g_128[0][3][1]))) & p_73)), g_146)))))), p_69)), l_1322))), 0x0C7AL)))) || p_69))), l_1322)) && 1L) , g_204)), g_133)), l_1323)) , l_1324[0][1]), 2)), l_1325)); + } + ++l_1328; + } + else + { /* block id: 620 */ + int64_t **l_1333 = &l_1150; + int64_t ***l_1332[7][3]; + const int64_t *l_1336 = &g_1337; + const int64_t **l_1335 = &l_1336; + int i, j; + for (i = 0; i < 7; i++) + { + for (j = 0; j < 3; j++) + l_1332[i][j] = &l_1333; + } + g_146 &= ((l_1331 = &l_1215) != ((*l_1335) = (((*g_276) == (g_1334 = &l_1150)) , (void*)0))); + } + } + } + } + p_69 = ((safe_mul_func_int8_t_s_s(((!p_70) , (p_71 = (safe_sub_func_uint16_t_u_u((safe_add_func_int32_t_s_s(((((**g_276) = (void*)0) != (((safe_lshift_func_int16_t_s_u(((*l_461) = (safe_add_func_uint8_t_u_u(((*g_983)--), (safe_sub_func_uint8_t_u_u(((*g_457) , (g_458.f1 & ((*l_454)--))), (0xE33CL & (**l_1203))))))), 1)) && ((*g_643) = 0xE1FCL)) , (void*)0)) ^ ((safe_rshift_func_uint8_t_u_u(((**l_1203) , 0xAAL), p_73)) && 9UL)), 0x35057CD6L)), (**l_1203))))), g_1086)) , p_73); + return p_71; +} + + +/* ------------------------------------------ */ +/* + * reads : g_20 g_91 g_4 g_128 g_130 g_132 g_147 g_159 g_133 g_135 g_177 g_67 g_183 g_146 g_206 g_209 g_127 g_204 g_209.f1 g_209.f0 g_209.f3 g_254 g_258 g_267 g_276 g_268 g_274 l_17 + * writes: g_127 g_130 g_132 g_133 g_147 g_159 g_177 g_183 g_135 g_146 g_204 g_206 g_254 g_258 g_267 g_268 + */ +static union U0 func_97(const int32_t * p_98) +{ /* block id: 35 */ + union U0 l_118[10][7][1] = {{{{0xC9L}},{{0L}},{{0xFDL}},{{-10L}},{{-1L}},{{-1L}},{{-10L}}},{{{0xFDL}},{{0L}},{{0xC9L}},{{0L}},{{0L}},{{0xEEL}},{{-1L}}},{{{0xEEL}},{{0L}},{{0L}},{{0xC9L}},{{0L}},{{0xFDL}},{{-10L}}},{{{-1L}},{{-1L}},{{-10L}},{{0xFDL}},{{0L}},{{0xC9L}},{{0L}}},{{{0L}},{{0xEEL}},{{-1L}},{{0xEEL}},{{0L}},{{0L}},{{0xC9L}}},{{{0L}},{{0xFDL}},{{-10L}},{{-1L}},{{-1L}},{{-10L}},{{0xFDL}}},{{{0L}},{{0xC9L}},{{0L}},{{0L}},{{0xEEL}},{{-1L}},{{0xEEL}}},{{{0L}},{{0L}},{{0xC9L}},{{0L}},{{0xFDL}},{{-10L}},{{-1L}}},{{{-1L}},{{-10L}},{{0xFDL}},{{0L}},{{0xC9L}},{{0L}},{{0L}}},{{{0xEEL}},{{-1L}},{{0xEEL}},{{0L}},{{0L}},{{0xC9L}},{{0L}}}}; + int32_t *l_121 = &g_20; + int32_t *l_123 = (void*)0; + int32_t **l_122 = &l_123; + int64_t *l_124 = (void*)0; + int64_t *l_126 = &g_91; + int64_t **l_125[2]; + uint8_t *l_129 = &g_130; + uint64_t *l_131 = &g_132; + int32_t l_142 = 0x28050347L; + int32_t l_158[8][5] = {{0x58A6C8DEL,0xA13AD1F1L,(-1L),0xA13AD1F1L,0x58A6C8DEL},{0L,0xBB4E128BL,0xBB4E128BL,0L,0x815FF81FL},{(-2L),0xA13AD1F1L,(-2L),(-1L),(-2L)},{0L,0L,0x7C678778L,0xBB4E128BL,0x815FF81FL},{0x58A6C8DEL,(-1L),(-1L),(-1L),0x58A6C8DEL},{0x815FF81FL,0xBB4E128BL,0x7C678778L,0L,0L},{(-2L),(-1L),(-2L),0xA13AD1F1L,(-2L)},{0x815FF81FL,0L,0xBB4E128BL,0xBB4E128BL,0L}}; + int64_t l_162 = (-1L); + uint32_t *l_230 = (void*)0; + int64_t l_330[6][10] = {{3L,0x18470653C73B861FLL,0xCCF0B8B5409C4288LL,0L,0L,0xCCF0B8B5409C4288LL,0x18470653C73B861FLL,3L,0x18470653C73B861FLL,0xCCF0B8B5409C4288LL},{0xA5B1CB5A17DCD406LL,0x7E45F49753809639LL,0L,0x7E45F49753809639LL,0xA5B1CB5A17DCD406LL,0xCCF0B8B5409C4288LL,0xCCF0B8B5409C4288LL,0xA5B1CB5A17DCD406LL,0x7E45F49753809639LL,0L},{3L,3L,0L,0xA5B1CB5A17DCD406LL,0xE47515C299F0A386LL,0xA5B1CB5A17DCD406LL,0L,3L,3L,0L},{0x7E45F49753809639LL,0xA5B1CB5A17DCD406LL,0xCCF0B8B5409C4288LL,0xCCF0B8B5409C4288LL,0xA5B1CB5A17DCD406LL,0x7E45F49753809639LL,0L,0x7E45F49753809639LL,0xA5B1CB5A17DCD406LL,0xCCF0B8B5409C4288LL},{0x18470653C73B861FLL,3L,0x18470653C73B861FLL,0xCCF0B8B5409C4288LL,0L,0L,0xCCF0B8B5409C4288LL,0x18470653C73B861FLL,3L,0x18470653C73B861FLL},{0x18470653C73B861FLL,0x7E45F49753809639LL,3L,0xA5B1CB5A17DCD406LL,3L,0x7E45F49753809639LL,0x18470653C73B861FLL,0x18470653C73B861FLL,0x7E45F49753809639LL,3L}}; + int32_t l_338 = 4L; + uint64_t l_353 = 1UL; + const uint64_t l_440 = 0x55F846FE51E95657LL; + uint16_t *l_444[2]; + uint16_t **l_443 = &l_444[0]; + int i, j, k; + for (i = 0; i < 2; i++) + l_125[i] = &l_126; + for (i = 0; i < 2; i++) + l_444[i] = (void*)0; + if ((safe_div_func_int32_t_s_s(g_20, (safe_lshift_func_int8_t_s_s((safe_unary_minus_func_uint64_t_u((g_91 < (g_133 = (g_91 != ((*l_131) &= (((*l_129) |= (l_118[4][5][0] , (g_4[3] == ((((safe_rshift_func_uint8_t_u_u((((!(l_121 != ((*l_122) = (void*)0))) , l_124) == (g_127 = &g_91)), 0)) , (*l_121)) & g_128[1][2][0]) <= 0x94F4A132L)))) , (*l_121)))))))), 7))))) + { /* block id: 41 */ + int32_t *l_134 = &g_135; + int32_t *l_136 = (void*)0; + int32_t l_137 = 0x8EC8C7DFL; + int32_t *l_138 = &g_135; + int32_t *l_139 = (void*)0; + int32_t *l_140 = &g_135; + int32_t *l_141[2][10][5] = {{{&g_135,(void*)0,&g_135,&g_135,(void*)0},{(void*)0,&g_4[4],&g_4[0],(void*)0,&g_20},{(void*)0,&g_4[3],&g_4[1],&g_4[0],(void*)0},{(void*)0,(void*)0,(void*)0,(void*)0,&g_135},{&l_137,(void*)0,(void*)0,&g_20,(void*)0},{(void*)0,&g_20,&g_135,(void*)0,&g_135},{&g_4[0],&g_4[0],(void*)0,&g_20,(void*)0},{(void*)0,&g_4[4],&g_135,&g_4[0],(void*)0},{&g_135,(void*)0,&g_20,(void*)0,&g_135},{&l_137,&g_4[4],&g_20,&g_4[3],(void*)0}},{{&g_20,&g_4[0],(void*)0,(void*)0,(void*)0},{&g_4[3],&g_20,&g_4[3],&g_4[4],(void*)0},{&g_4[1],(void*)0,&g_4[0],&g_4[3],&g_135},{(void*)0,(void*)0,(void*)0,(void*)0,(void*)0},{(void*)0,(void*)0,&g_4[0],&g_135,(void*)0},{&g_20,&g_20,&g_4[3],&g_135,&g_135},{&g_135,(void*)0,(void*)0,&g_135,(void*)0},{&g_20,(void*)0,&g_20,&l_137,&g_135},{(void*)0,&l_137,&g_20,&g_4[0],&g_20},{(void*)0,(void*)0,&g_135,&l_137,&g_20}}}; + uint8_t l_143 = 0UL; + int i, j, k; + ++l_143; + g_147--; + } + else + { /* block id: 44 */ + int32_t *l_150 = &l_142; + int32_t *l_151 = &l_142; + int32_t *l_152 = (void*)0; + int32_t *l_153 = &l_142; + int32_t *l_154 = &l_142; + int32_t *l_155 = &g_146; + int32_t *l_156 = &g_146; + int32_t *l_157[2]; + int16_t l_222[5] = {(-1L),(-1L),(-1L),(-1L),(-1L)}; + uint16_t *l_275 = &g_177; + int64_t *l_282 = &l_162; + int32_t **l_287 = &l_154; + union U0 l_299[3] = {{0L},{0L},{0L}}; + int32_t l_306 = 0xE7992D64L; + uint8_t l_346 = 0x8BL; + uint8_t l_378 = 0UL; + uint16_t ***l_445 = &l_443; + int i; + for (i = 0; i < 2; i++) + l_157[i] = &g_135; + (*l_150) = 0xCCA6638CL; + g_159--; + for (g_133 = 0; (g_133 <= 0); g_133 += 1) + { /* block id: 49 */ + uint16_t *l_176 = &g_177; + uint8_t *l_182 = &g_183; + int32_t l_202 = 0xFD7715F6L; + int32_t l_225 = 0xCDD8E95DL; + int32_t **l_265 = (void*)0; + uint64_t *l_278[2]; + uint32_t *l_319 = &g_159; + union U0 l_352 = {0xE1L}; + int64_t ***l_406 = &g_277[0]; + int i; + for (i = 0; i < 2; i++) + l_278[i] = &g_132; + if (l_162) + break; + if ((safe_mul_func_uint16_t_u_u(g_132, (safe_lshift_func_int8_t_s_u(((!(safe_lshift_func_uint16_t_u_u((safe_mod_func_uint32_t_u_u(g_91, ((*l_153) = (safe_lshift_func_int8_t_s_u((safe_div_func_int16_t_s_s((g_135 != (((((safe_unary_minus_func_int64_t_s(0L)) <= g_4[3]) | ((*l_176)--)) , &g_132) != (void*)0)), ((((*l_182) = (g_130++)) || g_128[0][0][1]) ^ 0UL))), 1))))), 9))) == g_67[5]), g_159))))) + { /* block id: 55 */ + int32_t *l_184[2][4][9] = {{{(void*)0,&g_135,&g_146,&g_146,&g_135,(void*)0,&g_135,&g_146,&g_146},{&g_135,&g_135,(void*)0,(void*)0,(void*)0,&g_135,&g_135,(void*)0,(void*)0},{(void*)0,&g_135,(void*)0,(void*)0,(void*)0,(void*)0,&g_135,(void*)0,(void*)0},{&g_4[3],(void*)0,(void*)0,&g_4[3],&l_142,&g_4[3],(void*)0,(void*)0,&g_4[3]}},{{&g_4[2],(void*)0,&g_146,(void*)0,&g_4[2],&g_4[2],(void*)0,&g_146,(void*)0},{(void*)0,&l_142,(void*)0,(void*)0,&l_142,(void*)0,&l_142,(void*)0,(void*)0},{&g_4[2],&g_4[2],(void*)0,&g_146,(void*)0,&g_4[2],&g_4[2],(void*)0,&g_146},{&g_4[3],&l_142,&g_4[3],(void*)0,(void*)0,&g_4[3],&l_142,&g_4[3],(void*)0}}}; + int32_t *l_185 = &l_158[5][4]; + int32_t l_226 = 0x35E0E7B4L; + int8_t l_227 = (-7L); + int8_t l_229 = 0x9BL; + int i, j, k; + l_185 = (l_184[1][2][2] = ((*l_122) = (void*)0)); + for (g_135 = 0; (g_135 >= 0); g_135 -= 1) + { /* block id: 61 */ + int16_t l_205 = 0x495EL; + for (l_142 = 0; (l_142 <= 0); l_142 += 1) + { /* block id: 64 */ + uint32_t *l_199 = &g_159; + int32_t l_203 = 1L; + g_204 = (safe_sub_func_uint8_t_u_u((safe_sub_func_uint16_t_u_u((safe_lshift_func_uint8_t_u_s((!0xEBL), ((safe_mod_func_int32_t_s_s((*p_98), ((*l_121) & (safe_rshift_func_uint16_t_u_u((safe_unary_minus_func_int64_t_s((0x15133C6BL <= g_183))), ((safe_add_func_uint64_t_u_u(9UL, 0xE941047791FE6ADBLL)) | ((--(*l_199)) & ((*l_156) |= ((~l_202) || (((*l_131) = (g_130 , l_203)) | 0x206A442AE9B445DALL)))))))))) < g_67[3]))), g_128[0][0][0])), 0x5CL)); + if (l_205) + break; + g_206--; + } + return g_209; + } + if (g_67[1]) + { /* block id: 74 */ + uint32_t *l_228 = &g_159; + int32_t l_238 = 0x66868886L; + int32_t l_257[8] = {(-6L),(-6L),(-6L),(-6L),(-6L),(-6L),(-6L),(-6L)}; + const uint16_t *l_273 = &g_274; + int i; + if ((((((safe_add_func_uint32_t_u_u(((void*)0 != p_98), ((((safe_mul_func_uint16_t_u_u((((((safe_lshift_func_int8_t_s_s((safe_lshift_func_uint8_t_u_u((*l_121), 4)), (0UL & (g_4[0] , (((((*l_129) = (safe_mod_func_int64_t_s_s((l_222[3] = (*g_127)), g_204))) ^ l_202) <= ((((*l_228) = ((((safe_rshift_func_uint8_t_u_s((l_225 = ((-10L) || 4L)), 1)) & l_226) == l_227) | 1L)) && 0x4375D102L) | (*g_127))) <= g_209.f1))))) ^ g_209.f0) == 0x0DDE07FD64A67530LL) && 0L) , l_229), 0xA2EDL)) | (*g_127)) != 18446744073709551615UL) >= g_133))) || g_146) , g_209.f3) >= l_202) ^ g_91)) + { /* block id: 79 */ + int32_t **l_231 = (void*)0; + int32_t **l_232 = (void*)0; + int32_t **l_233 = (void*)0; + int32_t **l_234 = &l_152; + (*l_154) = (0x1EL >= 0L); + l_202 |= (((l_230 = l_155) != l_121) <= 0x0F1CL); + (*l_234) = ((*l_122) = (void*)0); + } + else + { /* block id: 85 */ + uint32_t l_235 = 4294967295UL; + l_235--; + } + if (((*l_155) = (l_202 < g_4[3]))) + { /* block id: 89 */ + const int16_t l_245 = 0x1D43L; + uint64_t *l_248 = (void*)0; + int32_t l_249 = 0x4F5E980EL; + int32_t l_250 = (-1L); + int32_t l_251 = 0x2859D2BFL; + int32_t l_252 = 1L; + (*l_150) &= ((((*l_176) = 0xA8DEL) | l_238) >= ((*l_182) |= (safe_lshift_func_uint8_t_u_u((g_4[3] != g_146), 6)))); + (*l_155) = (safe_lshift_func_int8_t_s_s(((safe_mod_func_int8_t_s_s(((l_245 ^ ((-1L) < (1UL <= ((((safe_div_func_uint32_t_u_u((((!((void*)0 != &g_132)) > ((&g_133 == (g_209.f1 , l_248)) >= (0x9357L || l_245))) <= (-3L)), 1L)) && g_209.f1) <= g_209.f0) <= 0xACL)))) <= (*g_127)), (-3L))) != 0UL), 3)); + ++g_254; + } + else + { /* block id: 95 */ + int32_t ***l_266 = &l_265; + const int32_t ***l_269 = &g_267; + const uint16_t *l_270 = &g_177; + const uint16_t **l_271 = (void*)0; + const uint16_t **l_272 = &l_270; + union U0 l_279[6][7] = {{{-7L},{1L},{1L},{1L},{1L},{-7L},{1L}},{{-3L},{-7L},{-7L},{-3L},{1L},{-3L},{-7L}},{{-10L},{-10L},{-7L},{1L},{-7L},{-10L},{-10L}},{{-10L},{-3L},{1L},{-3L},{-7L},{-7L},{-3L}},{{1L},{-10L},{1L},{-3L},{-3L},{1L},{-10L}},{{-3L},{-10L},{1L},{1L},{-10L},{-3L},{-10L}}}; + union U0 *l_280[2]; + int64_t * const l_281 = (void*)0; + int i, j; + for (i = 0; i < 2; i++) + l_280[i] = (void*)0; + --g_258[3]; + (*l_156) = ((p_98 == p_98) != ((safe_mod_func_uint8_t_u_u((((l_238 ^ (safe_lshift_func_int16_t_s_u(((((*l_266) = l_265) != ((*l_269) = g_267)) , (l_257[5] > ((l_273 = ((*l_272) = l_270)) == l_275))), ((((!(g_209.f1 && 4294967295UL)) , 18446744073709551615UL) , 0xDDL) <= l_257[5])))) , &l_125[1]) != g_276), l_257[5])) >= l_238)); + (**l_269) = func_99(((*l_176) = 0xD72BL), (~(&g_132 != ((+(***l_269)) , l_278[0]))), (l_118[1][1][0] = l_279[4][4]), l_281, l_282); + } + if ((*g_268)) + break; + return g_209; + } + else + { /* block id: 108 */ + uint32_t l_283 = 0x9C6F2927L; + uint32_t *l_286 = &l_283; + l_283 = 0L; + (*l_156) |= (safe_sub_func_uint32_t_u_u((g_147 || ((((*l_286) = g_91) , (65526UL <= (((l_287 != ((+l_225) , &l_151)) || (safe_lshift_func_uint16_t_u_s(0x0559L, 15))) >= (((1L == ((((*l_129) = ((-2L) > g_4[3])) > g_177) , g_20)) , g_147) == l_283)))) <= 8L)), g_20)); + } + } + else + { /* block id: 114 */ + uint32_t *l_292 = &g_254; + int8_t *l_297 = &g_209.f3; + int8_t *l_298[3]; + int i; + for (i = 0; i < 3; i++) + l_298[i] = (void*)0; + (*l_153) = (**l_287); + g_135 ^= (safe_div_func_int16_t_s_s((((((((**g_267) >= ((*l_292) = ((void*)0 != (*g_267)))) > ((*l_282) = (safe_mod_func_uint32_t_u_u(0xB1D3D90BL, (safe_mul_func_int8_t_s_s(((+(g_130 , (*l_150))) <= ((*l_156) = g_209.f1)), (*l_121))))))) >= (((((~((g_183 || (-1L)) || g_274)) & 0x12DC9772L) ^ g_67[0]) == 3L) , (*l_121))) != 0xEB08L) == (*l_121)) , (*l_121)), (*l_121))); + (*l_122) = ((*l_287) = (*l_287)); + for (g_132 = 0; (g_132 <= 1); g_132 += 1) + { /* block id: 124 */ + return l_299[2]; + } + } + (*g_267) = p_98; + for (g_132 = 0; (g_132 <= 0); g_132 += 1) + { /* block id: 131 */ + const uint8_t l_328 = 253UL; + int8_t *l_329 = &g_209.f1; + int32_t l_345 = 0x37E602FBL; + int8_t l_379 = 0x45L; + int32_t l_381 = (-1L); + int64_t *** const l_405 = (void*)0; + } + } + (*l_445) = l_443; + } + return l_118[6][0][0]; +} + + +/* ------------------------------------------ */ +/* + * reads : + * writes: + */ +static const int32_t * func_99(uint16_t p_100, int16_t p_101, union U0 p_102, int64_t * const p_103, int64_t * p_104) +{ /* block id: 32 */ + int64_t * const l_111 = &g_91; + int64_t * const *l_110 = &l_111; + int64_t * const **l_109 = &l_110; + const int32_t *l_112[3][1][6]; + int i, j, k; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 1; j++) + { + for (k = 0; k < 6; k++) + l_112[i][j][k] = &g_4[3]; + } + } + (*l_109) = &p_103; + return l_112[2][0][0]; +} + + + + +/* ---------------------------------------- */ +int main (int argc, char* argv[]) +{ + int i, j, k; + int print_hash_value = 0; + if (argc == 2 && strcmp(argv[1], "1") == 0) print_hash_value = 1; + platform_main_begin(); + crc32_gentab(); + func_1(); + for (i = 0; i < 5; i++) + { + transparent_crc(g_4[i], "g_4[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_20, "g_20", print_hash_value); + for (i = 0; i < 7; i++) + { + transparent_crc(g_67[i], "g_67[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + for (i = 0; i < 3; i++) + { + transparent_crc(g_75[i], "g_75[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_78, "g_78", print_hash_value); + transparent_crc(g_91, "g_91", print_hash_value); + for (i = 0; i < 2; i++) + { + for (j = 0; j < 4; j++) + { + for (k = 0; k < 3; k++) + { + transparent_crc(g_128[i][j][k], "g_128[i][j][k]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d][%d]\n", i, j, k); + + } + } + } + transparent_crc(g_130, "g_130", print_hash_value); + transparent_crc(g_132, "g_132", print_hash_value); + transparent_crc(g_133, "g_133", print_hash_value); + transparent_crc(g_135, "g_135", print_hash_value); + transparent_crc(g_146, "g_146", print_hash_value); + transparent_crc(g_147, "g_147", print_hash_value); + transparent_crc(g_159, "g_159", print_hash_value); + transparent_crc(g_177, "g_177", print_hash_value); + transparent_crc(g_183, "g_183", print_hash_value); + transparent_crc(g_204, "g_204", print_hash_value); + transparent_crc(g_206, "g_206", print_hash_value); + transparent_crc(g_209.f0, "g_209.f0", print_hash_value); + transparent_crc(g_209.f1, "g_209.f1", print_hash_value); + transparent_crc(g_209.f3, "g_209.f3", print_hash_value); + transparent_crc(g_253, "g_253", print_hash_value); + transparent_crc(g_254, "g_254", print_hash_value); + for (i = 0; i < 8; i++) + { + transparent_crc(g_258[i], "g_258[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_274, "g_274", print_hash_value); + transparent_crc(g_380, "g_380", print_hash_value); + transparent_crc(g_383, "g_383", print_hash_value); + transparent_crc(g_384, "g_384", print_hash_value); + transparent_crc(g_408, "g_408", print_hash_value); + for (i = 0; i < 1; i++) + { + for (j = 0; j < 4; j++) + { + transparent_crc(g_409[i][j], "g_409[i][j]", print_hash_value); + if (print_hash_value) printf("index = [%d][%d]\n", i, j); + + } + } + transparent_crc(g_458.f0, "g_458.f0", print_hash_value); + transparent_crc(g_458.f1, "g_458.f1", print_hash_value); + transparent_crc(g_458.f3, "g_458.f3", print_hash_value); + transparent_crc(g_471, "g_471", print_hash_value); + transparent_crc(g_578, "g_578", print_hash_value); + transparent_crc(g_629, "g_629", print_hash_value); + transparent_crc(g_708, "g_708", print_hash_value); + transparent_crc(g_746, "g_746", print_hash_value); + transparent_crc(g_778, "g_778", print_hash_value); + transparent_crc(g_888, "g_888", print_hash_value); + transparent_crc(g_1086, "g_1086", print_hash_value); + transparent_crc(g_1326, "g_1326", print_hash_value); + transparent_crc(g_1337, "g_1337", print_hash_value); + transparent_crc(g_1413, "g_1413", print_hash_value); + transparent_crc(g_1585, "g_1585", print_hash_value); + transparent_crc(g_1622, "g_1622", print_hash_value); + transparent_crc(g_1679, "g_1679", print_hash_value); + transparent_crc(g_1860, "g_1860", print_hash_value); + transparent_crc(g_1962, "g_1962", print_hash_value); + for (i = 0; i < 10; i++) + { + transparent_crc(g_2033[i], "g_2033[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_2193.f0, "g_2193.f0", print_hash_value); + transparent_crc(g_2193.f1, "g_2193.f1", print_hash_value); + transparent_crc(g_2193.f3, "g_2193.f3", print_hash_value); + transparent_crc(g_2307, "g_2307", print_hash_value); + transparent_crc(g_2497, "g_2497", print_hash_value); + transparent_crc(g_2508, "g_2508", print_hash_value); + transparent_crc(g_2648, "g_2648", print_hash_value); + transparent_crc(g_2767, "g_2767", print_hash_value); + transparent_crc(g_2797, "g_2797", print_hash_value); + transparent_crc(g_2866, "g_2866", print_hash_value); + transparent_crc(g_2895, "g_2895", print_hash_value); + for (i = 0; i < 4; i++) + { + transparent_crc(g_3176[i], "g_3176[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_3254, "g_3254", print_hash_value); + transparent_crc(g_3261, "g_3261", print_hash_value); + for (i = 0; i < 7; i++) + { + transparent_crc(g_3322[i], "g_3322[i]", print_hash_value); + if (print_hash_value) printf("index = [%d]\n", i); + + } + transparent_crc(g_3340, "g_3340", print_hash_value); + transparent_crc(g_3407, "g_3407", print_hash_value); + transparent_crc(g_3485, "g_3485", print_hash_value); + transparent_crc(g_3515, "g_3515", print_hash_value); + transparent_crc(g_3578, "g_3578", print_hash_value); + transparent_crc(g_3815, "g_3815", print_hash_value); + transparent_crc(g_3847, "g_3847", print_hash_value); + transparent_crc(g_3879, "g_3879", print_hash_value); + transparent_crc(g_3880, "g_3880", print_hash_value); + platform_main_end(crc32_context ^ 0xFFFFFFFFUL, print_hash_value); + return 0; +} + +/************************ statistics ************************* +XXX max struct depth: 0 +breakdown: + depth: 0, occurrence: 1041 +XXX total union variables: 31 + +XXX non-zero bitfields defined in structs: 0 +XXX zero bitfields defined in structs: 0 +XXX const bitfields defined in structs: 0 +XXX volatile bitfields defined in structs: 0 +XXX structs with bitfields in the program: 0 +breakdown: +XXX full-bitfields structs in the program: 0 +breakdown: +XXX times a bitfields struct's address is taken: 0 +XXX times a bitfields struct on LHS: 0 +XXX times a bitfields struct on RHS: 0 +XXX times a single bitfield on LHS: 0 +XXX times a single bitfield on RHS: 0 + +XXX max expression depth: 47 +breakdown: + depth: 1, occurrence: 335 + depth: 2, occurrence: 80 + depth: 3, occurrence: 8 + depth: 4, occurrence: 4 + depth: 5, occurrence: 5 + depth: 6, occurrence: 2 + depth: 7, occurrence: 4 + depth: 8, occurrence: 3 + depth: 9, occurrence: 4 + depth: 10, occurrence: 2 + depth: 15, occurrence: 3 + depth: 16, occurrence: 4 + depth: 17, occurrence: 2 + depth: 18, occurrence: 5 + depth: 19, occurrence: 8 + depth: 20, occurrence: 8 + depth: 21, occurrence: 3 + depth: 22, occurrence: 7 + depth: 23, occurrence: 2 + depth: 24, occurrence: 2 + depth: 25, occurrence: 4 + depth: 26, occurrence: 2 + depth: 27, occurrence: 7 + depth: 28, occurrence: 2 + depth: 29, occurrence: 3 + depth: 30, occurrence: 3 + depth: 31, occurrence: 1 + depth: 32, occurrence: 1 + depth: 34, occurrence: 2 + depth: 36, occurrence: 1 + depth: 39, occurrence: 1 + depth: 41, occurrence: 1 + depth: 44, occurrence: 1 + depth: 47, occurrence: 1 + +XXX total number of pointers: 777 + +XXX times a variable address is taken: 1700 +XXX times a pointer is dereferenced on RHS: 704 +breakdown: + depth: 1, occurrence: 460 + depth: 2, occurrence: 141 + depth: 3, occurrence: 54 + depth: 4, occurrence: 38 + depth: 5, occurrence: 9 + depth: 6, occurrence: 2 +XXX times a pointer is dereferenced on LHS: 578 +breakdown: + depth: 1, occurrence: 460 + depth: 2, occurrence: 71 + depth: 3, occurrence: 35 + depth: 4, occurrence: 10 + depth: 5, occurrence: 1 + depth: 6, occurrence: 1 +XXX times a pointer is compared with null: 83 +XXX times a pointer is compared with address of another variable: 24 +XXX times a pointer is compared with another pointer: 23 +XXX times a pointer is qualified to be dereferenced: 13137 + +XXX max dereference level: 6 +breakdown: + level: 0, occurrence: 0 + level: 1, occurrence: 3348 + level: 2, occurrence: 779 + level: 3, occurrence: 469 + level: 4, occurrence: 276 + level: 5, occurrence: 33 + level: 6, occurrence: 10 +XXX number of pointers point to pointers: 359 +XXX number of pointers point to scalars: 399 +XXX number of pointers point to structs: 0 +XXX percent of pointers has null in alias set: 28.4 +XXX average alias set size: 1.47 + +XXX times a non-volatile is read: 4088 +XXX times a non-volatile is write: 1844 +XXX times a volatile is read: 0 +XXX times read thru a pointer: 0 +XXX times a volatile is write: 0 +XXX times written thru a pointer: 0 +XXX times a volatile is available for access: 0 +XXX percentage of non-volatile access: 100 + +XXX forward jumps: 2 +XXX backward jumps: 8 + +XXX stmts: 344 +XXX max block depth: 5 +breakdown: + depth: 0, occurrence: 29 + depth: 1, occurrence: 40 + depth: 2, occurrence: 37 + depth: 3, occurrence: 58 + depth: 4, occurrence: 74 + depth: 5, occurrence: 106 + +XXX percentage a fresh-made variable is used: 15.7 +XXX percentage an existing variable is used: 84.3 +********************* end of statistics **********************/ + diff --git a/tests/fuzz/21.c.txt b/tests/fuzz/21.c.txt new file mode 100644 index 00000000..135eae10 --- /dev/null +++ b/tests/fuzz/21.c.txt @@ -0,0 +1 @@ +checksum = BE13AE15 diff --git a/tests/test_browser.py b/tests/test_browser.py index c06f11ac..b85c6e1c 100644 --- a/tests/test_browser.py +++ b/tests/test_browser.py @@ -1300,7 +1300,7 @@ keydown(100);keyup(100); // trigger the end time.sleep(2) def test_glgears(self): - self.btest('hello_world_gles.c', reference='gears.png', reference_slack=1, + self.btest('hello_world_gles.c', reference='gears.png', reference_slack=2, args=['-DHAVE_BUILTIN_SINCOS'], outfile='something.html', message='You should see animating gears.') @@ -1322,7 +1322,7 @@ keydown(100);keyup(100); // trigger the end self.btest('full_es2_sdlproc.c', '1', args=['-s', 'GL_TESTING=1', '-DHAVE_BUILTIN_SINCOS', '-s', 'FULL_ES2=1']) def test_glgears_deriv(self): - self.btest('hello_world_gles_deriv.c', reference='gears.png', reference_slack=1, + self.btest('hello_world_gles_deriv.c', reference='gears.png', reference_slack=2, args=['-DHAVE_BUILTIN_SINCOS'], outfile='something.html', message='You should see animating gears.') with open('something.html') as f: diff --git a/tests/test_core.py b/tests/test_core.py index 97462cf9..04271192 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3905,6 +3905,8 @@ Pass: 0.000012 0.000012''') self.do_run_from_file(src, output) def test_sscanf_hex(self): + if Settings.USE_TYPED_ARRAYS != 2: return self.skip('requires ta2') + test_path = path_from_root('tests', 'core', 'test_sscanf_hex') src, output = (test_path + s for s in ('.in', '.out')) @@ -4252,6 +4254,18 @@ def process(filename): src = open(path_from_root('tests', 'fs', 'test_nodefs_rw.c'), 'r').read() self.do_run(src, 'success', force_c=True, js_engines=[NODE_JS]) + def test_fs_trackingdelegate(self): + src = path_from_root('tests', 'fs', 'test_trackingdelegate.c') + out = path_from_root('tests', 'fs', 'test_trackingdelegate.out') + self.do_run_from_file(src, out) + + def test_fs_writeFile(self): + if self.emcc_args is None: return self.skip('requires emcc') + self.emcc_args += ['-s', 'DISABLE_EXCEPTION_CATCHING=1'] # see issue 2334 + src = path_from_root('tests', 'fs', 'test_writeFile.cc') + out = path_from_root('tests', 'fs', 'test_writeFile.out') + self.do_run_from_file(src, out) + def test_unistd_access(self): self.clear() if not self.is_emscripten_abi(): return self.skip('asmjs-unknown-emscripten needed for inline js') @@ -5271,7 +5285,7 @@ def process(filename): #if os.path.basename(name) != '4.c': continue if 'newfail' in name: continue if os.environ.get('EMCC_FAST_COMPILER') == '0' and os.path.basename(name) in [ - '18.cpp', '15.c' + '18.cpp', '15.c', '21.c' ]: continue # works only in fastcomp if x == 'lto' and self.run_name == 'default' and os.path.basename(name) in [ '19.c' @@ -5635,7 +5649,6 @@ def process(filename): def test_embind(self): if self.emcc_args is None: return self.skip('requires emcc') - if os.environ.get('EMCC_FAST_COMPILER') != '0': return self.skip('todo in fastcomp') Building.COMPILER_TEST_OPTS += ['--bind'] src = r''' @@ -5658,7 +5671,7 @@ def process(filename): def test_embind_2(self): if self.emcc_args is None: return self.skip('requires emcc') - if os.environ.get('EMCC_FAST_COMPILER') != '0': return self.skip('todo in fastcomp') + if self.run_name == 'slow2asm': return self.skip('embind/asm.js requires fastcomp') Building.COMPILER_TEST_OPTS += ['--bind', '--post-js', 'post.js'] open('post.js', 'w').write(''' Module.print('lerp ' + Module.lerp(1, 2, 0.66) + '.'); @@ -5971,6 +5984,22 @@ def process(filename): ''' self.do_run(src, '|hello|43|world|41|', post_build=post) + def test_webidl(self): + if self.emcc_args is None: return self.skip('requires emcc') + + output = Popen([PYTHON, path_from_root('tools', 'webidl_binder.py'), + path_from_root('tests', 'webidl', 'test.idl'), + 'glue']).communicate()[0] + assert os.path.exists('glue.cpp') + assert os.path.exists('glue.js') + + self.emcc_args += ['--post-js', 'glue.js', + '--post-js', path_from_root('tests', 'webidl', 'post.js')] + shutil.copyfile(path_from_root('tests', 'webidl', 'test.h'), self.in_dir('test.h')) + shutil.copyfile(path_from_root('tests', 'webidl', 'test.cpp'), self.in_dir('test.cpp')) + src = open('test.cpp').read() + self.do_run(src, open(path_from_root('tests', 'webidl', 'output.txt')).read()) + def test_typeinfo(self): if os.environ.get('EMCC_FAST_COMPILER') != '0': return self.skip('fastcomp does not support RUNTIME_TYPE_INFO') diff --git a/tests/test_other.py b/tests/test_other.py index cdea493a..137a83b1 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -1879,25 +1879,20 @@ This pointer might make sense in another type signature: i: 0 assert 'If you see this - the world is all right!' in output def test_embind(self): - def nonfc(): - if os.environ.get('EMCC_FAST_COMPILER') != '0': return self.skip('todo in fastcomp') - for args, fail in [ - ([], True), # without --bind, we fail - (['--bind'], False), - (['--bind', '-O1'], False), - (['--bind', '-O2'], False), - (['--bind', '-O1', '-s', 'ASM_JS=0'], False), - (['--bind', '-O2', '-s', 'ASM_JS=0'], False) - ]: - print args, fail - self.clear() - try_delete(self.in_dir('a.out.js')) - Popen([PYTHON, EMCC, path_from_root('tests', 'embind', 'embind_test.cpp'), '--post-js', path_from_root('tests', 'embind', 'underscore-1.4.2.js'), '--post-js', path_from_root('tests', 'embind', 'imvu_test_adapter.js'), '--post-js', path_from_root('tests', 'embind', 'embind.test.js')] + args, stderr=PIPE if fail else None).communicate() - assert os.path.exists(self.in_dir('a.out.js')) == (not fail) - if not fail: - output = run_js(self.in_dir('a.out.js'), stdout=PIPE, stderr=PIPE, full_output=True) - assert "FAIL" not in output, output - nonfastcomp(nonfc) + for args, fail in [ + ([], True), # without --bind, we fail + (['--bind'], False), + (['--bind', '-O1'], False), + (['--bind', '-O2'], False), + ]: + print args, fail + self.clear() + try_delete(self.in_dir('a.out.js')) + Popen([PYTHON, EMCC, path_from_root('tests', 'embind', 'embind_test.cpp'), '--post-js', path_from_root('tests', 'embind', 'underscore-1.4.2.js'), '--post-js', path_from_root('tests', 'embind', 'imvu_test_adapter.js'), '--post-js', path_from_root('tests', 'embind', 'embind.test.js')] + args, stderr=PIPE if fail else None).communicate() + assert os.path.exists(self.in_dir('a.out.js')) == (not fail) + if not fail: + output = run_js(self.in_dir('a.out.js'), stdout=PIPE, stderr=PIPE, full_output=True, assert_returncode=0) + assert "FAIL" not in output, output def test_llvm_nativizer(self): try: @@ -2381,6 +2376,11 @@ int main() { err = Popen([PYTHON, EMCC, 'src.cpp', '-include', 'header.h', '-Xclang', '-print-stats'], stderr=PIPE).communicate() assert '*** PCH/Modules Loaded:\nModule: header.h.gch' not in err[1], err[1] + # with specified target via -o + try_delete('header.h.gch') + Popen([PYTHON, EMCC, '-xc++-header', 'header.h', '-o', 'my.gch']).communicate() + assert os.path.exists('my.gch') + def test_warn_unaligned(self): if os.environ.get('EMCC_FAST_COMPILER') == '0': return self.skip('need fastcomp') open('src.cpp', 'w').write(r''' @@ -2710,3 +2710,82 @@ int main() assert os.path.exists('hello_world.o') assert os.path.exists('hello_world.bc') + def test_bad_function_pointer_cast(self): + open('src.cpp', 'w').write(r''' +#include <stdio.h> + +typedef int (*callback) (int, ...); + +int impl(int foo) { + printf("Hello, world.\n"); + return 0; +} + +int main() { + volatile callback f = (callback) impl; + f(0); /* This fails with or without additional arguments. */ + return 0; +} +''') + + for opts in [0, 1, 2]: + for safe in [0, 1]: + cmd = [PYTHON, EMCC, 'src.cpp', '-O' + str(opts), '-s', 'SAFE_HEAP=' + str(safe)] + print cmd + Popen(cmd).communicate() + output = run_js('a.out.js', stderr=PIPE, full_output=True) + if safe: + assert 'Function table mask error' in output, output + else: + if opts == 0: + assert 'Invalid function pointer called' in output, output + else: + assert 'abort()' in output, output + + def test_aliased_func_pointers(self): + open('src.cpp', 'w').write(r''' +#include <stdio.h> + +int impl1(int foo) { return foo; } +float impla(float foo) { return foo; } +int impl2(int foo) { return foo+1; } +float implb(float foo) { return foo+1; } +int impl3(int foo) { return foo+2; } +float implc(float foo) { return foo+2; } + +int main(int argc, char **argv) { + volatile void *f = (void*)impl1; + if (argc == 50) f = (void*)impla; + if (argc == 51) f = (void*)impl2; + if (argc == 52) f = (void*)implb; + if (argc == 53) f = (void*)impl3; + if (argc == 54) f = (void*)implc; + return (int)f; +} +''') + + print 'aliasing' + + sizes_ii = {} + sizes_dd = {} + + for alias in [None, 0, 1]: + cmd = [PYTHON, EMCC, 'src.cpp', '-O1'] + if alias is not None: + cmd += ['-s', 'ALIASING_FUNCTION_POINTERS=' + str(alias)] + else: + alias = -1 + print cmd + Popen(cmd).communicate() + src = open('a.out.js').read().split('\n') + for line in src: + if line.strip().startswith('var FUNCTION_TABLE_ii = '): + sizes_ii[alias] = line.count(',') + if line.strip().startswith('var FUNCTION_TABLE_dd = '): + sizes_dd[alias] = line.count(',') + + for sizes in [sizes_ii, sizes_dd]: + assert sizes[-1] == 3 # default - let them alias + assert sizes[0] == 7 # no aliasing, all unique, fat tables + assert sizes[1] == 3 # aliased once more + diff --git a/tests/webidl/output.txt b/tests/webidl/output.txt new file mode 100644 index 00000000..b874d928 --- /dev/null +++ b/tests/webidl/output.txt @@ -0,0 +1,56 @@ +Parent:42 +* +84 +c1 +Parent:7 +Child1:7 +7 +14 +196 +588 +14 +28 +c1 v2 +Parent:16 +Child1:15 +15 +30 +900 +2700 +c2 +Parent:9 +Child2:9 +9 +18 +5832 +0 +0 +1 +*static* +*virtualf* +*virtualf* +*virtualf2* +Parent:9 +Child2:9 +*js virtualf replacement* +*js virtualf replacement* +*js virtualf2 replacement* +*js virtualf3 replacement 123* +caught: a JSImplementation must implement all functions, you forgot Child2JS::virtualFunc4. +*virtualf* +*virtualf* +*virtualf2* +*ok* +|hello|43|world|41| +12.35 +10 +object +10 +11 +object +10 +11 +21.12 +198 + +done. diff --git a/tests/webidl/post.js b/tests/webidl/post.js new file mode 100644 index 00000000..444efcd1 --- /dev/null +++ b/tests/webidl/post.js @@ -0,0 +1,117 @@ + +// Part 1 + +var sme = new Module.Parent(42); +sme.mulVal(2); +Module.print('*') +Module.print(sme.getVal()); + +Module.print('c1'); + +var c1 = new Module.Child1(); +Module.print(c1.getVal()); +c1.mulVal(2); +Module.print(c1.getVal()); +Module.print(c1.getValSqr()); +Module.print(c1.getValSqr(3)); +Module.print(c1.getValTimes()); // default argument should be 1 +Module.print(c1.getValTimes(2)); + +Module.print('c1 v2'); + +c1 = new Module.Child1(8); // now with a parameter, we should handle the overloading automatically and properly and use constructor #2 +Module.print(c1.getVal()); +c1.mulVal(2); +Module.print(c1.getVal()); +Module.print(c1.getValSqr()); +Module.print(c1.getValSqr(3)); + +Module.print('c2') + +var c2 = new Module.Child2(); +Module.print(c2.getVal()); +c2.mulVal(2); +Module.print(c2.getVal()); +Module.print(c2.getValCube()); +var succeeded; +try { + succeeded = 0; + Module.print(c2.doSomethingSecret()); // should fail since private + succeeded = 1; +} catch(e) {} +Module.print(succeeded); +try { + succeeded = 0; + Module.print(c2.getValSqr()); // function from the other class + succeeded = 1; +} catch(e) {} +Module.print(succeeded); +try { + succeeded = 0; + c2.getValCube(); // sanity + succeeded = 1; +} catch(e) {} +Module.print(succeeded); + +Module.Child2.prototype.printStatic(); // static calls go through the prototype + +// virtual function +c2.virtualFunc(); +Module.Child2.prototype.runVirtualFunc(c2); +c2.virtualFunc2(); + +// extend a class from JS +var c3 = new Module.Child2JS; + +c3.virtualFunc = function() { + Module.print('*js virtualf replacement*'); +}; +c3.virtualFunc2 = function() { + Module.print('*js virtualf2 replacement*'); +}; +c3.virtualFunc3 = function(x) { + Module.print('*js virtualf3 replacement ' + x + '*'); +}; + +c3.virtualFunc(); +Module.Child2.prototype.runVirtualFunc(c3); +c3.virtualFunc2(); +c3.virtualFunc3(123); // this one is not replaced! +try { + c3.virtualFunc4(123); +} catch(e) { + Module.print('caught: ' + e); +} + +c2.virtualFunc(); // original should remain the same +Module.Child2.prototype.runVirtualFunc(c2); +c2.virtualFunc2(); +Module.print('*ok*'); + +// Part 2 + +var suser = new Module.StringUser("hello", 43); +suser.Print(41, "world"); +suser.PrintFloat(12.3456); + +var bv = new Module.RefUser(10); +var bv2 = new Module.RefUser(11); +Module.print(bv2.getValue(bv)); + +Module.print(typeof bv2.getMe()); +Module.print(bv2.getMe().getValue(bv)); +Module.print(bv2.getMe().getValue(bv2)); + +Module.print(typeof bv2.getCopy()); +Module.print(bv2.getCopy().getValue(bv)); +Module.print(bv2.getCopy().getValue(bv2)); + +bv2.getAnother().PrintFloat(21.12); + +Module.print(new Module.Inner().get()); +new Module.Inner().mul(2); + +// + +Module.print('\ndone.') + diff --git a/tests/webidl/test.cpp b/tests/webidl/test.cpp new file mode 100644 index 00000000..8a2b5c72 --- /dev/null +++ b/tests/webidl/test.cpp @@ -0,0 +1,8 @@ +#include "test.h" + +Parent::Parent(int val) : value(val) { printf("Parent:%d\n", val); } +Parent::Parent(Parent *p, Parent *q) : value(p->value + q->value) { printf("Parent:%d\n", value); } +void Parent::mulVal(int mul) { value *= mul; } + +#include "glue.cpp" + diff --git a/tests/webidl/test.h b/tests/webidl/test.h new file mode 100644 index 00000000..903f8f78 --- /dev/null +++ b/tests/webidl/test.h @@ -0,0 +1,72 @@ +#include <stdio.h> + +// Part 1 + +class Parent { +protected: + int value; +public: + Parent(int val); + Parent(Parent *p, Parent *q); // overload constructor + int getVal() { return value; }; // inline should work just fine here, unlike Way 1 before + void mulVal(int mul); +}; + +class Child1 : public Parent { +public: + Child1() : Parent(7) { printf("Child1:%d\n", value); }; + Child1(int val) : Parent(val*2) { value -= 1; printf("Child1:%d\n", value); }; + int getValSqr() { return value*value; } + int getValSqr(int more) { return value*value*more; } + int getValTimes(int times=1) { return value*times; } +}; + +// Child2 has vtable, parent does not. Checks we cast child->parent properly - (Parent*)child is not a no-op, must offset +class Child2 : public Parent { +public: + Child2() : Parent(9) { printf("Child2:%d\n", value); }; + int getValCube() { return value*value*value; } + static void printStatic() { printf("*static*\n"); } + + virtual void virtualFunc() { printf("*virtualf*\n"); } + virtual void virtualFunc2() { printf("*virtualf2*\n"); } + static void runVirtualFunc(Child2 *self) { self->virtualFunc(); }; + virtual void virtualFunc3(int x) { printf("*virtualf3: %d*\n", x); } + virtual void virtualFunc4(int x) { printf("*virtualf4: %d*\n", x); } + +private: + void doSomethingSecret() { printf("security breached!\n"); }; // we should not be able to do this +}; + +// Part 2 + +#include <string.h> + +class StringUser { + char *s; + int i; +public: + StringUser(char *string="NO", int integer=99) : s(strdup(string)), i(integer) {} + void Print(int anotherInteger, char *anotherString) { + printf("|%s|%d|%s|%d|\n", s, i, anotherString, anotherInteger); + } + void PrintFloat(float f) { printf("%.2f\n", f); } +}; + +struct RefUser { + int value; + RefUser(int x = 77) : value(x) {} + int getValue(RefUser b) { return b.value; } + RefUser &getMe() { return *this; } + RefUser getCopy() { return RefUser(value*2); } + StringUser getAnother() { return StringUser("another", 5); } +}; + +namespace Space { + struct Inner { + Inner() {} + int get() { return 198; } + Inner& operator*=(float x) { return *this; } + }; +} + diff --git a/tests/webidl/test.idl b/tests/webidl/test.idl new file mode 100644 index 00000000..98ab5070 --- /dev/null +++ b/tests/webidl/test.idl @@ -0,0 +1,64 @@ + +// Part 1 + +interface Parent { + void Parent(long val); + long getVal(); + void mulVal(long mul); +}; + +interface Child1 { + void Child1(optional long val); + long getValSqr(optional long more); + long getValTimes(optional long times=1); +}; + +Child1 implements Parent; + +interface Child2 { + void Child2(); + long getValCube(); + static void printStatic(); + void virtualFunc(); + void virtualFunc2(); + void virtualFunc3(long x); + void virtualFunc4(long x); + static void runVirtualFunc(Child2 self); +}; + +Child2 implements Parent; + +[JSImplementation="Child2"] +interface Child2JS { + void Child2JS(); + void virtualFunc(); + void virtualFunc2(); + void virtualFunc3(long x); + void virtualFunc4(long x); +}; + +// Part 2 + +interface StringUser { + void StringUser(); + void StringUser(DOMString str, long i); + void Print(long anotherInteger, DOMString anotherString); + void PrintFloat(float f); +}; + +interface RefUser { + void RefUser(); + void RefUser(long value); + long getValue([Ref] RefUser b); + [Ref] RefUser getMe(); + [Value] RefUser getCopy(); // must have zero-arg constructor + [Value] StringUser getAnother(); +}; + +[Prefix="Space::"] +interface Inner { + void Inner(); + long get(); + [Operator="*=", Ref] Inner mul(float x); +}; + diff --git a/third_party/WebIDL.py b/third_party/WebIDL.py new file mode 100644 index 00000000..867a7cbc --- /dev/null +++ b/third_party/WebIDL.py @@ -0,0 +1,5030 @@ +# from http://mxr.mozilla.org/mozilla-central/source/dom/bindings/parser/WebIDL.py +# rev 501baeb3a034 + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +""" A WebIDL parser. """ + +from ply import lex, yacc +import re +import os +import traceback +import math + +# Machinery + +def parseInt(literal): + string = literal + sign = 0 + base = 0 + + if string[0] == '-': + sign = -1 + string = string[1:] + else: + sign = 1 + + if string[0] == '0' and len(string) > 1: + if string[1] == 'x' or string[1] == 'X': + base = 16 + string = string[2:] + else: + base = 8 + string = string[1:] + else: + base = 10 + + value = int(string, base) + return value * sign + +# Magic for creating enums +def M_add_class_attribs(attribs, start): + def foo(name, bases, dict_): + for v, k in enumerate(attribs): + dict_[k] = start + v + assert 'length' not in dict_ + dict_['length'] = start + len(attribs) + return type(name, bases, dict_) + return foo + +def enum(*names, **kw): + if len(kw) == 1: + base = kw['base'].__class__ + start = base.length + else: + assert len(kw) == 0 + base = object + start = 0 + class Foo(base): + __metaclass__ = M_add_class_attribs(names, start) + def __setattr__(self, name, value): # this makes it read-only + raise NotImplementedError + return Foo() + +class WebIDLError(Exception): + def __init__(self, message, locations, warning=False): + self.message = message + self.locations = [str(loc) for loc in locations] + self.warning = warning + + def __str__(self): + return "%s: %s%s%s" % (self.warning and 'warning' or 'error', + self.message, + ", " if len(self.locations) != 0 else "", + "\n".join(self.locations)) + +class Location(object): + def __init__(self, lexer, lineno, lexpos, filename): + self._line = None + self._lineno = lineno + self._lexpos = lexpos + self._lexdata = lexer.lexdata + self._file = filename if filename else "<unknown>" + + def __eq__(self, other): + return self._lexpos == other._lexpos and \ + self._file == other._file + + def filename(self): + return self._file + + def resolve(self): + if self._line: + return + + startofline = self._lexdata.rfind('\n', 0, self._lexpos) + 1 + endofline = self._lexdata.find('\n', self._lexpos, self._lexpos + 80) + if endofline != -1: + self._line = self._lexdata[startofline:endofline] + else: + self._line = self._lexdata[startofline:] + self._colno = self._lexpos - startofline + + # Our line number seems to point to the start of self._lexdata + self._lineno += self._lexdata.count('\n', 0, startofline) + + def get(self): + self.resolve() + return "%s line %s:%s" % (self._file, self._lineno, self._colno) + + def _pointerline(self): + return " " * self._colno + "^" + + def __str__(self): + self.resolve() + return "%s line %s:%s\n%s\n%s" % (self._file, self._lineno, self._colno, + self._line, self._pointerline()) + +class BuiltinLocation(object): + def __init__(self, text): + self.msg = text + "\n" + + def __eq__(self, other): + return isinstance(other, BuiltinLocation) and \ + self.msg == other.msg + + def filename(self): + return '<builtin>' + + def resolve(self): + pass + + def get(self): + return self.msg + + def __str__(self): + return self.get() + + +# Data Model + +class IDLObject(object): + def __init__(self, location): + self.location = location + self.userData = dict() + + def filename(self): + return self.location.filename() + + def isInterface(self): + return False + + def isEnum(self): + return False + + def isCallback(self): + return False + + def isType(self): + return False + + def isDictionary(self): + return False; + + def isUnion(self): + return False + + def getUserData(self, key, default): + return self.userData.get(key, default) + + def setUserData(self, key, value): + self.userData[key] = value + + def addExtendedAttributes(self, attrs): + assert False # Override me! + + def handleExtendedAttribute(self, attr): + assert False # Override me! + + def _getDependentObjects(self): + assert False # Override me! + + def getDeps(self, visited=None): + """ Return a set of files that this object depends on. If any of + these files are changed the parser needs to be rerun to regenerate + a new IDLObject. + + The visited argument is a set of all the objects already visited. + We must test to see if we are in it, and if so, do nothing. This + prevents infinite recursion.""" + + # NB: We can't use visited=set() above because the default value is + # evaluated when the def statement is evaluated, not when the function + # is executed, so there would be one set for all invocations. + if visited == None: + visited = set() + + if self in visited: + return set() + + visited.add(self) + + deps = set() + if self.filename() != "<builtin>": + deps.add(self.filename()) + + for d in self._getDependentObjects(): + deps = deps.union(d.getDeps(visited)) + + return deps + +class IDLScope(IDLObject): + def __init__(self, location, parentScope, identifier): + IDLObject.__init__(self, location) + + self.parentScope = parentScope + if identifier: + assert isinstance(identifier, IDLIdentifier) + self._name = identifier + else: + self._name = None + + self._dict = {} + + def __str__(self): + return self.QName() + + def QName(self): + if self._name: + return self._name.QName() + "::" + return "::" + + def ensureUnique(self, identifier, object): + """ + Ensure that there is at most one 'identifier' in scope ('self'). + Note that object can be None. This occurs if we end up here for an + interface type we haven't seen yet. + """ + assert isinstance(identifier, IDLUnresolvedIdentifier) + assert not object or isinstance(object, IDLObjectWithIdentifier) + assert not object or object.identifier == identifier + + if identifier.name in self._dict: + if not object: + return + + # ensureUnique twice with the same object is not allowed + assert id(object) != id(self._dict[identifier.name]) + + replacement = self.resolveIdentifierConflict(self, identifier, + self._dict[identifier.name], + object) + self._dict[identifier.name] = replacement + return + + assert object + + self._dict[identifier.name] = object + + def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject): + if isinstance(originalObject, IDLExternalInterface) and \ + isinstance(newObject, IDLExternalInterface) and \ + originalObject.identifier.name == newObject.identifier.name: + return originalObject + + if (isinstance(originalObject, IDLExternalInterface) or + isinstance(newObject, IDLExternalInterface)): + raise WebIDLError( + "Name collision between " + "interface declarations for identifier '%s' at '%s' and '%s'" + % (identifier.name, + originalObject.location, newObject.location), []) + + # We do the merging of overloads here as opposed to in IDLInterface + # because we need to merge overloads of NamedConstructors and we need to + # detect conflicts in those across interfaces. See also the comment in + # IDLInterface.addExtendedAttributes for "NamedConstructor". + if originalObject.tag == IDLInterfaceMember.Tags.Method and \ + newObject.tag == IDLInterfaceMember.Tags.Method: + return originalObject.addOverload(newObject) + + # Default to throwing, derived classes can override. + conflictdesc = "\n\t%s at %s\n\t%s at %s" % \ + (originalObject, originalObject.location, newObject, newObject.location) + + raise WebIDLError( + "Multiple unresolvable definitions of identifier '%s' in scope '%s%s" + % (identifier.name, str(self), conflictdesc), []) + + def _lookupIdentifier(self, identifier): + return self._dict[identifier.name] + + def lookupIdentifier(self, identifier): + assert isinstance(identifier, IDLIdentifier) + assert identifier.scope == self + return self._lookupIdentifier(identifier) + +class IDLIdentifier(IDLObject): + def __init__(self, location, scope, name): + IDLObject.__init__(self, location) + + self.name = name + assert isinstance(scope, IDLScope) + self.scope = scope + + def __str__(self): + return self.QName() + + def QName(self): + return self.scope.QName() + self.name + + def __hash__(self): + return self.QName().__hash__() + + def __eq__(self, other): + return self.QName() == other.QName() + + def object(self): + return self.scope.lookupIdentifier(self) + +class IDLUnresolvedIdentifier(IDLObject): + def __init__(self, location, name, allowDoubleUnderscore = False, + allowForbidden = False): + IDLObject.__init__(self, location) + + assert len(name) > 0 + + if name[:2] == "__" and name != "__content" and name != "___noSuchMethod__" and not allowDoubleUnderscore: + raise WebIDLError("Identifiers beginning with __ are reserved", + [location]) + if name[0] == '_' and not allowDoubleUnderscore: + name = name[1:] + # TODO: Bug 872377, Restore "toJSON" to below list. + # We sometimes need custom serialization, so allow toJSON for now. + if (name in ["constructor", "toString"] and + not allowForbidden): + raise WebIDLError("Cannot use reserved identifier '%s'" % (name), + [location]) + + self.name = name + + def __str__(self): + return self.QName() + + def QName(self): + return "<unresolved scope>::" + self.name + + def resolve(self, scope, object): + assert isinstance(scope, IDLScope) + assert not object or isinstance(object, IDLObjectWithIdentifier) + assert not object or object.identifier == self + + scope.ensureUnique(self, object) + + identifier = IDLIdentifier(self.location, scope, self.name) + if object: + object.identifier = identifier + return identifier + + def finish(self): + assert False # Should replace with a resolved identifier first. + +class IDLObjectWithIdentifier(IDLObject): + def __init__(self, location, parentScope, identifier): + IDLObject.__init__(self, location) + + assert isinstance(identifier, IDLUnresolvedIdentifier) + + self.identifier = identifier + + if parentScope: + self.resolve(parentScope) + + self.treatNullAs = "Default" + + def resolve(self, parentScope): + assert isinstance(parentScope, IDLScope) + assert isinstance(self.identifier, IDLUnresolvedIdentifier) + self.identifier.resolve(parentScope, self) + + def checkForStringHandlingExtendedAttributes(self, attrs, + isDictionaryMember=False, + isOptional=False): + """ + A helper function to deal with TreatNullAs. Returns the list + of attrs it didn't handle itself. + """ + assert isinstance(self, IDLArgument) or isinstance(self, IDLAttribute) + unhandledAttrs = list() + for attr in attrs: + if not attr.hasValue(): + unhandledAttrs.append(attr) + continue + + identifier = attr.identifier() + value = attr.value() + if identifier == "TreatNullAs": + if not self.type.isDOMString() or self.type.nullable(): + raise WebIDLError("[TreatNullAs] is only allowed on " + "arguments or attributes whose type is " + "DOMString", + [self.location]) + if isDictionaryMember: + raise WebIDLError("[TreatNullAs] is not allowed for " + "dictionary members", [self.location]) + if value != 'EmptyString': + raise WebIDLError("[TreatNullAs] must take the identifier " + "'EmptyString', not '%s'" % value, + [self.location]) + self.treatNullAs = value + else: + unhandledAttrs.append(attr) + + return unhandledAttrs + +class IDLObjectWithScope(IDLObjectWithIdentifier, IDLScope): + def __init__(self, location, parentScope, identifier): + assert isinstance(identifier, IDLUnresolvedIdentifier) + + IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier) + IDLScope.__init__(self, location, parentScope, self.identifier) + +class IDLIdentifierPlaceholder(IDLObjectWithIdentifier): + def __init__(self, location, identifier): + assert isinstance(identifier, IDLUnresolvedIdentifier) + IDLObjectWithIdentifier.__init__(self, location, None, identifier) + + def finish(self, scope): + try: + scope._lookupIdentifier(self.identifier) + except: + raise WebIDLError("Unresolved type '%s'." % self.identifier, + [self.location]) + + obj = self.identifier.resolve(scope, None) + return scope.lookupIdentifier(obj) + +class IDLExternalInterface(IDLObjectWithIdentifier): + def __init__(self, location, parentScope, identifier): + assert isinstance(identifier, IDLUnresolvedIdentifier) + assert isinstance(parentScope, IDLScope) + self.parent = None + IDLObjectWithIdentifier.__init__(self, location, parentScope, identifier) + IDLObjectWithIdentifier.resolve(self, parentScope) + + def finish(self, scope): + pass + + def validate(self): + pass + + def isExternal(self): + return True + + def isInterface(self): + return True + + def isConsequential(self): + return False + + def addExtendedAttributes(self, attrs): + assert len(attrs) == 0 + + def resolve(self, parentScope): + pass + + def getJSImplementation(self): + return None + + def isJSImplemented(self): + return False + + def getNavigatorProperty(self): + return None + + def _getDependentObjects(self): + return set() + +class IDLInterface(IDLObjectWithScope): + def __init__(self, location, parentScope, name, parent, members, + isPartial): + assert isinstance(parentScope, IDLScope) + assert isinstance(name, IDLUnresolvedIdentifier) + assert not isPartial or not parent + + self.parent = None + self._callback = False + self._finished = False + self.members = [] + # namedConstructors needs deterministic ordering because bindings code + # outputs the constructs in the order that namedConstructors enumerates + # them. + self.namedConstructors = list() + self.implementedInterfaces = set() + self._consequential = False + self._isPartial = True + # self.interfacesBasedOnSelf is the set of interfaces that inherit from + # self or have self as a consequential interface, including self itself. + # Used for distinguishability checking. + self.interfacesBasedOnSelf = set([self]) + # self.interfacesImplementingSelf is the set of interfaces that directly + # have self as a consequential interface + self.interfacesImplementingSelf = set() + self._hasChildInterfaces = False + self._isOnGlobalProtoChain = False + # Tracking of the number of reserved slots we need for our + # members and those of ancestor interfaces. + self.totalMembersInSlots = 0 + # Tracking of the number of own own members we have in slots + self._ownMembersInSlots = 0 + + IDLObjectWithScope.__init__(self, location, parentScope, name) + + if not isPartial: + self.setNonPartial(location, parent, members) + else: + # Just remember our members for now + self.members = members + + def __str__(self): + return "Interface '%s'" % self.identifier.name + + def ctor(self): + identifier = IDLUnresolvedIdentifier(self.location, "constructor", + allowForbidden=True) + try: + return self._lookupIdentifier(identifier) + except: + return None + + def resolveIdentifierConflict(self, scope, identifier, originalObject, newObject): + assert isinstance(scope, IDLScope) + assert isinstance(originalObject, IDLInterfaceMember) + assert isinstance(newObject, IDLInterfaceMember) + + retval = IDLScope.resolveIdentifierConflict(self, scope, identifier, + originalObject, newObject) + + # Might be a ctor, which isn't in self.members + if newObject in self.members: + self.members.remove(newObject) + return retval + + def finish(self, scope): + if self._finished: + return + + self._finished = True + + if self._isPartial: + raise WebIDLError("Interface %s does not have a non-partial " + "declaration" % self.identifier.name, + [self.location]) + + assert not self.parent or isinstance(self.parent, IDLIdentifierPlaceholder) + parent = self.parent.finish(scope) if self.parent else None + if parent and isinstance(parent, IDLExternalInterface): + raise WebIDLError("%s inherits from %s which does not have " + "a definition" % + (self.identifier.name, + self.parent.identifier.name), + [self.location]) + assert not parent or isinstance(parent, IDLInterface) + + self.parent = parent + + assert iter(self.members) + + if self.parent: + self.parent.finish(scope) + + self.parent._hasChildInterfaces = True + + self.totalMembersInSlots = self.parent.totalMembersInSlots + + # Interfaces with [Global] must not have anything inherit from them + if self.parent.getExtendedAttribute("Global"): + # Note: This is not a self.parent.isOnGlobalProtoChain() check + # because ancestors of a [Global] interface can have other + # descendants. + raise WebIDLError("[Global] interface has another interface " + "inheriting from it", + [self.location, self.parent.location]) + + # Callbacks must not inherit from non-callbacks or inherit from + # anything that has consequential interfaces. + # XXXbz Can non-callbacks inherit from callbacks? Spec issue pending. + # XXXbz Can callbacks have consequential interfaces? Spec issue pending + if self.isCallback(): + if not self.parent.isCallback(): + raise WebIDLError("Callback interface %s inheriting from " + "non-callback interface %s" % + (self.identifier.name, + self.parent.identifier.name), + [self.location, self.parent.location]) + elif self.parent.isCallback(): + raise WebIDLError("Non-callback interface %s inheriting from " + "callback interface %s" % + (self.identifier.name, + self.parent.identifier.name), + [self.location, self.parent.location]) + + for iface in self.implementedInterfaces: + iface.finish(scope) + + cycleInGraph = self.findInterfaceLoopPoint(self) + if cycleInGraph: + raise WebIDLError("Interface %s has itself as ancestor or " + "implemented interface" % self.identifier.name, + [self.location, cycleInGraph.location]) + + if self.isCallback(): + # "implements" should have made sure we have no + # consequential interfaces. + assert len(self.getConsequentialInterfaces()) == 0 + # And that we're not consequential. + assert not self.isConsequential() + + # Now resolve() and finish() our members before importing the + # ones from our implemented interfaces. + + # resolve() will modify self.members, so we need to iterate + # over a copy of the member list here. + for member in list(self.members): + member.resolve(self) + + for member in self.members: + member.finish(scope) + + ctor = self.ctor() + if ctor is not None: + ctor.finish(scope) + + for ctor in self.namedConstructors: + ctor.finish(scope) + + # Make a copy of our member list, so things that implement us + # can get those without all the stuff we implement ourselves + # admixed. + self.originalMembers = list(self.members) + + # Import everything from our consequential interfaces into + # self.members. Sort our consequential interfaces by name + # just so we have a consistent order. + for iface in sorted(self.getConsequentialInterfaces(), + cmp=cmp, + key=lambda x: x.identifier.name): + # Flag the interface as being someone's consequential interface + iface.setIsConsequentialInterfaceOf(self) + additionalMembers = iface.originalMembers; + for additionalMember in additionalMembers: + for member in self.members: + if additionalMember.identifier.name == member.identifier.name: + raise WebIDLError( + "Multiple definitions of %s on %s coming from 'implements' statements" % + (member.identifier.name, self), + [additionalMember.location, member.location]) + self.members.extend(additionalMembers) + iface.interfacesImplementingSelf.add(self) + + for ancestor in self.getInheritedInterfaces(): + ancestor.interfacesBasedOnSelf.add(self) + for ancestorConsequential in ancestor.getConsequentialInterfaces(): + ancestorConsequential.interfacesBasedOnSelf.add(self) + + for member in self.members: + if (member.isAttr() and member.isUnforgeable() and + not hasattr(member, "originatingInterface")): + member.originatingInterface = self + + # Compute slot indices for our members before we pull in + # unforgeable members from our parent. + for member in self.members: + if (member.isAttr() and + (member.getExtendedAttribute("StoreInSlot") or + member.getExtendedAttribute("Cached"))): + member.slotIndex = self.totalMembersInSlots + self.totalMembersInSlots += 1 + if member.getExtendedAttribute("StoreInSlot"): + self._ownMembersInSlots += 1 + + if self.parent: + # Make sure we don't shadow any of the [Unforgeable] attributes on + # our ancestor interfaces. We don't have to worry about + # consequential interfaces here, because those have already been + # imported into the relevant .members lists. And we don't have to + # worry about anything other than our parent, because it has already + # imported its ancestors unforgeable attributes into its member + # list. + for unforgeableAttr in (attr for attr in self.parent.members if + attr.isAttr() and not attr.isStatic() and + attr.isUnforgeable()): + shadows = [ m for m in self.members if + (m.isAttr() or m.isMethod()) and + not m.isStatic() and + m.identifier.name == unforgeableAttr.identifier.name ] + if len(shadows) != 0: + locs = [unforgeableAttr.location] + [ s.location for s + in shadows ] + raise WebIDLError("Interface %s shadows [Unforgeable] " + "members of %s" % + (self.identifier.name, + ancestor.identifier.name), + locs) + # And now just stick it in our members, since we won't be + # inheriting this down the proto chain. If we really cared we + # could try to do something where we set up the unforgeable + # attributes of ancestor interfaces, with their corresponding + # getters, on our interface, but that gets pretty complicated + # and seems unnecessary. + self.members.append(unforgeableAttr) + + # Ensure that there's at most one of each {named,indexed} + # {getter,setter,creator,deleter}, at most one stringifier, + # and at most one legacycaller. Note that this last is not + # quite per spec, but in practice no one overloads + # legacycallers. + specialMembersSeen = {} + for member in self.members: + if not member.isMethod(): + continue + + if member.isGetter(): + memberType = "getters" + elif member.isSetter(): + memberType = "setters" + elif member.isCreator(): + memberType = "creators" + elif member.isDeleter(): + memberType = "deleters" + elif member.isStringifier(): + memberType = "stringifiers" + elif member.isJsonifier(): + memberType = "jsonifiers" + elif member.isLegacycaller(): + memberType = "legacycallers" + else: + continue + + if (memberType != "stringifiers" and memberType != "legacycallers" and + memberType != "jsonifiers"): + if member.isNamed(): + memberType = "named " + memberType + else: + assert member.isIndexed() + memberType = "indexed " + memberType + + if memberType in specialMembersSeen: + raise WebIDLError("Multiple " + memberType + " on %s" % (self), + [self.location, + specialMembersSeen[memberType].location, + member.location]) + + specialMembersSeen[memberType] = member + + if self._isOnGlobalProtoChain: + # Make sure we have no named setters, creators, or deleters + for memberType in ["setter", "creator", "deleter"]: + memberId = "named " + memberType + "s" + if memberId in specialMembersSeen: + raise WebIDLError("Interface with [Global] has a named %s" % + memberType, + [self.location, + specialMembersSeen[memberId].location]) + # Make sure we're not [OverrideBuiltins] + if self.getExtendedAttribute("OverrideBuiltins"): + raise WebIDLError("Interface with [Global] also has " + "[OverrideBuiltins]", + [self.location]) + # Mark all of our ancestors as being on the global's proto chain too + parent = self.parent + while parent: + # Must not inherit from an interface with [OverrideBuiltins] + if parent.getExtendedAttribute("OverrideBuiltins"): + raise WebIDLError("Interface with [Global] inherits from " + "interface with [OverrideBuiltins]", + [self.location, parent.location]) + parent._isOnGlobalProtoChain = True + parent = parent.parent + + def validate(self): + for member in self.members: + member.validate() + + # Check that PutForwards refers to another attribute and that no + # cycles exist in forwarded assignments. + if member.isAttr(): + iface = self + attr = member + putForwards = attr.getExtendedAttribute("PutForwards") + if putForwards and self.isCallback(): + raise WebIDLError("[PutForwards] used on an attribute " + "on interface %s which is a callback " + "interface" % self.identifier.name, + [self.location, member.location]) + + while putForwards is not None: + forwardIface = attr.type.unroll().inner + fowardAttr = None + + for forwardedMember in forwardIface.members: + if (not forwardedMember.isAttr() or + forwardedMember.identifier.name != putForwards[0]): + continue + if forwardedMember == member: + raise WebIDLError("Cycle detected in forwarded " + "assignments for attribute %s on " + "%s" % + (member.identifier.name, self), + [member.location]) + fowardAttr = forwardedMember + break + + if fowardAttr is None: + raise WebIDLError("Attribute %s on %s forwards to " + "missing attribute %s" % + (attr.identifier.name, iface, putForwards), + [attr.location]) + + iface = forwardIface + attr = fowardAttr + putForwards = attr.getExtendedAttribute("PutForwards") + + + def isInterface(self): + return True + + def isExternal(self): + return False + + def setIsConsequentialInterfaceOf(self, other): + self._consequential = True + self.interfacesBasedOnSelf.add(other) + + def isConsequential(self): + return self._consequential + + def setCallback(self, value): + self._callback = value + + def isCallback(self): + return self._callback + + def isSingleOperationInterface(self): + assert self.isCallback() or self.isJSImplemented() + return ( + # JS-implemented things should never need the + # this-handling weirdness of single-operation interfaces. + not self.isJSImplemented() and + # Not inheriting from another interface + not self.parent and + # No consequential interfaces + len(self.getConsequentialInterfaces()) == 0 and + # No attributes of any kinds + not any(m.isAttr() for m in self.members) and + # There is at least one regular operation, and all regular + # operations have the same identifier + len(set(m.identifier.name for m in self.members if + m.isMethod() and not m.isStatic())) == 1) + + def inheritanceDepth(self): + depth = 0 + parent = self.parent + while parent: + depth = depth + 1 + parent = parent.parent + return depth + + def hasConstants(self): + return any(m.isConst() for m in self.members) + + def hasInterfaceObject(self): + if self.isCallback(): + return self.hasConstants() + return not hasattr(self, "_noInterfaceObject") + + def hasInterfacePrototypeObject(self): + return not self.isCallback() and self.getUserData('hasConcreteDescendant', False) + + def addExtendedAttributes(self, attrs): + self._extendedAttrDict = {} + for attr in attrs: + identifier = attr.identifier() + + # Special cased attrs + if identifier == "TreatNonCallableAsNull": + raise WebIDLError("TreatNonCallableAsNull cannot be specified on interfaces", + [attr.location, self.location]) + if identifier == "TreatNonObjectAsNull": + raise WebIDLError("TreatNonObjectAsNull cannot be specified on interfaces", + [attr.location, self.location]) + elif identifier == "NoInterfaceObject": + if not attr.noArguments(): + raise WebIDLError("[NoInterfaceObject] must take no arguments", + [attr.location]) + + if self.ctor(): + raise WebIDLError("Constructor and NoInterfaceObject are incompatible", + [self.location]) + + self._noInterfaceObject = True + elif identifier == "Constructor" or identifier == "NamedConstructor" or identifier == "ChromeConstructor": + if identifier == "Constructor" and not self.hasInterfaceObject(): + raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", + [self.location]) + + if identifier == "NamedConstructor" and not attr.hasValue(): + raise WebIDLError("NamedConstructor must either take an identifier or take a named argument list", + [attr.location]) + + if identifier == "ChromeConstructor" and not self.hasInterfaceObject(): + raise WebIDLError(str(identifier) + " and NoInterfaceObject are incompatible", + [self.location]) + + args = attr.args() if attr.hasArgs() else [] + + retType = IDLWrapperType(self.location, self) + + if identifier == "Constructor" or identifier == "ChromeConstructor": + name = "constructor" + allowForbidden = True + else: + name = attr.value() + allowForbidden = False + + methodIdentifier = IDLUnresolvedIdentifier(self.location, name, + allowForbidden=allowForbidden) + + method = IDLMethod(self.location, methodIdentifier, retType, + args, static=True) + # Constructors are always NewObject and are always + # assumed to be able to throw (since there's no way to + # indicate otherwise) and never have any other + # extended attributes. + method.addExtendedAttributes( + [IDLExtendedAttribute(self.location, ("NewObject",)), + IDLExtendedAttribute(self.location, ("Throws",))]) + if identifier == "ChromeConstructor": + method.addExtendedAttributes( + [IDLExtendedAttribute(self.location, ("ChromeOnly",))]) + + if identifier == "Constructor" or identifier == "ChromeConstructor": + method.resolve(self) + else: + # We need to detect conflicts for NamedConstructors across + # interfaces. We first call resolve on the parentScope, + # which will merge all NamedConstructors with the same + # identifier accross interfaces as overloads. + method.resolve(self.parentScope) + + # Then we look up the identifier on the parentScope. If the + # result is the same as the method we're adding then it + # hasn't been added as an overload and it's the first time + # we've encountered a NamedConstructor with that identifier. + # If the result is not the same as the method we're adding + # then it has been added as an overload and we need to check + # whether the result is actually one of our existing + # NamedConstructors. + newMethod = self.parentScope.lookupIdentifier(method.identifier) + if newMethod == method: + self.namedConstructors.append(method) + elif not newMethod in self.namedConstructors: + raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface", + [method.location, newMethod.location]) + elif (identifier == "ArrayClass"): + if not attr.noArguments(): + raise WebIDLError("[ArrayClass] must take no arguments", + [attr.location]) + if self.parent: + raise WebIDLError("[ArrayClass] must not be specified on " + "an interface with inherited interfaces", + [attr.location, self.location]) + elif identifier == "Global": + if not attr.noArguments(): + raise WebIDLError("[Global] must take no arguments", + [attr.location]) + self._isOnGlobalProtoChain = True + elif (identifier == "NeedNewResolve" or + identifier == "OverrideBuiltins" or + identifier == "NoDelete" or + identifier == "ChromeOnly"): + # Known extended attributes that do not take values + if not attr.noArguments(): + raise WebIDLError("[%s] must take no arguments" % identifier, + [attr.location]) + elif (identifier == "Pref" or + identifier == "JSImplementation" or + identifier == "HeaderFile" or + identifier == "NavigatorProperty" or + identifier == "AvailableIn" or + identifier == "Prefix" or + identifier == "Func"): + # Known extended attributes that take a string value + if not attr.hasValue(): + raise WebIDLError("[%s] must have a value" % identifier, + [attr.location]) + else: + raise WebIDLError("Unknown extended attribute %s on interface" % identifier, + [attr.location]) + + attrlist = attr.listValue() + self._extendedAttrDict[identifier] = attrlist if len(attrlist) else True + + def addImplementedInterface(self, implementedInterface): + assert(isinstance(implementedInterface, IDLInterface)) + self.implementedInterfaces.add(implementedInterface) + + def getInheritedInterfaces(self): + """ + Returns a list of the interfaces this interface inherits from + (not including this interface itself). The list is in order + from most derived to least derived. + """ + assert(self._finished) + if not self.parent: + return [] + parentInterfaces = self.parent.getInheritedInterfaces() + parentInterfaces.insert(0, self.parent) + return parentInterfaces + + def getConsequentialInterfaces(self): + assert(self._finished) + # The interfaces we implement directly + consequentialInterfaces = set(self.implementedInterfaces) + + # And their inherited interfaces + for iface in self.implementedInterfaces: + consequentialInterfaces |= set(iface.getInheritedInterfaces()) + + # And now collect up the consequential interfaces of all of those + temp = set() + for iface in consequentialInterfaces: + temp |= iface.getConsequentialInterfaces() + + return consequentialInterfaces | temp + + def findInterfaceLoopPoint(self, otherInterface): + """ + Finds an interface, amongst our ancestors and consequential interfaces, + that inherits from otherInterface or implements otherInterface + directly. If there is no such interface, returns None. + """ + if self.parent: + if self.parent == otherInterface: + return self + loopPoint = self.parent.findInterfaceLoopPoint(otherInterface) + if loopPoint: + return loopPoint + if otherInterface in self.implementedInterfaces: + return self + for iface in self.implementedInterfaces: + loopPoint = iface.findInterfaceLoopPoint(otherInterface) + if loopPoint: + return loopPoint + return None + + def getExtendedAttribute(self, name): + return self._extendedAttrDict.get(name, None) + + def setNonPartial(self, location, parent, members): + assert not parent or isinstance(parent, IDLIdentifierPlaceholder) + if not self._isPartial: + raise WebIDLError("Two non-partial definitions for the " + "same interface", + [location, self.location]) + self._isPartial = False + # Now make it look like we were parsed at this new location, since + # that's the place where the interface is "really" defined + self.location = location + assert not self.parent + self.parent = parent + # Put the new members at the beginning + self.members = members + self.members + + def getJSImplementation(self): + classId = self.getExtendedAttribute("JSImplementation") + if not classId: + return classId + assert isinstance(classId, list) + assert len(classId) == 1 + return classId[0] + + def isJSImplemented(self): + return bool(self.getJSImplementation()) + + def getNavigatorProperty(self): + naviProp = self.getExtendedAttribute("NavigatorProperty") + if not naviProp: + return None + assert len(naviProp) == 1 + assert isinstance(naviProp, list) + assert len(naviProp[0]) != 0 + return naviProp[0] + + def hasChildInterfaces(self): + return self._hasChildInterfaces + + def isOnGlobalProtoChain(self): + return self._isOnGlobalProtoChain + + def _getDependentObjects(self): + deps = set(self.members) + deps.union(self.implementedInterfaces) + if self.parent: + deps.add(self.parent) + return deps + + def hasMembersInSlots(self): + return self._ownMembersInSlots != 0 + +class IDLDictionary(IDLObjectWithScope): + def __init__(self, location, parentScope, name, parent, members): + assert isinstance(parentScope, IDLScope) + assert isinstance(name, IDLUnresolvedIdentifier) + assert not parent or isinstance(parent, IDLIdentifierPlaceholder) + + self.parent = parent + self._finished = False + self.members = list(members) + + IDLObjectWithScope.__init__(self, location, parentScope, name) + + def __str__(self): + return "Dictionary '%s'" % self.identifier.name + + def isDictionary(self): + return True; + + def finish(self, scope): + if self._finished: + return + + self._finished = True + + if self.parent: + assert isinstance(self.parent, IDLIdentifierPlaceholder) + oldParent = self.parent + self.parent = self.parent.finish(scope) + if not isinstance(self.parent, IDLDictionary): + raise WebIDLError("Dictionary %s has parent that is not a dictionary" % + self.identifier.name, + [oldParent.location, self.parent.location]) + + # Make sure the parent resolves all its members before we start + # looking at them. + self.parent.finish(scope) + + for member in self.members: + member.resolve(self) + if not member.isComplete(): + member.complete(scope) + assert member.type.isComplete() + + # Members of a dictionary are sorted in lexicographic order + self.members.sort(cmp=cmp, key=lambda x: x.identifier.name) + + inheritedMembers = [] + ancestor = self.parent + while ancestor: + if ancestor == self: + raise WebIDLError("Dictionary %s has itself as an ancestor" % + self.identifier.name, + [self.identifier.location]) + inheritedMembers.extend(ancestor.members) + ancestor = ancestor.parent + + # Catch name duplication + for inheritedMember in inheritedMembers: + for member in self.members: + if member.identifier.name == inheritedMember.identifier.name: + raise WebIDLError("Dictionary %s has two members with name %s" % + (self.identifier.name, member.identifier.name), + [member.location, inheritedMember.location]) + + def validate(self): + def typeContainsDictionary(memberType, dictionary): + """ + Returns a tuple whose: + + - First element is a Boolean value indicating whether + memberType contains dictionary. + + - Second element is: + A list of locations that leads from the type that was passed in + the memberType argument, to the dictionary being validated, + if the boolean value in the first element is True. + + None, if the boolean value in the first element is False. + """ + + if memberType.nullable() or \ + memberType.isArray() or \ + memberType.isSequence(): + return typeContainsDictionary(memberType.inner, dictionary) + + if memberType.isDictionary(): + if memberType.inner == dictionary: + return (True, [memberType.location]) + + (contains, locations) = dictionaryContainsDictionary(memberType.inner, \ + dictionary) + if contains: + return (True, [memberType.location] + locations) + + if memberType.isUnion(): + for member in memberType.flatMemberTypes: + (contains, locations) = typeContainsDictionary(member, dictionary) + if contains: + return (True, locations) + + return (False, None) + + def dictionaryContainsDictionary(dictMember, dictionary): + for member in dictMember.members: + (contains, locations) = typeContainsDictionary(member.type, dictionary) + if contains: + return (True, [member.location] + locations) + + if dictMember.parent: + if dictMember.parent == dictionary: + return (True, [dictMember.location]) + else: + (contains, locations) = dictionaryContainsDictionary(dictMember.parent, dictionary) + if contains: + return (True, [dictMember.location] + locations) + + return (False, None) + + for member in self.members: + if member.type.isDictionary() and member.type.nullable(): + raise WebIDLError("Dictionary %s has member with nullable " + "dictionary type" % self.identifier.name, + [member.location]) + (contains, locations) = typeContainsDictionary(member.type, self) + if contains: + raise WebIDLError("Dictionary %s has member with itself as type." % + self.identifier.name, + [member.location] + locations) + + def addExtendedAttributes(self, attrs): + assert len(attrs) == 0 + + def _getDependentObjects(self): + deps = set(self.members) + if (self.parent): + deps.add(self.parent) + return deps + +class IDLEnum(IDLObjectWithIdentifier): + def __init__(self, location, parentScope, name, values): + assert isinstance(parentScope, IDLScope) + assert isinstance(name, IDLUnresolvedIdentifier) + + if len(values) != len(set(values)): + raise WebIDLError("Enum %s has multiple identical strings" % name.name, + [location]) + + IDLObjectWithIdentifier.__init__(self, location, parentScope, name) + self._values = values + + def values(self): + return self._values + + def finish(self, scope): + pass + + def validate(self): + pass + + def isEnum(self): + return True + + def addExtendedAttributes(self, attrs): + assert len(attrs) == 0 + + def _getDependentObjects(self): + return set() + +class IDLType(IDLObject): + Tags = enum( + # The integer types + 'int8', + 'uint8', + 'int16', + 'uint16', + 'int32', + 'uint32', + 'int64', + 'uint64', + # Additional primitive types + 'bool', + 'unrestricted_float', + 'float', + 'unrestricted_double', + # "double" last primitive type to match IDLBuiltinType + 'double', + # Other types + 'any', + 'domstring', + 'bytestring', + 'object', + 'date', + 'void', + # Funny stuff + 'interface', + 'dictionary', + 'enum', + 'callback', + 'union', + 'sequence', + 'array' + ) + + def __init__(self, location, name): + IDLObject.__init__(self, location) + self.name = name + self.builtin = False + + def __eq__(self, other): + return other and self.builtin == other.builtin and self.name == other.name + + def __ne__(self, other): + return not self == other + + def __str__(self): + return str(self.name) + + def isType(self): + return True + + def nullable(self): + return False + + def isPrimitive(self): + return False + + def isBoolean(self): + return False + + def isNumeric(self): + return False + + def isString(self): + return False + + def isByteString(self): + return False + + def isDOMString(self): + return False + + def isVoid(self): + return self.name == "Void" + + def isSequence(self): + return False + + def isArray(self): + return False + + def isArrayBuffer(self): + return False + + def isArrayBufferView(self): + return False + + def isTypedArray(self): + return False + + def isCallbackInterface(self): + return False + + def isNonCallbackInterface(self): + return False + + def isGeckoInterface(self): + """ Returns a boolean indicating whether this type is an 'interface' + type that is implemented in Gecko. At the moment, this returns + true for all interface types that are not types from the TypedArray + spec.""" + return self.isInterface() and not self.isSpiderMonkeyInterface() + + def isSpiderMonkeyInterface(self): + """ Returns a boolean indicating whether this type is an 'interface' + type that is implemented in Spidermonkey. At the moment, this + only returns true for the types from the TypedArray spec. """ + return self.isInterface() and (self.isArrayBuffer() or \ + self.isArrayBufferView() or \ + self.isTypedArray()) + + def isDictionary(self): + return False + + def isInterface(self): + return False + + def isAny(self): + return self.tag() == IDLType.Tags.any + + def isDate(self): + return self.tag() == IDLType.Tags.date + + def isObject(self): + return self.tag() == IDLType.Tags.object + + def isPromise(self): + return False + + def isComplete(self): + return True + + def includesRestrictedFloat(self): + return False + + def isFloat(self): + return False + + def isUnrestricted(self): + # Should only call this on float types + assert self.isFloat() + + def isSerializable(self): + return False + + def tag(self): + assert False # Override me! + + def treatNonCallableAsNull(self): + assert self.tag() == IDLType.Tags.callback + return self.nullable() and self.inner._treatNonCallableAsNull + + def treatNonObjectAsNull(self): + assert self.tag() == IDLType.Tags.callback + return self.nullable() and self.inner._treatNonObjectAsNull + + def addExtendedAttributes(self, attrs): + assert len(attrs) == 0 + + def resolveType(self, parentScope): + pass + + def unroll(self): + return self + + def isDistinguishableFrom(self, other): + raise TypeError("Can't tell whether a generic type is or is not " + "distinguishable from other things") + +class IDLUnresolvedType(IDLType): + """ + Unresolved types are interface types + """ + + def __init__(self, location, name): + IDLType.__init__(self, location, name) + + def isComplete(self): + return False + + def complete(self, scope): + obj = None + try: + obj = scope._lookupIdentifier(self.name) + except: + raise WebIDLError("Unresolved type '%s'." % self.name, + [self.location]) + + assert obj + if obj.isType(): + # obj itself might not be complete; deal with that. + assert obj != self + if not obj.isComplete(): + obj = obj.complete(scope) + return obj + + name = self.name.resolve(scope, None) + return IDLWrapperType(self.location, obj) + + def isDistinguishableFrom(self, other): + raise TypeError("Can't tell whether an unresolved type is or is not " + "distinguishable from other things") + +class IDLNullableType(IDLType): + def __init__(self, location, innerType): + assert not innerType.isVoid() + assert not innerType == BuiltinTypes[IDLBuiltinType.Types.any] + + IDLType.__init__(self, location, innerType.name) + self.inner = innerType + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLNullableType) and self.inner == other.inner + + def __str__(self): + return self.inner.__str__() + "OrNull" + + def nullable(self): + return True + + def isCallback(self): + return self.inner.isCallback() + + def isPrimitive(self): + return self.inner.isPrimitive() + + def isBoolean(self): + return self.inner.isBoolean() + + def isNumeric(self): + return self.inner.isNumeric() + + def isString(self): + return self.inner.isString() + + def isByteString(self): + return self.inner.isByteString() + + def isDOMString(self): + return self.inner.isDOMString() + + def isFloat(self): + return self.inner.isFloat() + + def isUnrestricted(self): + return self.inner.isUnrestricted() + + def includesRestrictedFloat(self): + return self.inner.includesRestrictedFloat() + + def isInteger(self): + return self.inner.isInteger() + + def isVoid(self): + return False + + def isSequence(self): + return self.inner.isSequence() + + def isArray(self): + return self.inner.isArray() + + def isArrayBuffer(self): + return self.inner.isArrayBuffer() + + def isArrayBufferView(self): + return self.inner.isArrayBufferView() + + def isTypedArray(self): + return self.inner.isTypedArray() + + def isDictionary(self): + return self.inner.isDictionary() + + def isInterface(self): + return self.inner.isInterface() + + def isCallbackInterface(self): + return self.inner.isCallbackInterface() + + def isNonCallbackInterface(self): + return self.inner.isNonCallbackInterface() + + def isEnum(self): + return self.inner.isEnum() + + def isUnion(self): + return self.inner.isUnion() + + def isSerializable(self): + return self.inner.isSerializable() + + def tag(self): + return self.inner.tag() + + def resolveType(self, parentScope): + assert isinstance(parentScope, IDLScope) + self.inner.resolveType(parentScope) + + def isComplete(self): + return self.inner.isComplete() + + def complete(self, scope): + self.inner = self.inner.complete(scope) + if self.inner.nullable(): + raise WebIDLError("The inner type of a nullable type must not be " + "a nullable type", + [self.location, self.inner.location]) + if self.inner.isUnion(): + if self.inner.hasNullableType: + raise WebIDLError("The inner type of a nullable type must not " + "be a union type that itself has a nullable " + "type as a member type", [self.location]) + + self.name = self.inner.name + return self + + def unroll(self): + return self.inner.unroll() + + def isDistinguishableFrom(self, other): + if (other.nullable() or (other.isUnion() and other.hasNullableType) or + other.isDictionary()): + # Can't tell which type null should become + return False + return self.inner.isDistinguishableFrom(other) + + def _getDependentObjects(self): + return self.inner._getDependentObjects() + +class IDLSequenceType(IDLType): + def __init__(self, location, parameterType): + assert not parameterType.isVoid() + + IDLType.__init__(self, location, parameterType.name) + self.inner = parameterType + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLSequenceType) and self.inner == other.inner + + def __str__(self): + return self.inner.__str__() + "Sequence" + + def nullable(self): + return False + + def isPrimitive(self): + return False; + + def isString(self): + return False; + + def isByteString(self): + return False + + def isDOMString(self): + return False + + def isVoid(self): + return False + + def isSequence(self): + return True + + def isArray(self): + return False + + def isDictionary(self): + return False + + def isInterface(self): + return False + + def isEnum(self): + return False + + def isSerializable(self): + return self.inner.isSerializable() + + def includesRestrictedFloat(self): + return self.inner.includesRestrictedFloat() + + def tag(self): + return IDLType.Tags.sequence + + def resolveType(self, parentScope): + assert isinstance(parentScope, IDLScope) + self.inner.resolveType(parentScope) + + def isComplete(self): + return self.inner.isComplete() + + def complete(self, scope): + self.inner = self.inner.complete(scope) + self.name = self.inner.name + return self + + def unroll(self): + return self.inner.unroll() + + def isDistinguishableFrom(self, other): + if other.isUnion(): + # Just forward to the union; it'll deal + return other.isDistinguishableFrom(self) + return (other.isPrimitive() or other.isString() or other.isEnum() or + other.isDate() or other.isNonCallbackInterface()) + + def _getDependentObjects(self): + return self.inner._getDependentObjects() + +class IDLUnionType(IDLType): + def __init__(self, location, memberTypes): + IDLType.__init__(self, location, "") + self.memberTypes = memberTypes + self.hasNullableType = False + self.hasDictionaryType = False + self.flatMemberTypes = None + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLUnionType) and self.memberTypes == other.memberTypes + + def isVoid(self): + return False + + def isUnion(self): + return True + + def isSerializable(self): + return all(m.isSerializable() for m in self.memberTypes) + + def includesRestrictedFloat(self): + return any(t.includesRestrictedFloat() for t in self.memberTypes) + + def tag(self): + return IDLType.Tags.union + + def resolveType(self, parentScope): + assert isinstance(parentScope, IDLScope) + for t in self.memberTypes: + t.resolveType(parentScope) + + def isComplete(self): + return self.flatMemberTypes is not None + + def complete(self, scope): + def typeName(type): + if isinstance(type, IDLNullableType): + return typeName(type.inner) + "OrNull" + if isinstance(type, IDLWrapperType): + return typeName(type._identifier.object()) + if isinstance(type, IDLObjectWithIdentifier): + return typeName(type.identifier) + if isinstance(type, IDLType) and (type.isArray() or type.isSequence()): + return str(type) + return type.name + + for (i, type) in enumerate(self.memberTypes): + if not type.isComplete(): + self.memberTypes[i] = type.complete(scope) + + self.name = "Or".join(typeName(type) for type in self.memberTypes) + self.flatMemberTypes = list(self.memberTypes) + i = 0 + while i < len(self.flatMemberTypes): + if self.flatMemberTypes[i].nullable(): + if self.hasNullableType: + raise WebIDLError("Can't have more than one nullable types in a union", + [nullableType.location, self.flatMemberTypes[i].location]) + if self.hasDictionaryType: + raise WebIDLError("Can't have a nullable type and a " + "dictionary type in a union", + [dictionaryType.location, + self.flatMemberTypes[i].location]) + self.hasNullableType = True + nullableType = self.flatMemberTypes[i] + self.flatMemberTypes[i] = self.flatMemberTypes[i].inner + continue + if self.flatMemberTypes[i].isDictionary(): + if self.hasNullableType: + raise WebIDLError("Can't have a nullable type and a " + "dictionary type in a union", + [nullableType.location, + self.flatMemberTypes[i].location]) + self.hasDictionaryType = True + dictionaryType = self.flatMemberTypes[i] + elif self.flatMemberTypes[i].isUnion(): + self.flatMemberTypes[i:i + 1] = self.flatMemberTypes[i].memberTypes + continue + i += 1 + + for (i, t) in enumerate(self.flatMemberTypes[:-1]): + for u in self.flatMemberTypes[i + 1:]: + if not t.isDistinguishableFrom(u): + raise WebIDLError("Flat member types of a union should be " + "distinguishable, " + str(t) + " is not " + "distinguishable from " + str(u), + [self.location, t.location, u.location]) + + return self + + def isDistinguishableFrom(self, other): + if self.hasNullableType and other.nullable(): + # Can't tell which type null should become + return False + if other.isUnion(): + otherTypes = other.unroll().memberTypes + else: + otherTypes = [other] + # For every type in otherTypes, check that it's distinguishable from + # every type in our types + for u in otherTypes: + if any(not t.isDistinguishableFrom(u) for t in self.memberTypes): + return False + return True + + def _getDependentObjects(self): + return set(self.memberTypes) + +class IDLArrayType(IDLType): + def __init__(self, location, parameterType): + assert not parameterType.isVoid() + if parameterType.isSequence(): + raise WebIDLError("Array type cannot parameterize over a sequence type", + [location]) + if parameterType.isDictionary(): + raise WebIDLError("Array type cannot parameterize over a dictionary type", + [location]) + + IDLType.__init__(self, location, parameterType.name) + self.inner = parameterType + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLArrayType) and self.inner == other.inner + + def __str__(self): + return self.inner.__str__() + "Array" + + def nullable(self): + return False + + def isPrimitive(self): + return False + + def isString(self): + return False + + def isByteString(self): + return False + + def isDOMString(self): + return False + + def isVoid(self): + return False + + def isSequence(self): + assert not self.inner.isSequence() + return False + + def isArray(self): + return True + + def isDictionary(self): + assert not self.inner.isDictionary() + return False + + def isInterface(self): + return False + + def isEnum(self): + return False + + def tag(self): + return IDLType.Tags.array + + def resolveType(self, parentScope): + assert isinstance(parentScope, IDLScope) + self.inner.resolveType(parentScope) + + def isComplete(self): + return self.inner.isComplete() + + def complete(self, scope): + self.inner = self.inner.complete(scope) + self.name = self.inner.name + + if self.inner.isDictionary(): + raise WebIDLError("Array type must not contain " + "dictionary as element type.", + [self.inner.location]) + + assert not self.inner.isSequence() + + return self + + def unroll(self): + return self.inner.unroll() + + def isDistinguishableFrom(self, other): + if other.isUnion(): + # Just forward to the union; it'll deal + return other.isDistinguishableFrom(self) + return (other.isPrimitive() or other.isString() or other.isEnum() or + other.isDate() or other.isNonCallbackInterface()) + + def _getDependentObjects(self): + return self.inner._getDependentObjects() + +class IDLTypedefType(IDLType, IDLObjectWithIdentifier): + def __init__(self, location, innerType, name): + IDLType.__init__(self, location, innerType.name) + + identifier = IDLUnresolvedIdentifier(location, name) + + IDLObjectWithIdentifier.__init__(self, location, None, identifier) + + self.inner = innerType + self.name = name + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLTypedefType) and self.inner == other.inner + + def __str__(self): + return self.identifier.name + + def nullable(self): + return self.inner.nullable() + + def isPrimitive(self): + return self.inner.isPrimitive() + + def isBoolean(self): + return self.inner.isBoolean() + + def isNumeric(self): + return self.inner.isNumeric() + + def isString(self): + return self.inner.isString() + + def isByteString(self): + return self.inner.isByteString() + + def isDOMString(self): + return self.inner.isDOMString() + + def isVoid(self): + return self.inner.isVoid() + + def isSequence(self): + return self.inner.isSequence() + + def isArray(self): + return self.inner.isArray() + + def isDictionary(self): + return self.inner.isDictionary() + + def isArrayBuffer(self): + return self.inner.isArrayBuffer() + + def isArrayBufferView(self): + return self.inner.isArrayBufferView() + + def isTypedArray(self): + return self.inner.isTypedArray() + + def isInterface(self): + return self.inner.isInterface() + + def isCallbackInterface(self): + return self.inner.isCallbackInterface() + + def isNonCallbackInterface(self): + return self.inner.isNonCallbackInterface() + + def isComplete(self): + return False + + def complete(self, parentScope): + if not self.inner.isComplete(): + self.inner = self.inner.complete(parentScope) + assert self.inner.isComplete() + return self.inner + + def finish(self, parentScope): + # Maybe the IDLObjectWithIdentifier for the typedef should be + # a separate thing from the type? If that happens, we can + # remove some hackery around avoiding isInterface() in + # Configuration.py. + self.complete(parentScope) + + def validate(self): + pass + + # Do we need a resolveType impl? I don't think it's particularly useful.... + + def tag(self): + return self.inner.tag() + + def unroll(self): + return self.inner.unroll() + + def isDistinguishableFrom(self, other): + return self.inner.isDistinguishableFrom(other) + + def _getDependentObjects(self): + return self.inner._getDependentObjects() + +class IDLWrapperType(IDLType): + def __init__(self, location, inner): + IDLType.__init__(self, location, inner.identifier.name) + self.inner = inner + self._identifier = inner.identifier + self.builtin = False + + def __eq__(self, other): + return isinstance(other, IDLWrapperType) and \ + self._identifier == other._identifier and \ + self.builtin == other.builtin + + def __str__(self): + return str(self.name) + " (Wrapper)" + + def nullable(self): + return False + + def isPrimitive(self): + return False + + def isString(self): + return False + + def isByteString(self): + return False + + def isDOMString(self): + return False + + def isVoid(self): + return False + + def isSequence(self): + return False + + def isArray(self): + return False + + def isDictionary(self): + return isinstance(self.inner, IDLDictionary) + + def isInterface(self): + return isinstance(self.inner, IDLInterface) or \ + isinstance(self.inner, IDLExternalInterface) + + def isCallbackInterface(self): + return self.isInterface() and self.inner.isCallback() + + def isNonCallbackInterface(self): + return self.isInterface() and not self.inner.isCallback() + + def isEnum(self): + return isinstance(self.inner, IDLEnum) + + def isPromise(self): + return isinstance(self.inner, IDLInterface) and \ + self.inner.identifier.name == "Promise" + + def isSerializable(self): + if self.isInterface(): + if self.inner.isExternal(): + return False + return any(m.isMethod() and m.isJsonifier() for m in self.inner.members) + elif self.isEnum(): + return True + elif self.isDictionary(): + return all(m.type.isSerializable() for m in self.inner.members) + else: + raise WebIDLError("IDLWrapperType wraps type %s that we don't know if " + "is serializable" % type(self.inner), [self.location]) + + def resolveType(self, parentScope): + assert isinstance(parentScope, IDLScope) + self.inner.resolve(parentScope) + + def isComplete(self): + return True + + def tag(self): + if self.isInterface(): + return IDLType.Tags.interface + elif self.isEnum(): + return IDLType.Tags.enum + elif self.isDictionary(): + return IDLType.Tags.dictionary + else: + assert False + + def isDistinguishableFrom(self, other): + if other.isUnion(): + # Just forward to the union; it'll deal + return other.isDistinguishableFrom(self) + assert self.isInterface() or self.isEnum() or self.isDictionary() + if self.isEnum(): + return (other.isPrimitive() or other.isInterface() or other.isObject() or + other.isCallback() or other.isDictionary() or + other.isSequence() or other.isArray() or + other.isDate()) + if self.isDictionary() and other.nullable(): + return False + if other.isPrimitive() or other.isString() or other.isEnum() or other.isDate(): + return True + if self.isDictionary(): + return other.isNonCallbackInterface() + + assert self.isInterface() + if other.isInterface(): + if other.isSpiderMonkeyInterface(): + # Just let |other| handle things + return other.isDistinguishableFrom(self) + assert self.isGeckoInterface() and other.isGeckoInterface() + if self.inner.isExternal() or other.unroll().inner.isExternal(): + return self != other + return (len(self.inner.interfacesBasedOnSelf & + other.unroll().inner.interfacesBasedOnSelf) == 0 and + (self.isNonCallbackInterface() or + other.isNonCallbackInterface())) + if (other.isDictionary() or other.isCallback() or + other.isSequence() or other.isArray()): + return self.isNonCallbackInterface() + + # Not much else |other| can be + assert other.isObject() + return False + + def _getDependentObjects(self): + # NB: The codegen for an interface type depends on + # a) That the identifier is in fact an interface (as opposed to + # a dictionary or something else). + # b) The native type of the interface. + # If we depend on the interface object we will also depend on + # anything the interface depends on which is undesirable. We + # considered implementing a dependency just on the interface type + # file, but then every modification to an interface would cause this + # to be regenerated which is still undesirable. We decided not to + # depend on anything, reasoning that: + # 1) Changing the concrete type of the interface requires modifying + # Bindings.conf, which is still a global dependency. + # 2) Changing an interface to a dictionary (or vice versa) with the + # same identifier should be incredibly rare. + return set() + +class IDLBuiltinType(IDLType): + + Types = enum( + # The integer types + 'byte', + 'octet', + 'short', + 'unsigned_short', + 'long', + 'unsigned_long', + 'long_long', + 'unsigned_long_long', + # Additional primitive types + 'boolean', + 'unrestricted_float', + 'float', + 'unrestricted_double', + # IMPORTANT: "double" must be the last primitive type listed + 'double', + # Other types + 'any', + 'domstring', + 'bytestring', + 'object', + 'date', + 'void', + # Funny stuff + 'ArrayBuffer', + 'ArrayBufferView', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ) + + TagLookup = { + Types.byte: IDLType.Tags.int8, + Types.octet: IDLType.Tags.uint8, + Types.short: IDLType.Tags.int16, + Types.unsigned_short: IDLType.Tags.uint16, + Types.long: IDLType.Tags.int32, + Types.unsigned_long: IDLType.Tags.uint32, + Types.long_long: IDLType.Tags.int64, + Types.unsigned_long_long: IDLType.Tags.uint64, + Types.boolean: IDLType.Tags.bool, + Types.unrestricted_float: IDLType.Tags.unrestricted_float, + Types.float: IDLType.Tags.float, + Types.unrestricted_double: IDLType.Tags.unrestricted_double, + Types.double: IDLType.Tags.double, + Types.any: IDLType.Tags.any, + Types.domstring: IDLType.Tags.domstring, + Types.bytestring: IDLType.Tags.bytestring, + Types.object: IDLType.Tags.object, + Types.date: IDLType.Tags.date, + Types.void: IDLType.Tags.void, + Types.ArrayBuffer: IDLType.Tags.interface, + Types.ArrayBufferView: IDLType.Tags.interface, + Types.Int8Array: IDLType.Tags.interface, + Types.Uint8Array: IDLType.Tags.interface, + Types.Uint8ClampedArray: IDLType.Tags.interface, + Types.Int16Array: IDLType.Tags.interface, + Types.Uint16Array: IDLType.Tags.interface, + Types.Int32Array: IDLType.Tags.interface, + Types.Uint32Array: IDLType.Tags.interface, + Types.Float32Array: IDLType.Tags.interface, + Types.Float64Array: IDLType.Tags.interface + } + + def __init__(self, location, name, type): + IDLType.__init__(self, location, name) + self.builtin = True + self._typeTag = type + + def isPrimitive(self): + return self._typeTag <= IDLBuiltinType.Types.double + + def isBoolean(self): + return self._typeTag == IDLBuiltinType.Types.boolean + + def isNumeric(self): + return self.isPrimitive() and not self.isBoolean() + + def isString(self): + return self._typeTag == IDLBuiltinType.Types.domstring or \ + self._typeTag == IDLBuiltinType.Types.bytestring + + def isByteString(self): + return self._typeTag == IDLBuiltinType.Types.bytestring + + def isDOMString(self): + return self._typeTag == IDLBuiltinType.Types.domstring + + def isInteger(self): + return self._typeTag <= IDLBuiltinType.Types.unsigned_long_long + + def isArrayBuffer(self): + return self._typeTag == IDLBuiltinType.Types.ArrayBuffer + + def isArrayBufferView(self): + return self._typeTag == IDLBuiltinType.Types.ArrayBufferView + + def isTypedArray(self): + return self._typeTag >= IDLBuiltinType.Types.Int8Array and \ + self._typeTag <= IDLBuiltinType.Types.Float64Array + + def isInterface(self): + # TypedArray things are interface types per the TypedArray spec, + # but we handle them as builtins because SpiderMonkey implements + # all of it internally. + return self.isArrayBuffer() or \ + self.isArrayBufferView() or \ + self.isTypedArray() + + def isNonCallbackInterface(self): + # All the interfaces we can be are non-callback + return self.isInterface() + + def isFloat(self): + return self._typeTag == IDLBuiltinType.Types.float or \ + self._typeTag == IDLBuiltinType.Types.double or \ + self._typeTag == IDLBuiltinType.Types.unrestricted_float or \ + self._typeTag == IDLBuiltinType.Types.unrestricted_double + + def isUnrestricted(self): + assert self.isFloat() + return self._typeTag == IDLBuiltinType.Types.unrestricted_float or \ + self._typeTag == IDLBuiltinType.Types.unrestricted_double + + def isSerializable(self): + return self.isPrimitive() or self.isDOMString() or self.isDate() + + def includesRestrictedFloat(self): + return self.isFloat() and not self.isUnrestricted() + + def tag(self): + return IDLBuiltinType.TagLookup[self._typeTag] + + def isDistinguishableFrom(self, other): + if other.isUnion(): + # Just forward to the union; it'll deal + return other.isDistinguishableFrom(self) + if self.isBoolean(): + return (other.isNumeric() or other.isString() or other.isEnum() or + other.isInterface() or other.isObject() or + other.isCallback() or other.isDictionary() or + other.isSequence() or other.isArray() or + other.isDate()) + if self.isNumeric(): + return (other.isBoolean() or other.isString() or other.isEnum() or + other.isInterface() or other.isObject() or + other.isCallback() or other.isDictionary() or + other.isSequence() or other.isArray() or + other.isDate()) + if self.isString(): + return (other.isPrimitive() or other.isInterface() or + other.isObject() or + other.isCallback() or other.isDictionary() or + other.isSequence() or other.isArray() or + other.isDate()) + if self.isAny(): + # Can't tell "any" apart from anything + return False + if self.isObject(): + return other.isPrimitive() or other.isString() or other.isEnum() + if self.isDate(): + return (other.isPrimitive() or other.isString() or other.isEnum() or + other.isInterface() or other.isCallback() or + other.isDictionary() or other.isSequence() or + other.isArray()) + if self.isVoid(): + return not other.isVoid() + # Not much else we could be! + assert self.isSpiderMonkeyInterface() + # Like interfaces, but we know we're not a callback + return (other.isPrimitive() or other.isString() or other.isEnum() or + other.isCallback() or other.isDictionary() or + other.isSequence() or other.isArray() or other.isDate() or + (other.isInterface() and ( + # ArrayBuffer is distinguishable from everything + # that's not an ArrayBuffer or a callback interface + (self.isArrayBuffer() and not other.isArrayBuffer()) or + # ArrayBufferView is distinguishable from everything + # that's not an ArrayBufferView or typed array. + (self.isArrayBufferView() and not other.isArrayBufferView() and + not other.isTypedArray()) or + # Typed arrays are distinguishable from everything + # except ArrayBufferView and the same type of typed + # array + (self.isTypedArray() and not other.isArrayBufferView() and not + (other.isTypedArray() and other.name == self.name))))) + + def _getDependentObjects(self): + return set() + +BuiltinTypes = { + IDLBuiltinType.Types.byte: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Byte", + IDLBuiltinType.Types.byte), + IDLBuiltinType.Types.octet: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Octet", + IDLBuiltinType.Types.octet), + IDLBuiltinType.Types.short: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Short", + IDLBuiltinType.Types.short), + IDLBuiltinType.Types.unsigned_short: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedShort", + IDLBuiltinType.Types.unsigned_short), + IDLBuiltinType.Types.long: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Long", + IDLBuiltinType.Types.long), + IDLBuiltinType.Types.unsigned_long: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLong", + IDLBuiltinType.Types.unsigned_long), + IDLBuiltinType.Types.long_long: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "LongLong", + IDLBuiltinType.Types.long_long), + IDLBuiltinType.Types.unsigned_long_long: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnsignedLongLong", + IDLBuiltinType.Types.unsigned_long_long), + IDLBuiltinType.Types.boolean: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Boolean", + IDLBuiltinType.Types.boolean), + IDLBuiltinType.Types.float: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float", + IDLBuiltinType.Types.float), + IDLBuiltinType.Types.unrestricted_float: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedFloat", + IDLBuiltinType.Types.unrestricted_float), + IDLBuiltinType.Types.double: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Double", + IDLBuiltinType.Types.double), + IDLBuiltinType.Types.unrestricted_double: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "UnrestrictedDouble", + IDLBuiltinType.Types.unrestricted_double), + IDLBuiltinType.Types.any: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Any", + IDLBuiltinType.Types.any), + IDLBuiltinType.Types.domstring: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "String", + IDLBuiltinType.Types.domstring), + IDLBuiltinType.Types.bytestring: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString", + IDLBuiltinType.Types.bytestring), + IDLBuiltinType.Types.object: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object", + IDLBuiltinType.Types.object), + IDLBuiltinType.Types.date: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Date", + IDLBuiltinType.Types.date), + IDLBuiltinType.Types.void: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Void", + IDLBuiltinType.Types.void), + IDLBuiltinType.Types.ArrayBuffer: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBuffer", + IDLBuiltinType.Types.ArrayBuffer), + IDLBuiltinType.Types.ArrayBufferView: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "ArrayBufferView", + IDLBuiltinType.Types.ArrayBufferView), + IDLBuiltinType.Types.Int8Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int8Array", + IDLBuiltinType.Types.Int8Array), + IDLBuiltinType.Types.Uint8Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8Array", + IDLBuiltinType.Types.Uint8Array), + IDLBuiltinType.Types.Uint8ClampedArray: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint8ClampedArray", + IDLBuiltinType.Types.Uint8ClampedArray), + IDLBuiltinType.Types.Int16Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int16Array", + IDLBuiltinType.Types.Int16Array), + IDLBuiltinType.Types.Uint16Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint16Array", + IDLBuiltinType.Types.Uint16Array), + IDLBuiltinType.Types.Int32Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Int32Array", + IDLBuiltinType.Types.Int32Array), + IDLBuiltinType.Types.Uint32Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Uint32Array", + IDLBuiltinType.Types.Uint32Array), + IDLBuiltinType.Types.Float32Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float32Array", + IDLBuiltinType.Types.Float32Array), + IDLBuiltinType.Types.Float64Array: + IDLBuiltinType(BuiltinLocation("<builtin type>"), "Float64Array", + IDLBuiltinType.Types.Float64Array) + } + + +integerTypeSizes = { + IDLBuiltinType.Types.byte: (-128, 127), + IDLBuiltinType.Types.octet: (0, 255), + IDLBuiltinType.Types.short: (-32768, 32767), + IDLBuiltinType.Types.unsigned_short: (0, 65535), + IDLBuiltinType.Types.long: (-2147483648, 2147483647), + IDLBuiltinType.Types.unsigned_long: (0, 4294967295), + IDLBuiltinType.Types.long_long: (-9223372036854775808, + 9223372036854775807), + IDLBuiltinType.Types.unsigned_long_long: (0, 18446744073709551615) + } + +def matchIntegerValueToType(value): + for type, extremes in integerTypeSizes.items(): + (min, max) = extremes + if value <= max and value >= min: + return BuiltinTypes[type] + + return None + +class IDLValue(IDLObject): + def __init__(self, location, type, value): + IDLObject.__init__(self, location) + self.type = type + assert isinstance(type, IDLType) + + self.value = value + + def coerceToType(self, type, location): + if type == self.type: + return self # Nothing to do + + # We first check for unions to ensure that even if the union is nullable + # we end up with the right flat member type, not the union's type. + if type.isUnion(): + # We use the flat member types here, because if we have a nullable + # member type, or a nested union, we want the type the value + # actually coerces to, not the nullable or nested union type. + for subtype in type.unroll().flatMemberTypes: + try: + coercedValue = self.coerceToType(subtype, location) + # Create a new IDLValue to make sure that we have the + # correct float/double type. This is necessary because we + # use the value's type when it is a default value of a + # union, and the union cares about the exact float type. + return IDLValue(self.location, subtype, coercedValue.value) + except: + pass + # If the type allows null, rerun this matching on the inner type, except + # nullable enums. We handle those specially, because we want our + # default string values to stay strings even when assigned to a nullable + # enum. + elif type.nullable() and not type.isEnum(): + innerValue = self.coerceToType(type.inner, location) + return IDLValue(self.location, type, innerValue.value) + + elif self.type.isInteger() and type.isInteger(): + # We're both integer types. See if we fit. + + (min, max) = integerTypeSizes[type._typeTag] + if self.value <= max and self.value >= min: + # Promote + return IDLValue(self.location, type, self.value) + else: + raise WebIDLError("Value %s is out of range for type %s." % + (self.value, type), [location]) + elif self.type.isInteger() and type.isFloat(): + # Convert an integer literal into float + if -2**24 <= self.value <= 2**24: + floatType = BuiltinTypes[IDLBuiltinType.Types.float] + return IDLValue(self.location, floatType, float(self.value)) + else: + raise WebIDLError("Converting value %s to %s will lose precision." % + (self.value, type), [location]) + elif self.type.isString() and type.isEnum(): + # Just keep our string, but make sure it's a valid value for this enum + enum = type.unroll().inner + if self.value not in enum.values(): + raise WebIDLError("'%s' is not a valid default value for enum %s" + % (self.value, enum.identifier.name), + [location, enum.location]) + return self + elif self.type.isFloat() and type.isFloat(): + if (not type.isUnrestricted() and + (self.value == float("inf") or self.value == float("-inf") or + math.isnan(self.value))): + raise WebIDLError("Trying to convert unrestricted value %s to non-unrestricted" + % self.value, [location]); + return self + raise WebIDLError("Cannot coerce type %s to type %s." % + (self.type, type), [location]) + + def _getDependentObjects(self): + return set() + +class IDLNullValue(IDLObject): + def __init__(self, location): + IDLObject.__init__(self, location) + self.type = None + self.value = None + + def coerceToType(self, type, location): + if (not isinstance(type, IDLNullableType) and + not (type.isUnion() and type.hasNullableType) and + not (type.isUnion() and type.hasDictionaryType) and + not type.isDictionary() and + not type.isAny()): + raise WebIDLError("Cannot coerce null value to type %s." % type, + [location]) + + nullValue = IDLNullValue(self.location) + if type.isUnion() and not type.nullable() and type.hasDictionaryType: + # We're actually a default value for the union's dictionary member. + # Use its type. + for t in type.flatMemberTypes: + if t.isDictionary(): + nullValue.type = t + return nullValue + nullValue.type = type + return nullValue + + def _getDependentObjects(self): + return set() + +class IDLUndefinedValue(IDLObject): + def __init__(self, location): + IDLObject.__init__(self, location) + self.type = None + self.value = None + + def coerceToType(self, type, location): + if not type.isAny(): + raise WebIDLError("Cannot coerce undefined value to type %s." % type, + [location]) + + undefinedValue = IDLUndefinedValue(self.location) + undefinedValue.type = type + return undefinedValue + + def _getDependentObjects(self): + return set() + +class IDLInterfaceMember(IDLObjectWithIdentifier): + + Tags = enum( + 'Const', + 'Attr', + 'Method' + ) + + Special = enum( + 'Static', + 'Stringifier' + ) + + def __init__(self, location, identifier, tag): + IDLObjectWithIdentifier.__init__(self, location, None, identifier) + self.tag = tag + self._extendedAttrDict = {} + + def isMethod(self): + return self.tag == IDLInterfaceMember.Tags.Method + + def isAttr(self): + return self.tag == IDLInterfaceMember.Tags.Attr + + def isConst(self): + return self.tag == IDLInterfaceMember.Tags.Const + + def addExtendedAttributes(self, attrs): + for attr in attrs: + self.handleExtendedAttribute(attr) + attrlist = attr.listValue() + self._extendedAttrDict[attr.identifier()] = attrlist if len(attrlist) else True + + def handleExtendedAttribute(self, attr): + pass + + def getExtendedAttribute(self, name): + return self._extendedAttrDict.get(name, None) + +class IDLConst(IDLInterfaceMember): + def __init__(self, location, identifier, type, value): + IDLInterfaceMember.__init__(self, location, identifier, + IDLInterfaceMember.Tags.Const) + + assert isinstance(type, IDLType) + if type.isDictionary(): + raise WebIDLError("A constant cannot be of a dictionary type", + [self.location]) + self.type = type + self.value = value + + if identifier.name == "prototype": + raise WebIDLError("The identifier of a constant must not be 'prototype'", + [location]) + + def __str__(self): + return "'%s' const '%s'" % (self.type, self.identifier) + + def finish(self, scope): + if not self.type.isComplete(): + type = self.type.complete(scope) + if not type.isPrimitive() and not type.isString(): + locations = [self.type.location, type.location] + try: + locations.append(type.inner.location) + except: + pass + raise WebIDLError("Incorrect type for constant", locations) + self.type = type + + # The value might not match the type + coercedValue = self.value.coerceToType(self.type, self.location) + assert coercedValue + + self.value = coercedValue + + def validate(self): + pass + + def _getDependentObjects(self): + return set([self.type, self.value]) + +class IDLAttribute(IDLInterfaceMember): + def __init__(self, location, identifier, type, readonly, inherit=False, + static=False, stringifier=False): + IDLInterfaceMember.__init__(self, location, identifier, + IDLInterfaceMember.Tags.Attr) + + assert isinstance(type, IDLType) + self.type = type + self.readonly = readonly + self.inherit = inherit + self.static = static + self.lenientThis = False + self._unforgeable = False + self.stringifier = stringifier + self.enforceRange = False + self.clamp = False + self.slotIndex = None + + if static and identifier.name == "prototype": + raise WebIDLError("The identifier of a static attribute must not be 'prototype'", + [location]) + + if readonly and inherit: + raise WebIDLError("An attribute cannot be both 'readonly' and 'inherit'", + [self.location]) + + def isStatic(self): + return self.static + + def __str__(self): + return "'%s' attribute '%s'" % (self.type, self.identifier) + + def finish(self, scope): + if not self.type.isComplete(): + t = self.type.complete(scope) + + assert not isinstance(t, IDLUnresolvedType) + assert not isinstance(t, IDLTypedefType) + assert not isinstance(t.name, IDLUnresolvedIdentifier) + self.type = t + + if self.type.isDictionary() and not self.getExtendedAttribute("Cached"): + raise WebIDLError("An attribute cannot be of a dictionary type", + [self.location]) + if self.type.isSequence() and not self.getExtendedAttribute("Cached"): + raise WebIDLError("A non-cached attribute cannot be of a sequence " + "type", [self.location]) + if self.type.isUnion(): + for f in self.type.unroll().flatMemberTypes: + if f.isDictionary(): + raise WebIDLError("An attribute cannot be of a union " + "type if one of its member types (or " + "one of its member types's member " + "types, and so on) is a dictionary " + "type", [self.location, f.location]) + if f.isSequence(): + raise WebIDLError("An attribute cannot be of a union " + "type if one of its member types (or " + "one of its member types's member " + "types, and so on) is a sequence " + "type", [self.location, f.location]) + if not self.type.isInterface() and self.getExtendedAttribute("PutForwards"): + raise WebIDLError("An attribute with [PutForwards] must have an " + "interface type as its type", [self.location]) + + if not self.type.isInterface() and self.getExtendedAttribute("SameObject"): + raise WebIDLError("An attribute with [SameObject] must have an " + "interface type as its type", [self.location]) + + def validate(self): + if ((self.getExtendedAttribute("Cached") or + self.getExtendedAttribute("StoreInSlot")) and + not self.getExtendedAttribute("Constant") and + not self.getExtendedAttribute("Pure")): + raise WebIDLError("Cached attributes and attributes stored in " + "slots must be constant or pure, since the " + "getter won't always be called.", + [self.location]) + if self.getExtendedAttribute("Frozen"): + if not self.type.isSequence() and not self.type.isDictionary(): + raise WebIDLError("[Frozen] is only allowed on sequence-valued " + "and dictionary-valued attributes", + [self.location]) + + def handleExtendedAttribute(self, attr): + identifier = attr.identifier() + if identifier == "SetterThrows" and self.readonly: + raise WebIDLError("Readonly attributes must not be flagged as " + "[SetterThrows]", + [self.location]) + elif (((identifier == "Throws" or identifier == "GetterThrows") and + self.getExtendedAttribute("StoreInSlot")) or + (identifier == "StoreInSlot" and + (self.getExtendedAttribute("Throws") or + self.getExtendedAttribute("GetterThrows")))): + raise WebIDLError("Throwing things can't be [Pure] or [Constant] " + "or [SameObject] or [StoreInSlot]", + [attr.location]) + elif identifier == "LenientThis": + if not attr.noArguments(): + raise WebIDLError("[LenientThis] must take no arguments", + [attr.location]) + if self.isStatic(): + raise WebIDLError("[LenientThis] is only allowed on non-static " + "attributes", [attr.location, self.location]) + if self.getExtendedAttribute("CrossOriginReadable"): + raise WebIDLError("[LenientThis] is not allowed in combination " + "with [CrossOriginReadable]", + [attr.location, self.location]) + if self.getExtendedAttribute("CrossOriginWritable"): + raise WebIDLError("[LenientThis] is not allowed in combination " + "with [CrossOriginWritable]", + [attr.location, self.location]) + self.lenientThis = True + elif identifier == "Unforgeable": + if not self.readonly: + raise WebIDLError("[Unforgeable] is only allowed on readonly " + "attributes", [attr.location, self.location]) + if self.isStatic(): + raise WebIDLError("[Unforgeable] is only allowed on non-static " + "attributes", [attr.location, self.location]) + self._unforgeable = True + elif identifier == "SameObject" and not self.readonly: + raise WebIDLError("[SameObject] only allowed on readonly attributes", + [attr.location, self.location]) + elif identifier == "Constant" and not self.readonly: + raise WebIDLError("[Constant] only allowed on readonly attributes", + [attr.location, self.location]) + elif identifier == "PutForwards": + if not self.readonly: + raise WebIDLError("[PutForwards] is only allowed on readonly " + "attributes", [attr.location, self.location]) + if self.isStatic(): + raise WebIDLError("[PutForwards] is only allowed on non-static " + "attributes", [attr.location, self.location]) + if self.getExtendedAttribute("Replaceable") is not None: + raise WebIDLError("[PutForwards] and [Replaceable] can't both " + "appear on the same attribute", + [attr.location, self.location]) + if not attr.hasValue(): + raise WebIDLError("[PutForwards] takes an identifier", + [attr.location, self.location]) + elif identifier == "Replaceable": + if self.getExtendedAttribute("PutForwards") is not None: + raise WebIDLError("[PutForwards] and [Replaceable] can't both " + "appear on the same attribute", + [attr.location, self.location]) + elif identifier == "LenientFloat": + if self.readonly: + raise WebIDLError("[LenientFloat] used on a readonly attribute", + [attr.location, self.location]) + if not self.type.includesRestrictedFloat(): + raise WebIDLError("[LenientFloat] used on an attribute with a " + "non-restricted-float type", + [attr.location, self.location]) + elif identifier == "EnforceRange": + if self.readonly: + raise WebIDLError("[EnforceRange] used on a readonly attribute", + [attr.location, self.location]) + self.enforceRange = True + elif identifier == "Clamp": + if self.readonly: + raise WebIDLError("[Clamp] used on a readonly attribute", + [attr.location, self.location]) + self.clamp = True + elif identifier == "StoreInSlot": + if self.getExtendedAttribute("Cached"): + raise WebIDLError("[StoreInSlot] and [Cached] must not be " + "specified on the same attribute", + [attr.location, self.location]) + elif identifier == "Cached": + if self.getExtendedAttribute("StoreInSlot"): + raise WebIDLError("[Cached] and [StoreInSlot] must not be " + "specified on the same attribute", + [attr.location, self.location]) + elif (identifier == "CrossOriginReadable" or + identifier == "CrossOriginWritable"): + if not attr.noArguments(): + raise WebIDLError("[%s] must take no arguments" % identifier, + [attr.location]) + if self.isStatic(): + raise WebIDLError("[%s] is only allowed on non-static " + "attributes" % identifier, + [attr.location, self.location]) + if self.getExtendedAttribute("LenientThis"): + raise WebIDLError("[LenientThis] is not allowed in combination " + "with [%s]" % identifier, + [attr.location, self.location]) + elif (identifier == "Pref" or + identifier == "SetterThrows" or + identifier == "Pure" or + identifier == "Throws" or + identifier == "GetterThrows" or + identifier == "ChromeOnly" or + identifier == "SameObject" or + identifier == "Constant" or + identifier == "Func" or + identifier == "Frozen" or + identifier == "AvailableIn" or + identifier == "Const" or + identifier == "Value" or + identifier == "NewObject"): + # Known attributes that we don't need to do anything with here + pass + else: + raise WebIDLError("Unknown extended attribute %s on attribute" % identifier, + [attr.location]) + IDLInterfaceMember.handleExtendedAttribute(self, attr) + + def resolve(self, parentScope): + assert isinstance(parentScope, IDLScope) + self.type.resolveType(parentScope) + IDLObjectWithIdentifier.resolve(self, parentScope) + + def addExtendedAttributes(self, attrs): + attrs = self.checkForStringHandlingExtendedAttributes(attrs) + IDLInterfaceMember.addExtendedAttributes(self, attrs) + + def hasLenientThis(self): + return self.lenientThis + + def isUnforgeable(self): + return self._unforgeable + + def _getDependentObjects(self): + return set([self.type]) + +class IDLArgument(IDLObjectWithIdentifier): + def __init__(self, location, identifier, type, optional=False, defaultValue=None, variadic=False, dictionaryMember=False): + IDLObjectWithIdentifier.__init__(self, location, None, identifier) + + assert isinstance(type, IDLType) + self.type = type + + self.optional = optional + self.defaultValue = defaultValue + self.variadic = variadic + self.dictionaryMember = dictionaryMember + self._isComplete = False + self.enforceRange = False + self.clamp = False + self._allowTreatNonCallableAsNull = False + + self._extraAttributes = {} + + assert not variadic or optional + + def getExtendedAttribute(self, name): + return self._extraAttributes.get(name) + + def addExtendedAttributes(self, attrs): + attrs = self.checkForStringHandlingExtendedAttributes( + attrs, + isDictionaryMember=self.dictionaryMember, + isOptional=self.optional) + for attribute in attrs: + identifier = attribute.identifier() + if identifier == "Clamp": + if not attribute.noArguments(): + raise WebIDLError("[Clamp] must take no arguments", + [attribute.location]) + if self.enforceRange: + raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive", + [self.location]); + self.clamp = True + elif identifier == "EnforceRange": + if not attribute.noArguments(): + raise WebIDLError("[EnforceRange] must take no arguments", + [attribute.location]) + if self.clamp: + raise WebIDLError("[EnforceRange] and [Clamp] are mutually exclusive", + [self.location]); + self.enforceRange = True + elif identifier == "TreatNonCallableAsNull": + self._allowTreatNonCallableAsNull = True + elif identifier in ['Ref', 'Const']: + # ok in emscripten + self._extraAttributes[identifier] = True + else: + raise WebIDLError("Unhandled extended attribute on an argument", + [attribute.location]) + + def isComplete(self): + return self._isComplete + + def complete(self, scope): + if self._isComplete: + return + + self._isComplete = True + + if not self.type.isComplete(): + type = self.type.complete(scope) + assert not isinstance(type, IDLUnresolvedType) + assert not isinstance(type, IDLTypedefType) + assert not isinstance(type.name, IDLUnresolvedIdentifier) + self.type = type + + if ((self.type.isDictionary() or + self.type.isUnion() and self.type.unroll().hasDictionaryType) and + self.optional and not self.defaultValue): + # Default optional dictionaries to null, for simplicity, + # so the codegen doesn't have to special-case this. + self.defaultValue = IDLNullValue(self.location) + elif self.type.isAny(): + assert (self.defaultValue is None or + isinstance(self.defaultValue, IDLNullValue)) + # optional 'any' values always have a default value + if self.optional and not self.defaultValue and not self.variadic: + # Set the default value to undefined, for simplicity, so the + # codegen doesn't have to special-case this. + self.defaultValue = IDLUndefinedValue(self.location) + + # Now do the coercing thing; this needs to happen after the + # above creation of a default value. + if self.defaultValue: + self.defaultValue = self.defaultValue.coerceToType(self.type, + self.location) + assert self.defaultValue + + def allowTreatNonCallableAsNull(self): + return self._allowTreatNonCallableAsNull + + def _getDependentObjects(self): + deps = set([self.type]) + if self.defaultValue: + deps.add(self.defaultValue) + return deps + +class IDLCallbackType(IDLType, IDLObjectWithScope): + def __init__(self, location, parentScope, identifier, returnType, arguments): + assert isinstance(returnType, IDLType) + + IDLType.__init__(self, location, identifier.name) + + self._returnType = returnType + # Clone the list + self._arguments = list(arguments) + + IDLObjectWithScope.__init__(self, location, parentScope, identifier) + + for (returnType, arguments) in self.signatures(): + for argument in arguments: + argument.resolve(self) + + self._treatNonCallableAsNull = False + self._treatNonObjectAsNull = False + + def isCallback(self): + return True + + def signatures(self): + return [(self._returnType, self._arguments)] + + def tag(self): + return IDLType.Tags.callback + + def finish(self, scope): + if not self._returnType.isComplete(): + type = self._returnType.complete(scope) + + assert not isinstance(type, IDLUnresolvedType) + assert not isinstance(type, IDLTypedefType) + assert not isinstance(type.name, IDLUnresolvedIdentifier) + self._returnType = type + + for argument in self._arguments: + if argument.type.isComplete(): + continue + + type = argument.type.complete(scope) + + assert not isinstance(type, IDLUnresolvedType) + assert not isinstance(type, IDLTypedefType) + assert not isinstance(type.name, IDLUnresolvedIdentifier) + argument.type = type + + def validate(self): + pass + + def isDistinguishableFrom(self, other): + if other.isUnion(): + # Just forward to the union; it'll deal + return other.isDistinguishableFrom(self) + return (other.isPrimitive() or other.isString() or other.isEnum() or + other.isNonCallbackInterface() or other.isDate()) + + def addExtendedAttributes(self, attrs): + unhandledAttrs = [] + for attr in attrs: + if attr.identifier() == "TreatNonCallableAsNull": + self._treatNonCallableAsNull = True + elif attr.identifier() == "TreatNonObjectAsNull": + self._treatNonObjectAsNull = True + else: + unhandledAttrs.append(attr) + if self._treatNonCallableAsNull and self._treatNonObjectAsNull: + raise WebIDLError("Cannot specify both [TreatNonCallableAsNull] " + "and [TreatNonObjectAsNull]", [self.location]) + if len(unhandledAttrs) != 0: + IDLType.addExtendedAttributes(self, unhandledAttrs) + + def _getDependentObjects(self): + return set([self._returnType] + self._arguments) + +class IDLMethodOverload: + """ + A class that represents a single overload of a WebIDL method. This is not + quite the same as an element of the "effective overload set" in the spec, + because separate IDLMethodOverloads are not created based on arguments being + optional. Rather, when multiple methods have the same name, there is an + IDLMethodOverload for each one, all hanging off an IDLMethod representing + the full set of overloads. + """ + def __init__(self, returnType, arguments, location): + self.returnType = returnType + # Clone the list of arguments, just in case + self.arguments = list(arguments) + self.location = location + + def _getDependentObjects(self): + deps = set(self.arguments) + deps.add(self.returnType) + return deps + +class IDLMethod(IDLInterfaceMember, IDLScope): + + Special = enum( + 'Getter', + 'Setter', + 'Creator', + 'Deleter', + 'LegacyCaller', + base=IDLInterfaceMember.Special + ) + + TypeSuffixModifier = enum( + 'None', + 'QMark', + 'Brackets' + ) + + NamedOrIndexed = enum( + 'Neither', + 'Named', + 'Indexed' + ) + + def __init__(self, location, identifier, returnType, arguments, + static=False, getter=False, setter=False, creator=False, + deleter=False, specialType=NamedOrIndexed.Neither, + legacycaller=False, stringifier=False, jsonifier=False): + # REVIEW: specialType is NamedOrIndexed -- wow, this is messed up. + IDLInterfaceMember.__init__(self, location, identifier, + IDLInterfaceMember.Tags.Method) + + self._hasOverloads = False + + assert isinstance(returnType, IDLType) + + # self._overloads is a list of IDLMethodOverloads + self._overloads = [IDLMethodOverload(returnType, arguments, location)] + + assert isinstance(static, bool) + self._static = static + assert isinstance(getter, bool) + self._getter = getter + assert isinstance(setter, bool) + self._setter = setter + assert isinstance(creator, bool) + self._creator = creator + assert isinstance(deleter, bool) + self._deleter = deleter + assert isinstance(legacycaller, bool) + self._legacycaller = legacycaller + assert isinstance(stringifier, bool) + self._stringifier = stringifier + assert isinstance(jsonifier, bool) + self._jsonifier = jsonifier + self._specialType = specialType + + if static and identifier.name == "prototype": + raise WebIDLError("The identifier of a static operation must not be 'prototype'", + [location]) + + self.assertSignatureConstraints() + + def __str__(self): + return "Method '%s'" % self.identifier + + def assertSignatureConstraints(self): + if self._getter or self._deleter: + assert len(self._overloads) == 1 + overload = self._overloads[0] + arguments = overload.arguments + assert len(arguments) == 1 + assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \ + arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long] + assert not arguments[0].optional and not arguments[0].variadic + assert not self._getter or not overload.returnType.isVoid() + + if self._setter or self._creator: + assert len(self._overloads) == 1 + arguments = self._overloads[0].arguments + assert len(arguments) == 2 + assert arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.domstring] or \ + arguments[0].type == BuiltinTypes[IDLBuiltinType.Types.unsigned_long] + assert not arguments[0].optional and not arguments[0].variadic + assert not arguments[1].optional and not arguments[1].variadic + + if self._stringifier: + assert len(self._overloads) == 1 + overload = self._overloads[0] + assert len(overload.arguments) == 0 + assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.domstring] + + if self._jsonifier: + assert len(self._overloads) == 1 + overload = self._overloads[0] + assert len(overload.arguments) == 0 + assert overload.returnType == BuiltinTypes[IDLBuiltinType.Types.object] + + def isStatic(self): + return self._static + + def isGetter(self): + return self._getter + + def isSetter(self): + return self._setter + + def isCreator(self): + return self._creator + + def isDeleter(self): + return self._deleter + + def isNamed(self): + assert self._specialType == IDLMethod.NamedOrIndexed.Named or \ + self._specialType == IDLMethod.NamedOrIndexed.Indexed + return self._specialType == IDLMethod.NamedOrIndexed.Named + + def isIndexed(self): + assert self._specialType == IDLMethod.NamedOrIndexed.Named or \ + self._specialType == IDLMethod.NamedOrIndexed.Indexed + return self._specialType == IDLMethod.NamedOrIndexed.Indexed + + def isLegacycaller(self): + return self._legacycaller + + def isStringifier(self): + return self._stringifier + + def isJsonifier(self): + return self._jsonifier + + def hasOverloads(self): + return self._hasOverloads + + def isIdentifierLess(self): + return self.identifier.name[:2] == "__" and self.identifier.name != "__noSuchMethod__" + + def resolve(self, parentScope): + assert isinstance(parentScope, IDLScope) + IDLObjectWithIdentifier.resolve(self, parentScope) + IDLScope.__init__(self, self.location, parentScope, self.identifier) + for (returnType, arguments) in self.signatures(): + for argument in arguments: + argument.resolve(self) + + def addOverload(self, method): + assert len(method._overloads) == 1 + + if self._extendedAttrDict != method ._extendedAttrDict: + raise WebIDLError("Extended attributes differ on different " + "overloads of %s" % method.identifier, + [self.location, method.location]) + + self._overloads.extend(method._overloads) + + self._hasOverloads = True + + if self.isStatic() != method.isStatic(): + raise WebIDLError("Overloaded identifier %s appears with different values of the 'static' attribute" % method.identifier, + [method.location]) + + if self.isLegacycaller() != method.isLegacycaller(): + raise WebIDLError("Overloaded identifier %s appears with different values of the 'legacycaller' attribute" % method.identifier, + [method.location]) + + # Can't overload special things! + assert not self.isGetter() + assert not method.isGetter() + assert not self.isSetter() + assert not method.isSetter() + assert not self.isCreator() + assert not method.isCreator() + assert not self.isDeleter() + assert not method.isDeleter() + assert not self.isStringifier() + assert not method.isStringifier() + assert not self.isJsonifier() + assert not method.isJsonifier() + + return self + + def signatures(self): + return [(overload.returnType, overload.arguments) for overload in + self._overloads] + + def finish(self, scope): + overloadWithPromiseReturnType = None + overloadWithoutPromiseReturnType = None + for overload in self._overloads: + variadicArgument = None + + arguments = overload.arguments + for (idx, argument) in enumerate(arguments): + if not argument.isComplete(): + argument.complete(scope) + assert argument.type.isComplete() + + if (argument.type.isDictionary() or + (argument.type.isUnion() and + argument.type.unroll().hasDictionaryType)): + # Dictionaries and unions containing dictionaries at the + # end of the list or followed by optional arguments must be + # optional. + if (not argument.optional and + all(arg.optional for arg in arguments[idx+1:])): + raise WebIDLError("Dictionary argument or union " + "argument containing a dictionary " + "not followed by a required argument " + "must be optional", + [argument.location]) + + # An argument cannot be a Nullable Dictionary + if argument.type.nullable(): + raise WebIDLError("An argument cannot be a nullable " + "dictionary or nullable union " + "containing a dictionary", + [argument.location]) + + # Only the last argument can be variadic + if variadicArgument: + raise WebIDLError("Variadic argument is not last argument", + [variadicArgument.location]) + if argument.variadic: + variadicArgument = argument + + returnType = overload.returnType + if not returnType.isComplete(): + returnType = returnType.complete(scope) + assert not isinstance(returnType, IDLUnresolvedType) + assert not isinstance(returnType, IDLTypedefType) + assert not isinstance(returnType.name, IDLUnresolvedIdentifier) + overload.returnType = returnType + + if returnType.isPromise(): + overloadWithPromiseReturnType = overload + else: + overloadWithoutPromiseReturnType = overload + + # Make sure either all our overloads return Promises or none do + if overloadWithPromiseReturnType and overloadWithoutPromiseReturnType: + raise WebIDLError("We have overloads with both Promise and " + "non-Promise return types", + [overloadWithPromiseReturnType.location, + overloadWithoutPromiseReturnType.location]) + + if overloadWithPromiseReturnType and self._legacycaller: + raise WebIDLError("May not have a Promise return type for a " + "legacycaller.", + [overloadWithPromiseReturnType.location]) + + # Now compute various information that will be used by the + # WebIDL overload resolution algorithm. + self.maxArgCount = max(len(s[1]) for s in self.signatures()) + self.allowedArgCounts = [ i for i in range(self.maxArgCount+1) + if len(self.signaturesForArgCount(i)) != 0 ] + + def validate(self): + # Make sure our overloads are properly distinguishable and don't have + # different argument types before the distinguishing args. + for argCount in self.allowedArgCounts: + possibleOverloads = self.overloadsForArgCount(argCount) + if len(possibleOverloads) == 1: + continue + distinguishingIndex = self.distinguishingIndexForArgCount(argCount) + for idx in range(distinguishingIndex): + firstSigType = possibleOverloads[0].arguments[idx].type + for overload in possibleOverloads[1:]: + if overload.arguments[idx].type != firstSigType: + raise WebIDLError( + "Signatures for method '%s' with %d arguments have " + "different types of arguments at index %d, which " + "is before distinguishing index %d" % + (self.identifier.name, argCount, idx, + distinguishingIndex), + [self.location, overload.location]) + + def overloadsForArgCount(self, argc): + return [overload for overload in self._overloads if + len(overload.arguments) == argc or + (len(overload.arguments) > argc and + all(arg.optional for arg in overload.arguments[argc:])) or + (len(overload.arguments) < argc and + len(overload.arguments) > 0 and + overload.arguments[-1].variadic)] + + def signaturesForArgCount(self, argc): + return [(overload.returnType, overload.arguments) for overload + in self.overloadsForArgCount(argc)] + + def locationsForArgCount(self, argc): + return [overload.location for overload in self.overloadsForArgCount(argc)] + + def distinguishingIndexForArgCount(self, argc): + def isValidDistinguishingIndex(idx, signatures): + for (firstSigIndex, (firstRetval, firstArgs)) in enumerate(signatures[:-1]): + for (secondRetval, secondArgs) in signatures[firstSigIndex+1:]: + if idx < len(firstArgs): + firstType = firstArgs[idx].type + else: + assert(firstArgs[-1].variadic) + firstType = firstArgs[-1].type + if idx < len(secondArgs): + secondType = secondArgs[idx].type + else: + assert(secondArgs[-1].variadic) + secondType = secondArgs[-1].type + if not firstType.isDistinguishableFrom(secondType): + return False + return True + signatures = self.signaturesForArgCount(argc) + for idx in range(argc): + if isValidDistinguishingIndex(idx, signatures): + return idx + # No valid distinguishing index. Time to throw + locations = self.locationsForArgCount(argc) + raise WebIDLError("Signatures with %d arguments for method '%s' are not " + "distinguishable" % (argc, self.identifier.name), + locations) + + def handleExtendedAttribute(self, attr): + identifier = attr.identifier() + if identifier == "GetterThrows": + raise WebIDLError("Methods must not be flagged as " + "[GetterThrows]", + [attr.location, self.location]) + elif identifier == "SetterThrows": + raise WebIDLError("Methods must not be flagged as " + "[SetterThrows]", + [attr.location, self.location]) + elif identifier == "Unforgeable": + raise WebIDLError("Methods must not be flagged as " + "[Unforgeable]", + [attr.location, self.location]) + elif identifier == "SameObject": + raise WebIDLError("Methods must not be flagged as [SameObject]", + [attr.location, self.location]); + elif identifier == "Constant": + raise WebIDLError("Methods must not be flagged as [Constant]", + [attr.location, self.location]); + elif identifier == "PutForwards": + raise WebIDLError("Only attributes support [PutForwards]", + [attr.location, self.location]) + elif identifier == "LenientFloat": + # This is called before we've done overload resolution + assert len(self.signatures()) == 1 + sig = self.signatures()[0] + if not sig[0].isVoid(): + raise WebIDLError("[LenientFloat] used on a non-void method", + [attr.location, self.location]) + if not any(arg.type.includesRestrictedFloat() for arg in sig[1]): + raise WebIDLError("[LenientFloat] used on an operation with no " + "restricted float type arguments", + [attr.location, self.location]) + elif (identifier == "Throws" or + identifier == "NewObject" or + identifier == "ChromeOnly" or + identifier == "Pref" or + identifier == "Func" or + identifier == "AvailableIn" or + identifier == "Pure" or + identifier == "CrossOriginCallable" or + identifier == "Ref" or + identifier == "Value" or + identifier == "Operator" or + identifier == "WebGLHandlesContextLoss"): + # Known attributes that we don't need to do anything with here + pass + else: + raise WebIDLError("Unknown extended attribute %s on method" % identifier, + [attr.location]) + IDLInterfaceMember.handleExtendedAttribute(self, attr) + + def returnsPromise(self): + return self._overloads[0].returnType.isPromise() + + def _getDependentObjects(self): + deps = set() + for overload in self._overloads: + deps.union(overload._getDependentObjects()) + return deps + +class IDLImplementsStatement(IDLObject): + def __init__(self, location, implementor, implementee): + IDLObject.__init__(self, location) + self.implementor = implementor; + self.implementee = implementee + + def finish(self, scope): + assert(isinstance(self.implementor, IDLIdentifierPlaceholder)) + assert(isinstance(self.implementee, IDLIdentifierPlaceholder)) + implementor = self.implementor.finish(scope) + implementee = self.implementee.finish(scope) + # NOTE: we depend on not setting self.implementor and + # self.implementee here to keep track of the original + # locations. + if not isinstance(implementor, IDLInterface): + raise WebIDLError("Left-hand side of 'implements' is not an " + "interface", + [self.implementor.location]) + if implementor.isCallback(): + raise WebIDLError("Left-hand side of 'implements' is a callback " + "interface", + [self.implementor.location]) + if not isinstance(implementee, IDLInterface): + raise WebIDLError("Right-hand side of 'implements' is not an " + "interface", + [self.implementee.location]) + if implementee.isCallback(): + raise WebIDLError("Right-hand side of 'implements' is a callback " + "interface", + [self.implementee.location]) + implementor.addImplementedInterface(implementee) + + def validate(self): + pass + + def addExtendedAttributes(self, attrs): + assert len(attrs) == 0 + +class IDLExtendedAttribute(IDLObject): + """ + A class to represent IDL extended attributes so we can give them locations + """ + def __init__(self, location, tuple): + IDLObject.__init__(self, location) + self._tuple = tuple + + def identifier(self): + return self._tuple[0] + + def noArguments(self): + return len(self._tuple) == 1 + + def hasValue(self): + return len(self._tuple) >= 2 and isinstance(self._tuple[1], str) + + def value(self): + assert(self.hasValue()) + return self._tuple[1] + + def hasArgs(self): + return (len(self._tuple) == 2 and isinstance(self._tuple[1], list) or + len(self._tuple) == 3) + + def args(self): + assert(self.hasArgs()) + # Our args are our last element + return self._tuple[-1] + + def listValue(self): + """ + Backdoor for storing random data in _extendedAttrDict + """ + return list(self._tuple)[1:] + +# Parser + +class Tokenizer(object): + tokens = [ + "INTEGER", + "FLOATLITERAL", + "IDENTIFIER", + "STRING", + "WHITESPACE", + "OTHER" + ] + + def t_FLOATLITERAL(self, t): + r'(-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+|Infinity))|NaN' + t.value = float(t.value) + return t + + def t_INTEGER(self, t): + r'-?(0([0-7]+|[Xx][0-9A-Fa-f]+)?|[1-9][0-9]*)' + try: + # Can't use int(), because that doesn't handle octal properly. + t.value = parseInt(t.value) + except: + raise WebIDLError("Invalid integer literal", + [Location(lexer=self.lexer, + lineno=self.lexer.lineno, + lexpos=self.lexer.lexpos, + filename=self._filename)]) + return t + + def t_IDENTIFIER(self, t): + r'[A-Z_a-z][0-9A-Z_a-z]*' + t.type = self.keywords.get(t.value, 'IDENTIFIER') + return t + + def t_STRING(self, t): + r'"[^"]*"' + t.value = t.value[1:-1] + return t + + def t_WHITESPACE(self, t): + r'[\t\n\r ]+|[\t\n\r ]*((//[^\n]*|/\*.*?\*/)[\t\n\r ]*)+' + pass + + def t_ELLIPSIS(self, t): + r'\.\.\.' + t.type = self.keywords.get(t.value) + return t + + def t_OTHER(self, t): + r'[^\t\n\r 0-9A-Z_a-z]' + t.type = self.keywords.get(t.value, 'OTHER') + return t + + keywords = { + "module": "MODULE", + "interface": "INTERFACE", + "partial": "PARTIAL", + "dictionary": "DICTIONARY", + "exception": "EXCEPTION", + "enum": "ENUM", + "callback": "CALLBACK", + "typedef": "TYPEDEF", + "implements": "IMPLEMENTS", + "const": "CONST", + "null": "NULL", + "true": "TRUE", + "false": "FALSE", + "serializer": "SERIALIZER", + "stringifier": "STRINGIFIER", + "jsonifier": "JSONIFIER", + "unrestricted": "UNRESTRICTED", + "attribute": "ATTRIBUTE", + "readonly": "READONLY", + "inherit": "INHERIT", + "static": "STATIC", + "getter": "GETTER", + "setter": "SETTER", + "creator": "CREATOR", + "deleter": "DELETER", + "legacycaller": "LEGACYCALLER", + "optional": "OPTIONAL", + "...": "ELLIPSIS", + "::": "SCOPE", + "Date": "DATE", + "DOMString": "DOMSTRING", + "ByteString": "BYTESTRING", + "any": "ANY", + "boolean": "BOOLEAN", + "byte": "BYTE", + "double": "DOUBLE", + "float": "FLOAT", + "long": "LONG", + "object": "OBJECT", + "octet": "OCTET", + "optional": "OPTIONAL", + "sequence": "SEQUENCE", + "short": "SHORT", + "unsigned": "UNSIGNED", + "void": "VOID", + ":": "COLON", + ";": "SEMICOLON", + "{": "LBRACE", + "}": "RBRACE", + "(": "LPAREN", + ")": "RPAREN", + "[": "LBRACKET", + "]": "RBRACKET", + "?": "QUESTIONMARK", + ",": "COMMA", + "=": "EQUALS", + "<": "LT", + ">": "GT", + "ArrayBuffer": "ARRAYBUFFER", + "or": "OR" + } + + tokens.extend(keywords.values()) + + def t_error(self, t): + raise WebIDLError("Unrecognized Input", + [Location(lexer=self.lexer, + lineno=self.lexer.lineno, + lexpos=self.lexer.lexpos, + filename = self.filename)]) + + def __init__(self, outputdir, lexer=None): + if lexer: + self.lexer = lexer + else: + self.lexer = lex.lex(object=self, + outputdir=outputdir, + lextab='webidllex', + reflags=re.DOTALL) + +class Parser(Tokenizer): + def getLocation(self, p, i): + return Location(self.lexer, p.lineno(i), p.lexpos(i), self._filename) + + def globalScope(self): + return self._globalScope + + # The p_Foo functions here must match the WebIDL spec's grammar. + # It's acceptable to split things at '|' boundaries. + def p_Definitions(self, p): + """ + Definitions : ExtendedAttributeList Definition Definitions + """ + if p[2]: + p[0] = [p[2]] + p[2].addExtendedAttributes(p[1]) + else: + assert not p[1] + p[0] = [] + + p[0].extend(p[3]) + + def p_DefinitionsEmpty(self, p): + """ + Definitions : + """ + p[0] = [] + + def p_Definition(self, p): + """ + Definition : CallbackOrInterface + | PartialInterface + | Dictionary + | Exception + | Enum + | Typedef + | ImplementsStatement + """ + p[0] = p[1] + assert p[1] # We might not have implemented something ... + + def p_CallbackOrInterfaceCallback(self, p): + """ + CallbackOrInterface : CALLBACK CallbackRestOrInterface + """ + if p[2].isInterface(): + assert isinstance(p[2], IDLInterface) + p[2].setCallback(True) + + p[0] = p[2] + + def p_CallbackOrInterfaceInterface(self, p): + """ + CallbackOrInterface : Interface + """ + p[0] = p[1] + + def p_CallbackRestOrInterface(self, p): + """ + CallbackRestOrInterface : CallbackRest + | Interface + """ + assert p[1] + p[0] = p[1] + + def p_Interface(self, p): + """ + Interface : INTERFACE IDENTIFIER Inheritance LBRACE InterfaceMembers RBRACE SEMICOLON + """ + location = self.getLocation(p, 1) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) + members = p[5] + parent = p[3] + + try: + if self.globalScope()._lookupIdentifier(identifier): + p[0] = self.globalScope()._lookupIdentifier(identifier) + if not isinstance(p[0], IDLInterface): + raise WebIDLError("Partial interface has the same name as " + "non-interface object", + [location, p[0].location]) + p[0].setNonPartial(location, parent, members) + return + except Exception, ex: + if isinstance(ex, WebIDLError): + raise ex + pass + + p[0] = IDLInterface(location, self.globalScope(), identifier, parent, + members, isPartial=False) + + def p_InterfaceForwardDecl(self, p): + """ + Interface : INTERFACE IDENTIFIER SEMICOLON + """ + location = self.getLocation(p, 1) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) + + try: + if self.globalScope()._lookupIdentifier(identifier): + p[0] = self.globalScope()._lookupIdentifier(identifier) + if not isinstance(p[0], IDLExternalInterface): + raise WebIDLError("Name collision between external " + "interface declaration for identifier " + "%s and %s" % (identifier.name, p[0]), + [location, p[0].location]) + return + except Exception, ex: + if isinstance(ex, WebIDLError): + raise ex + pass + + p[0] = IDLExternalInterface(location, self.globalScope(), identifier) + + def p_PartialInterface(self, p): + """ + PartialInterface : PARTIAL INTERFACE IDENTIFIER LBRACE InterfaceMembers RBRACE SEMICOLON + """ + location = self.getLocation(p, 2) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3]) + members = p[5] + + try: + if self.globalScope()._lookupIdentifier(identifier): + p[0] = self.globalScope()._lookupIdentifier(identifier) + if not isinstance(p[0], IDLInterface): + raise WebIDLError("Partial interface has the same name as " + "non-interface object", + [location, p[0].location]) + # Just throw our members into the existing IDLInterface. If we + # have extended attributes, those will get added to it + # automatically. + p[0].members.extend(members) + return + except Exception, ex: + if isinstance(ex, WebIDLError): + raise ex + pass + + p[0] = IDLInterface(location, self.globalScope(), identifier, None, + members, isPartial=True) + pass + + def p_Inheritance(self, p): + """ + Inheritance : COLON ScopedName + """ + p[0] = IDLIdentifierPlaceholder(self.getLocation(p, 2), p[2]) + + def p_InheritanceEmpty(self, p): + """ + Inheritance : + """ + pass + + def p_InterfaceMembers(self, p): + """ + InterfaceMembers : ExtendedAttributeList InterfaceMember InterfaceMembers + """ + p[0] = [p[2]] if p[2] else [] + + assert not p[1] or p[2] + p[2].addExtendedAttributes(p[1]) + + p[0].extend(p[3]) + + def p_InterfaceMembersEmpty(self, p): + """ + InterfaceMembers : + """ + p[0] = [] + + def p_InterfaceMember(self, p): + """ + InterfaceMember : Const + | AttributeOrOperation + """ + p[0] = p[1] + + def p_Dictionary(self, p): + """ + Dictionary : DICTIONARY IDENTIFIER Inheritance LBRACE DictionaryMembers RBRACE SEMICOLON + """ + location = self.getLocation(p, 1) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) + members = p[5] + p[0] = IDLDictionary(location, self.globalScope(), identifier, p[3], members) + + def p_DictionaryMembers(self, p): + """ + DictionaryMembers : ExtendedAttributeList DictionaryMember DictionaryMembers + | + """ + if len(p) == 1: + # We're at the end of the list + p[0] = [] + return + # Add our extended attributes + p[2].addExtendedAttributes(p[1]) + p[0] = [p[2]] + p[0].extend(p[3]) + + def p_DictionaryMember(self, p): + """ + DictionaryMember : Type IDENTIFIER DefaultValue SEMICOLON + """ + # These quack a lot like optional arguments, so just treat them that way. + t = p[1] + assert isinstance(t, IDLType) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) + defaultValue = p[3] + + p[0] = IDLArgument(self.getLocation(p, 2), identifier, t, optional=True, + defaultValue=defaultValue, variadic=False, + dictionaryMember=True) + + def p_DefaultValue(self, p): + """ + DefaultValue : EQUALS ConstValue + | + """ + if len(p) > 1: + p[0] = p[2] + else: + p[0] = None + + def p_Exception(self, p): + """ + Exception : EXCEPTION IDENTIFIER Inheritance LBRACE ExceptionMembers RBRACE SEMICOLON + """ + pass + + def p_Enum(self, p): + """ + Enum : ENUM IDENTIFIER LBRACE EnumValueList RBRACE SEMICOLON + """ + location = self.getLocation(p, 1) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 2), p[2]) + + values = p[4] + assert values + p[0] = IDLEnum(location, self.globalScope(), identifier, values) + + def p_EnumValueList(self, p): + """ + EnumValueList : STRING EnumValueListComma + """ + p[0] = [p[1]] + p[0].extend(p[2]) + + def p_EnumValueListComma(self, p): + """ + EnumValueListComma : COMMA EnumValueListString + """ + p[0] = p[2] + + def p_EnumValueListCommaEmpty(self, p): + """ + EnumValueListComma : + """ + p[0] = [] + + def p_EnumValueListString(self, p): + """ + EnumValueListString : STRING EnumValueListComma + """ + p[0] = [p[1]] + p[0].extend(p[2]) + + def p_EnumValueListStringEmpty(self, p): + """ + EnumValueListString : + """ + p[0] = [] + + def p_CallbackRest(self, p): + """ + CallbackRest : IDENTIFIER EQUALS ReturnType LPAREN ArgumentList RPAREN SEMICOLON + """ + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) + p[0] = IDLCallbackType(self.getLocation(p, 1), self.globalScope(), + identifier, p[3], p[5]) + + def p_ExceptionMembers(self, p): + """ + ExceptionMembers : ExtendedAttributeList ExceptionMember ExceptionMembers + | + """ + pass + + def p_Typedef(self, p): + """ + Typedef : TYPEDEF Type IDENTIFIER SEMICOLON + """ + typedef = IDLTypedefType(self.getLocation(p, 1), p[2], p[3]) + typedef.resolve(self.globalScope()) + p[0] = typedef + + def p_ImplementsStatement(self, p): + """ + ImplementsStatement : ScopedName IMPLEMENTS ScopedName SEMICOLON + """ + assert(p[2] == "implements") + implementor = IDLIdentifierPlaceholder(self.getLocation(p, 1), p[1]) + implementee = IDLIdentifierPlaceholder(self.getLocation(p, 3), p[3]) + p[0] = IDLImplementsStatement(self.getLocation(p, 1), implementor, + implementee) + + def p_Const(self, p): + """ + Const : CONST ConstType IDENTIFIER EQUALS ConstValue SEMICOLON + """ + location = self.getLocation(p, 1) + type = p[2] + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 3), p[3]) + value = p[5] + p[0] = IDLConst(location, identifier, type, value) + + def p_ConstValueBoolean(self, p): + """ + ConstValue : BooleanLiteral + """ + location = self.getLocation(p, 1) + booleanType = BuiltinTypes[IDLBuiltinType.Types.boolean] + p[0] = IDLValue(location, booleanType, p[1]) + + def p_ConstValueInteger(self, p): + """ + ConstValue : INTEGER + """ + location = self.getLocation(p, 1) + + # We don't know ahead of time what type the integer literal is. + # Determine the smallest type it could possibly fit in and use that. + integerType = matchIntegerValueToType(p[1]) + if integerType == None: + raise WebIDLError("Integer literal out of range", [location]) + + p[0] = IDLValue(location, integerType, p[1]) + + def p_ConstValueFloat(self, p): + """ + ConstValue : FLOATLITERAL + """ + location = self.getLocation(p, 1) + p[0] = IDLValue(location, BuiltinTypes[IDLBuiltinType.Types.unrestricted_float], p[1]) + + def p_ConstValueString(self, p): + """ + ConstValue : STRING + """ + location = self.getLocation(p, 1) + stringType = BuiltinTypes[IDLBuiltinType.Types.domstring] + p[0] = IDLValue(location, stringType, p[1]) + + def p_ConstValueNull(self, p): + """ + ConstValue : NULL + """ + p[0] = IDLNullValue(self.getLocation(p, 1)) + + def p_BooleanLiteralTrue(self, p): + """ + BooleanLiteral : TRUE + """ + p[0] = True + + def p_BooleanLiteralFalse(self, p): + """ + BooleanLiteral : FALSE + """ + p[0] = False + + def p_AttributeOrOperation(self, p): + """ + AttributeOrOperation : Attribute + | Operation + """ + p[0] = p[1] + + def p_AttributeWithQualifier(self, p): + """ + Attribute : Qualifier AttributeRest + """ + static = IDLInterfaceMember.Special.Static in p[1] + stringifier = IDLInterfaceMember.Special.Stringifier in p[1] + (location, identifier, type, readonly) = p[2] + p[0] = IDLAttribute(location, identifier, type, readonly, static=static, + stringifier=stringifier) + + def p_Attribute(self, p): + """ + Attribute : Inherit AttributeRest + """ + (location, identifier, type, readonly) = p[2] + p[0] = IDLAttribute(location, identifier, type, readonly, inherit=p[1]) + + def p_AttributeRest(self, p): + """ + AttributeRest : ReadOnly ATTRIBUTE Type IDENTIFIER SEMICOLON + """ + location = self.getLocation(p, 2) + readonly = p[1] + t = p[3] + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 4), p[4]) + p[0] = (location, identifier, t, readonly) + + def p_ReadOnly(self, p): + """ + ReadOnly : READONLY + """ + p[0] = True + + def p_ReadOnlyEmpty(self, p): + """ + ReadOnly : + """ + p[0] = False + + def p_Inherit(self, p): + """ + Inherit : INHERIT + """ + p[0] = True + + def p_InheritEmpty(self, p): + """ + Inherit : + """ + p[0] = False + + def p_Operation(self, p): + """ + Operation : Qualifiers OperationRest + """ + qualifiers = p[1] + + # Disallow duplicates in the qualifier set + if not len(set(qualifiers)) == len(qualifiers): + raise WebIDLError("Duplicate qualifiers are not allowed", + [self.getLocation(p, 1)]) + + static = IDLInterfaceMember.Special.Static in p[1] + # If static is there that's all that's allowed. This is disallowed + # by the parser, so we can assert here. + assert not static or len(qualifiers) == 1 + + stringifier = IDLInterfaceMember.Special.Stringifier in p[1] + # If stringifier is there that's all that's allowed. This is disallowed + # by the parser, so we can assert here. + assert not stringifier or len(qualifiers) == 1 + + getter = True if IDLMethod.Special.Getter in p[1] else False + setter = True if IDLMethod.Special.Setter in p[1] else False + creator = True if IDLMethod.Special.Creator in p[1] else False + deleter = True if IDLMethod.Special.Deleter in p[1] else False + legacycaller = True if IDLMethod.Special.LegacyCaller in p[1] else False + + if getter or deleter: + if setter or creator: + raise WebIDLError("getter and deleter are incompatible with setter and creator", + [self.getLocation(p, 1)]) + + (returnType, identifier, arguments) = p[2] + + assert isinstance(returnType, IDLType) + + specialType = IDLMethod.NamedOrIndexed.Neither + + if getter or deleter: + if len(arguments) != 1: + raise WebIDLError("%s has wrong number of arguments" % + ("getter" if getter else "deleter"), + [self.getLocation(p, 2)]) + argType = arguments[0].type + if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]: + specialType = IDLMethod.NamedOrIndexed.Named + elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]: + specialType = IDLMethod.NamedOrIndexed.Indexed + else: + raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" % + ("getter" if getter else "deleter"), + [arguments[0].location]) + if arguments[0].optional or arguments[0].variadic: + raise WebIDLError("%s cannot have %s argument" % + ("getter" if getter else "deleter", + "optional" if arguments[0].optional else "variadic"), + [arguments[0].location]) + if getter: + if returnType.isVoid(): + raise WebIDLError("getter cannot have void return type", + [self.getLocation(p, 2)]) + if setter or creator: + if len(arguments) != 2: + raise WebIDLError("%s has wrong number of arguments" % + ("setter" if setter else "creator"), + [self.getLocation(p, 2)]) + argType = arguments[0].type + if argType == BuiltinTypes[IDLBuiltinType.Types.domstring]: + specialType = IDLMethod.NamedOrIndexed.Named + elif argType == BuiltinTypes[IDLBuiltinType.Types.unsigned_long]: + specialType = IDLMethod.NamedOrIndexed.Indexed + else: + raise WebIDLError("%s has wrong argument type (must be DOMString or UnsignedLong)" % + ("setter" if setter else "creator"), + [arguments[0].location]) + if arguments[0].optional or arguments[0].variadic: + raise WebIDLError("%s cannot have %s argument" % + ("setter" if setter else "creator", + "optional" if arguments[0].optional else "variadic"), + [arguments[0].location]) + if arguments[1].optional or arguments[1].variadic: + raise WebIDLError("%s cannot have %s argument" % + ("setter" if setter else "creator", + "optional" if arguments[1].optional else "variadic"), + [arguments[1].location]) + + if stringifier: + if len(arguments) != 0: + raise WebIDLError("stringifier has wrong number of arguments", + [self.getLocation(p, 2)]) + if not returnType.isDOMString(): + raise WebIDLError("stringifier must have DOMString return type", + [self.getLocation(p, 2)]) + + # identifier might be None. This is only permitted for special methods. + if not identifier: + if not getter and not setter and not creator and \ + not deleter and not legacycaller and not stringifier: + raise WebIDLError("Identifier required for non-special methods", + [self.getLocation(p, 2)]) + + location = BuiltinLocation("<auto-generated-identifier>") + identifier = IDLUnresolvedIdentifier(location, "__%s%s%s%s%s%s%s" % + ("named" if specialType == IDLMethod.NamedOrIndexed.Named else \ + "indexed" if specialType == IDLMethod.NamedOrIndexed.Indexed else "", + "getter" if getter else "", + "setter" if setter else "", + "deleter" if deleter else "", + "creator" if creator else "", + "legacycaller" if legacycaller else "", + "stringifier" if stringifier else ""), allowDoubleUnderscore=True) + + method = IDLMethod(self.getLocation(p, 2), identifier, returnType, arguments, + static=static, getter=getter, setter=setter, creator=creator, + deleter=deleter, specialType=specialType, + legacycaller=legacycaller, stringifier=stringifier) + p[0] = method + + def p_Stringifier(self, p): + """ + Operation : STRINGIFIER SEMICOLON + """ + identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), + "__stringifier", + allowDoubleUnderscore=True) + method = IDLMethod(self.getLocation(p, 1), + identifier, + returnType=BuiltinTypes[IDLBuiltinType.Types.domstring], + arguments=[], + stringifier=True) + p[0] = method + + def p_Jsonifier(self, p): + """ + Operation : JSONIFIER SEMICOLON + """ + identifier = IDLUnresolvedIdentifier(BuiltinLocation("<auto-generated-identifier>"), + "__jsonifier", allowDoubleUnderscore=True) + method = IDLMethod(self.getLocation(p, 1), + identifier, + returnType=BuiltinTypes[IDLBuiltinType.Types.object], + arguments=[], + jsonifier=True) + p[0] = method + + def p_QualifierStatic(self, p): + """ + Qualifier : STATIC + """ + p[0] = [IDLInterfaceMember.Special.Static] + + def p_QualifierStringifier(self, p): + """ + Qualifier : STRINGIFIER + """ + p[0] = [IDLInterfaceMember.Special.Stringifier] + + def p_Qualifiers(self, p): + """ + Qualifiers : Qualifier + | Specials + """ + p[0] = p[1] + + def p_Specials(self, p): + """ + Specials : Special Specials + """ + p[0] = [p[1]] + p[0].extend(p[2]) + + def p_SpecialsEmpty(self, p): + """ + Specials : + """ + p[0] = [] + + def p_SpecialGetter(self, p): + """ + Special : GETTER + """ + p[0] = IDLMethod.Special.Getter + + def p_SpecialSetter(self, p): + """ + Special : SETTER + """ + p[0] = IDLMethod.Special.Setter + + def p_SpecialCreator(self, p): + """ + Special : CREATOR + """ + p[0] = IDLMethod.Special.Creator + + def p_SpecialDeleter(self, p): + """ + Special : DELETER + """ + p[0] = IDLMethod.Special.Deleter + + def p_SpecialLegacyCaller(self, p): + """ + Special : LEGACYCALLER + """ + p[0] = IDLMethod.Special.LegacyCaller + + def p_OperationRest(self, p): + """ + OperationRest : ReturnType OptionalIdentifier LPAREN ArgumentList RPAREN SEMICOLON + """ + p[0] = (p[1], p[2], p[4]) + + def p_OptionalIdentifier(self, p): + """ + OptionalIdentifier : IDENTIFIER + """ + p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) + + def p_OptionalIdentifierEmpty(self, p): + """ + OptionalIdentifier : + """ + pass + + def p_ArgumentList(self, p): + """ + ArgumentList : Argument Arguments + """ + p[0] = [p[1]] if p[1] else [] + p[0].extend(p[2]) + + def p_ArgumentListEmpty(self, p): + """ + ArgumentList : + """ + p[0] = [] + + def p_Arguments(self, p): + """ + Arguments : COMMA Argument Arguments + """ + p[0] = [p[2]] if p[2] else [] + p[0].extend(p[3]) + + def p_ArgumentsEmpty(self, p): + """ + Arguments : + """ + p[0] = [] + + def p_Argument(self, p): + """ + Argument : ExtendedAttributeList Optional Type Ellipsis ArgumentName DefaultValue + """ + t = p[3] + assert isinstance(t, IDLType) + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 5), p[5]) + + optional = p[2] + variadic = p[4] + defaultValue = p[6] + + if not optional and defaultValue: + raise WebIDLError("Mandatory arguments can't have a default value.", + [self.getLocation(p, 6)]) + + # We can't test t.isAny() here and give it a default value as needed, + # since at this point t is not a fully resolved type yet (e.g. it might + # be a typedef). We'll handle the 'any' case in IDLArgument.complete. + + if variadic: + if optional: + raise WebIDLError("Variadic arguments should not be marked optional.", + [self.getLocation(p, 2)]) + optional = variadic + + p[0] = IDLArgument(self.getLocation(p, 5), identifier, t, optional, defaultValue, variadic) + p[0].addExtendedAttributes(p[1]) + + def p_ArgumentName(self, p): + """ + ArgumentName : IDENTIFIER + | ATTRIBUTE + | CALLBACK + | CONST + | CREATOR + | DELETER + | DICTIONARY + | ENUM + | EXCEPTION + | GETTER + | IMPLEMENTS + | INHERIT + | INTERFACE + | LEGACYCALLER + | PARTIAL + | SERIALIZER + | SETTER + | STATIC + | STRINGIFIER + | JSONIFIER + | TYPEDEF + | UNRESTRICTED + """ + p[0] = p[1] + + def p_Optional(self, p): + """ + Optional : OPTIONAL + """ + p[0] = True + + def p_OptionalEmpty(self, p): + """ + Optional : + """ + p[0] = False + + def p_Ellipsis(self, p): + """ + Ellipsis : ELLIPSIS + """ + p[0] = True + + def p_EllipsisEmpty(self, p): + """ + Ellipsis : + """ + p[0] = False + + def p_ExceptionMember(self, p): + """ + ExceptionMember : Const + | ExceptionField + """ + pass + + def p_ExceptionField(self, p): + """ + ExceptionField : Type IDENTIFIER SEMICOLON + """ + pass + + def p_ExtendedAttributeList(self, p): + """ + ExtendedAttributeList : LBRACKET ExtendedAttribute ExtendedAttributes RBRACKET + """ + p[0] = [p[2]] + if p[3]: + p[0].extend(p[3]) + + def p_ExtendedAttributeListEmpty(self, p): + """ + ExtendedAttributeList : + """ + p[0] = [] + + def p_ExtendedAttribute(self, p): + """ + ExtendedAttribute : ExtendedAttributeNoArgs + | ExtendedAttributeArgList + | ExtendedAttributeIdent + | ExtendedAttributeNamedArgList + """ + p[0] = IDLExtendedAttribute(self.getLocation(p, 1), p[1]) + + def p_ExtendedAttributeEmpty(self, p): + """ + ExtendedAttribute : + """ + pass + + def p_ExtendedAttributes(self, p): + """ + ExtendedAttributes : COMMA ExtendedAttribute ExtendedAttributes + """ + p[0] = [p[2]] if p[2] else [] + p[0].extend(p[3]) + + def p_ExtendedAttributesEmpty(self, p): + """ + ExtendedAttributes : + """ + p[0] = [] + + def p_Other(self, p): + """ + Other : INTEGER + | FLOATLITERAL + | IDENTIFIER + | STRING + | OTHER + | ELLIPSIS + | COLON + | SCOPE + | SEMICOLON + | LT + | EQUALS + | GT + | QUESTIONMARK + | DATE + | DOMSTRING + | BYTESTRING + | ANY + | ATTRIBUTE + | BOOLEAN + | BYTE + | LEGACYCALLER + | CONST + | CREATOR + | DELETER + | DOUBLE + | EXCEPTION + | FALSE + | FLOAT + | GETTER + | IMPLEMENTS + | INHERIT + | INTERFACE + | LONG + | MODULE + | NULL + | OBJECT + | OCTET + | OPTIONAL + | SEQUENCE + | SETTER + | SHORT + | STATIC + | STRINGIFIER + | JSONIFIER + | TRUE + | TYPEDEF + | UNSIGNED + | VOID + """ + pass + + def p_OtherOrComma(self, p): + """ + OtherOrComma : Other + | COMMA + """ + pass + + def p_TypeSingleType(self, p): + """ + Type : SingleType + """ + p[0] = p[1] + + def p_TypeUnionType(self, p): + """ + Type : UnionType TypeSuffix + """ + p[0] = self.handleModifiers(p[1], p[2]) + + def p_SingleTypeNonAnyType(self, p): + """ + SingleType : NonAnyType + """ + p[0] = p[1] + + def p_SingleTypeAnyType(self, p): + """ + SingleType : ANY TypeSuffixStartingWithArray + """ + p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.any], p[2]) + + def p_UnionType(self, p): + """ + UnionType : LPAREN UnionMemberType OR UnionMemberType UnionMemberTypes RPAREN + """ + types = [p[2], p[4]] + types.extend(p[5]) + p[0] = IDLUnionType(self.getLocation(p, 1), types) + + def p_UnionMemberTypeNonAnyType(self, p): + """ + UnionMemberType : NonAnyType + """ + p[0] = p[1] + + def p_UnionMemberTypeArrayOfAny(self, p): + """ + UnionMemberTypeArrayOfAny : ANY LBRACKET RBRACKET + """ + p[0] = IDLArrayType(self.getLocation(p, 2), + BuiltinTypes[IDLBuiltinType.Types.any]) + + def p_UnionMemberType(self, p): + """ + UnionMemberType : UnionType TypeSuffix + | UnionMemberTypeArrayOfAny TypeSuffix + """ + p[0] = self.handleModifiers(p[1], p[2]) + + def p_UnionMemberTypes(self, p): + """ + UnionMemberTypes : OR UnionMemberType UnionMemberTypes + """ + p[0] = [p[2]] + p[0].extend(p[3]) + + def p_UnionMemberTypesEmpty(self, p): + """ + UnionMemberTypes : + """ + p[0] = [] + + def p_NonAnyType(self, p): + """ + NonAnyType : PrimitiveOrStringType TypeSuffix + | ARRAYBUFFER TypeSuffix + | OBJECT TypeSuffix + """ + if p[1] == "object": + type = BuiltinTypes[IDLBuiltinType.Types.object] + elif p[1] == "ArrayBuffer": + type = BuiltinTypes[IDLBuiltinType.Types.ArrayBuffer] + else: + type = BuiltinTypes[p[1]] + + p[0] = self.handleModifiers(type, p[2]) + + def p_NonAnyTypeSequenceType(self, p): + """ + NonAnyType : SEQUENCE LT Type GT Null + """ + innerType = p[3] + type = IDLSequenceType(self.getLocation(p, 1), innerType) + if p[5]: + type = IDLNullableType(self.getLocation(p, 5), type) + p[0] = type + + def p_NonAnyTypeScopedName(self, p): + """ + NonAnyType : ScopedName TypeSuffix + """ + assert isinstance(p[1], IDLUnresolvedIdentifier) + + type = None + + try: + if self.globalScope()._lookupIdentifier(p[1]): + obj = self.globalScope()._lookupIdentifier(p[1]) + if obj.isType(): + type = obj + else: + type = IDLWrapperType(self.getLocation(p, 1), p[1]) + p[0] = self.handleModifiers(type, p[2]) + return + except: + pass + + type = IDLUnresolvedType(self.getLocation(p, 1), p[1]) + p[0] = self.handleModifiers(type, p[2]) + + def p_NonAnyTypeDate(self, p): + """ + NonAnyType : DATE TypeSuffix + """ + p[0] = self.handleModifiers(BuiltinTypes[IDLBuiltinType.Types.date], + p[2]) + + def p_ConstType(self, p): + """ + ConstType : PrimitiveOrStringType Null + """ + type = BuiltinTypes[p[1]] + if p[2]: + type = IDLNullableType(self.getLocation(p, 1), type) + p[0] = type + + def p_ConstTypeIdentifier(self, p): + """ + ConstType : IDENTIFIER Null + """ + identifier = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) + + type = IDLUnresolvedType(self.getLocation(p, 1), identifier) + if p[2]: + type = IDLNullableType(self.getLocation(p, 1), type) + p[0] = type + + def p_PrimitiveOrStringTypeUint(self, p): + """ + PrimitiveOrStringType : UnsignedIntegerType + """ + p[0] = p[1] + + def p_PrimitiveOrStringTypeBoolean(self, p): + """ + PrimitiveOrStringType : BOOLEAN + """ + p[0] = IDLBuiltinType.Types.boolean + + def p_PrimitiveOrStringTypeByte(self, p): + """ + PrimitiveOrStringType : BYTE + """ + p[0] = IDLBuiltinType.Types.byte + + def p_PrimitiveOrStringTypeOctet(self, p): + """ + PrimitiveOrStringType : OCTET + """ + p[0] = IDLBuiltinType.Types.octet + + def p_PrimitiveOrStringTypeFloat(self, p): + """ + PrimitiveOrStringType : FLOAT + """ + p[0] = IDLBuiltinType.Types.float + + def p_PrimitiveOrStringTypeUnrestictedFloat(self, p): + """ + PrimitiveOrStringType : UNRESTRICTED FLOAT + """ + p[0] = IDLBuiltinType.Types.unrestricted_float + + def p_PrimitiveOrStringTypeDouble(self, p): + """ + PrimitiveOrStringType : DOUBLE + """ + p[0] = IDLBuiltinType.Types.double + + def p_PrimitiveOrStringTypeUnrestictedDouble(self, p): + """ + PrimitiveOrStringType : UNRESTRICTED DOUBLE + """ + p[0] = IDLBuiltinType.Types.unrestricted_double + + def p_PrimitiveOrStringTypeDOMString(self, p): + """ + PrimitiveOrStringType : DOMSTRING + """ + p[0] = IDLBuiltinType.Types.domstring + + def p_PrimitiveOrStringTypeBytestring(self, p): + """ + PrimitiveOrStringType : BYTESTRING + """ + p[0] = IDLBuiltinType.Types.bytestring + + def p_UnsignedIntegerTypeUnsigned(self, p): + """ + UnsignedIntegerType : UNSIGNED IntegerType + """ + p[0] = p[2] + 1 # Adding one to a given signed integer type + # gets you the unsigned type. + + def p_UnsignedIntegerType(self, p): + """ + UnsignedIntegerType : IntegerType + """ + p[0] = p[1] + + def p_IntegerTypeShort(self, p): + """ + IntegerType : SHORT + """ + p[0] = IDLBuiltinType.Types.short + + def p_IntegerTypeLong(self, p): + """ + IntegerType : LONG OptionalLong + """ + if p[2]: + p[0] = IDLBuiltinType.Types.long_long + else: + p[0] = IDLBuiltinType.Types.long + + def p_OptionalLong(self, p): + """ + OptionalLong : LONG + """ + p[0] = True + + def p_OptionalLongEmpty(self, p): + """ + OptionalLong : + """ + p[0] = False + + def p_TypeSuffixBrackets(self, p): + """ + TypeSuffix : LBRACKET RBRACKET TypeSuffix + """ + p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))] + p[0].extend(p[3]) + + def p_TypeSuffixQMark(self, p): + """ + TypeSuffix : QUESTIONMARK TypeSuffixStartingWithArray + """ + p[0] = [(IDLMethod.TypeSuffixModifier.QMark, self.getLocation(p, 1))] + p[0].extend(p[2]) + + def p_TypeSuffixEmpty(self, p): + """ + TypeSuffix : + """ + p[0] = [] + + def p_TypeSuffixStartingWithArray(self, p): + """ + TypeSuffixStartingWithArray : LBRACKET RBRACKET TypeSuffix + """ + p[0] = [(IDLMethod.TypeSuffixModifier.Brackets, self.getLocation(p, 1))] + p[0].extend(p[3]) + + def p_TypeSuffixStartingWithArrayEmpty(self, p): + """ + TypeSuffixStartingWithArray : + """ + p[0] = [] + + def p_Null(self, p): + """ + Null : QUESTIONMARK + | + """ + if len(p) > 1: + p[0] = True + else: + p[0] = False + + def p_ReturnTypeType(self, p): + """ + ReturnType : Type + """ + p[0] = p[1] + + def p_ReturnTypeVoid(self, p): + """ + ReturnType : VOID + """ + p[0] = BuiltinTypes[IDLBuiltinType.Types.void] + + def p_ScopedName(self, p): + """ + ScopedName : AbsoluteScopedName + | RelativeScopedName + """ + p[0] = p[1] + + def p_AbsoluteScopedName(self, p): + """ + AbsoluteScopedName : SCOPE IDENTIFIER ScopedNameParts + """ + assert False + pass + + def p_RelativeScopedName(self, p): + """ + RelativeScopedName : IDENTIFIER ScopedNameParts + """ + assert not p[2] # Not implemented! + + p[0] = IDLUnresolvedIdentifier(self.getLocation(p, 1), p[1]) + + def p_ScopedNameParts(self, p): + """ + ScopedNameParts : SCOPE IDENTIFIER ScopedNameParts + """ + assert False + pass + + def p_ScopedNamePartsEmpty(self, p): + """ + ScopedNameParts : + """ + p[0] = None + + def p_ExtendedAttributeNoArgs(self, p): + """ + ExtendedAttributeNoArgs : IDENTIFIER + """ + p[0] = (p[1],) + + def p_ExtendedAttributeArgList(self, p): + """ + ExtendedAttributeArgList : IDENTIFIER LPAREN ArgumentList RPAREN + """ + p[0] = (p[1], p[3]) + + def p_ExtendedAttributeIdent(self, p): + """ + ExtendedAttributeIdent : IDENTIFIER EQUALS STRING + | IDENTIFIER EQUALS IDENTIFIER + """ + p[0] = (p[1], p[3]) + + def p_ExtendedAttributeNamedArgList(self, p): + """ + ExtendedAttributeNamedArgList : IDENTIFIER EQUALS IDENTIFIER LPAREN ArgumentList RPAREN + """ + p[0] = (p[1], p[3], p[5]) + + def p_error(self, p): + if not p: + raise WebIDLError("Syntax Error at end of file. Possibly due to missing semicolon(;), braces(}) or both", + [self._filename]) + else: + raise WebIDLError("invalid syntax", [Location(self.lexer, p.lineno, p.lexpos, self._filename)]) + + def __init__(self, outputdir='', lexer=None): + Tokenizer.__init__(self, outputdir, lexer) + self.parser = yacc.yacc(module=self, + outputdir=outputdir, + tabmodule='webidlyacc', + errorlog=yacc.NullLogger(), + picklefile='WebIDLGrammar.pkl') + self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None) + self._installBuiltins(self._globalScope) + self._productions = [] + + self._filename = "<builtin>" + self.lexer.input(Parser._builtins) + self._filename = None + + self.parser.parse(lexer=self.lexer,tracking=True) + + def _installBuiltins(self, scope): + assert isinstance(scope, IDLScope) + + # xrange omits the last value. + for x in xrange(IDLBuiltinType.Types.ArrayBuffer, IDLBuiltinType.Types.Float64Array + 1): + builtin = BuiltinTypes[x] + name = builtin.name + + typedef = IDLTypedefType(BuiltinLocation("<builtin type>"), builtin, name) + typedef.resolve(scope) + + @ staticmethod + def handleModifiers(type, modifiers): + for (modifier, modifierLocation) in modifiers: + assert modifier == IDLMethod.TypeSuffixModifier.QMark or \ + modifier == IDLMethod.TypeSuffixModifier.Brackets + + if modifier == IDLMethod.TypeSuffixModifier.QMark: + type = IDLNullableType(modifierLocation, type) + elif modifier == IDLMethod.TypeSuffixModifier.Brackets: + type = IDLArrayType(modifierLocation, type) + + return type + + def parse(self, t, filename=None): + self.lexer.input(t) + + #for tok in iter(self.lexer.token, None): + # print tok + + self._filename = filename + self._productions.extend(self.parser.parse(lexer=self.lexer,tracking=True)) + self._filename = None + + def finish(self): + # First, finish all the IDLImplementsStatements. In particular, we + # have to make sure we do those before we do the IDLInterfaces. + # XXX khuey hates this bit and wants to nuke it from orbit. + implementsStatements = [ p for p in self._productions if + isinstance(p, IDLImplementsStatement)] + otherStatements = [ p for p in self._productions if + not isinstance(p, IDLImplementsStatement)] + for production in implementsStatements: + production.finish(self.globalScope()) + for production in otherStatements: + production.finish(self.globalScope()) + + # Do any post-finish validation we need to do + for production in self._productions: + production.validate() + + # De-duplicate self._productions, without modifying its order. + seen = set() + result = [] + for p in self._productions: + if p not in seen: + seen.add(p) + result.append(p) + return result + + def reset(self): + return Parser(lexer=self.lexer) + + # Builtin IDL defined by WebIDL + _builtins = """ + typedef unsigned long long DOMTimeStamp; + """ + +def main(): + # Parse arguments. + from optparse import OptionParser + usageString = "usage: %prog [options] files" + o = OptionParser(usage=usageString) + o.add_option("--cachedir", dest='cachedir', default=None, + help="Directory in which to cache lex/parse tables.") + o.add_option("--verbose-errors", action='store_true', default=False, + help="When an error happens, display the Python traceback.") + (options, args) = o.parse_args() + + if len(args) < 1: + o.error(usageString) + + fileList = args + baseDir = os.getcwd() + + # Parse the WebIDL. + parser = Parser(options.cachedir) + try: + for filename in fileList: + fullPath = os.path.normpath(os.path.join(baseDir, filename)) + f = open(fullPath, 'rb') + lines = f.readlines() + f.close() + print fullPath + parser.parse(''.join(lines), fullPath) + parser.finish() + except WebIDLError, e: + if options.verbose_errors: + traceback.print_exc() + else: + print e + +if __name__ == '__main__': + main() + diff --git a/third_party/__init__.py b/third_party/__init__.py new file mode 100644 index 00000000..8fa2136f --- /dev/null +++ b/third_party/__init__.py @@ -0,0 +1,2 @@ +# + diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py index 5bf0996e..9bc8b929 100755 --- a/tools/bindings_generator.py +++ b/tools/bindings_generator.py @@ -1,6 +1,61 @@ #!/usr/bin/env python2 ''' + + + + + + + + + + + + + + + + + + + + + + + + +XXX THIS IS DEPRECATED, see webidl_binder.py XXX + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Use CppHeaderParser to parse some C++ headers, and generate binding code for them. Usage: diff --git a/tools/ffdb.py b/tools/ffdb.py new file mode 100755 index 00000000..c22fd9db --- /dev/null +++ b/tools/ffdb.py @@ -0,0 +1,342 @@ +#!/usr/bin/env python + +import socket, json, sys, uuid, datetime, time, logging, cgi, zipfile, os, tempfile, atexit, subprocess + +LOG_VERBOSE = False # Verbose printing enabled with --verbose +HOST = 'localhost' # The remote host to connect to the B2G device +PORT = 6000 # The port on the host on which the B2G device listens on +b2g_socket = None # Python socket object for the active connection to the B2G device +read_queue = '' # Inbound queue of partial data read so far from the device + +webappsActorName = None + +def sizeof_fmt(num): + for x in ['bytes','KB','MB','GB']: + if num < 1024.0: + return "%3.1f%s" % (num, x) + num /= 1024.0 + return "%3.1f%s" % (num, 'TB') + +def zipdir(path, zipfilename): + zipf = zipfile.ZipFile(zipfilename, 'w') + files_to_compress = [] + for root, dirs, files in os.walk(path): + for file in files: + files_to_compress += [(root, file)] + + n = 1 + for tuple in files_to_compress: + (root, file) = tuple + filename = os.path.join(root, file) + filesize = os.path.getsize(filename) + print 'Compressing ' + str(n) + '/' + str(len(files_to_compress)) + ': "' + os.path.relpath(filename, path) + '" (' + sizeof_fmt(filesize) + ')...' + n += 1 + zipf.write(os.path.join(root, file)) + zipf.close() + print 'Done. ' + +# Returns given log message formatted to be outputted on a HTML page. +def format_html(msg): + if not msg.endswith('\n'): + msg += '\n' + msg = cgi.escape(msg) + msg = msg.replace('\r\n', '<br />').replace('\n', '<br />') + return msg + +# Prints a verbose log message to stdout channel. Only shown if run with --verbose. +def logv(msg): + if LOG_VERBOSE: + sys.stdout.write(format_html(msg)) + sys.stdout.flush() + +# Reads data from the socket, and tries to parse what we have got so far as a JSON message. +# The messages are of form "bytelength:{jsondict}", where bytelength tells how many bytes +# there are in the data that comes after the colon. +# Returns a JSON dictionary of the received message. +def read_b2g_response(): + global read_queue, b2g_socket + read_queue += b2g_socket.recv(65536*2) + while ':' in read_queue: + semicolon = read_queue.index(':') + payload_len = int(read_queue[:semicolon]) + if semicolon+1+payload_len > len(read_queue): + read_queue += b2g_socket.recv(65536*2) + continue + payload = read_queue[semicolon+1:semicolon+1+payload_len] + read_queue = read_queue[semicolon+1+payload_len:] + logv('Read a message of size ' + str(payload_len) + 'b from socket.') + payload = json.loads(payload) + return payload + +# Sends a command to the B2G device and waits for the response and returns it as a JSON dict. +def send_b2g_cmd(to, cmd, data = {}): + global b2g_socket + msg = { 'to': to, 'type': cmd} + msg = dict(msg.items() + data.items()) + msg = json.dumps(msg, encoding='latin-1') + msg = msg.replace('\\\\', '\\') + msg = str(len(msg))+':'+msg + logv('Sending cmd:' + cmd + ' to:' + to) + b2g_socket.sendall(msg) + return read_b2g_response() + +def escape_bytes(b): + return str(b) + +# Sends a data fragment of a packaged app upload. This is a special-case version of the send_b2g_cmd +# command optimized for performance. +def send_b2g_data_chunk(to, data_blob): + byte_str = [] + e = '\u0000' + # '"' == 34 + # '\' == 92 + i = 0 + while i < len(data_blob): + o = ord(data_blob[i]) +# if o == 34 or o == 92 or o >= 128 or o <= 32:#o <= 32 or o >= 36:# or o == ord('\\'): + if o <= 34 or o >= 128 or o == 92: + c = hex(o)[2:] + byte_str += e[:-len(c)] + c + else: + byte_str += data_blob[i] + i += 1 + message = '{"to":"'+to+'","type":"chunk","chunk":"' + ''.join(byte_str) + '"}' + message = str(len(message)) + ':' + message + b2g_socket.sendall(message) + +# Queries the device for a list of all installed apps. +def b2g_get_appslist(): + global webappsActorName + apps = send_b2g_cmd(webappsActorName, 'getAll') + return apps['apps'] + +# Queries the device for a list of all currently running apps. +def b2g_get_runningapps(): + global webappsActorName + apps = send_b2g_cmd(webappsActorName, 'listRunningApps') + return apps['apps'] # Returns manifestURLs of all running apps + +def print_applist(applist, running_app_manifests, print_removable): + num_printed = 0 + for app in applist: + if print_removable or app['removable']: # Print only removable apps unless --all is specified, skip the built-in apps that can't be uninstalled. + if 'manifest' in app and 'version' in app['manifest']: + version = " version '" + app['manifest']['version'] + "'" + else: + version = '' + if app['manifestURL'] in running_app_manifests: + version += ' RUNNING' + print ' ' + str(app['localId']) + ': "' + app['name'] + '"' + version + num_printed += 1 + return num_printed + +def main(): + global b2g_socket, webappsActorName + if len(sys.argv) < 2 or '--help' in sys.argv or 'help' in sys.argv or '-v' in sys.argv: + print '''Firefox OS Debug Bridge, a tool for automating FFOS device tasks from the command line. + + Usage: ffdb.py <command>, where command is one of: + + list [--running] [--all]: Prints out the user applications installed on the device. + If --running is passed, only the currently opened apps are shown. + If --all is specified, then also uninstallable system applications are listed. + launch <app>: Starts the given application. If already running, brings to front. + close <app>: Terminates the execution of the given application. + uninstall <app>: Removes the given application from the device. + install <path>: Uploads and installs a packaged app that resides in the given local directory. + <path> may either refer to a directory containing a packaged app, or to a prepackaged zip file. + log <app> [--clear]: Starts a persistent log listener that reads web console messages from the given application. + If --clear is passed, the message log for that application is cleared instead. + navigate <url>: Opens the given web page in the B2G browser. + + In the above, whenever a command requires an <app> to be specified, either the human-readable name, + localId or manifestURL of the application can be used.''' + + sys.exit(0) + + b2g_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + b2g_socket.connect((HOST, PORT)) + except Exception, e: + if e[0] == 61: # Connection refused + if HOST == 'localhost' or HOST == '127.0.0.1': + cmd = ['adb', 'forward', 'tcp:'+str(PORT), 'localfilesystem:/data/local/debugger-socket'] + print 'Connection to ' + HOST + ':' + str(PORT) + ' refused, attempting to forward device debugger-socket to local address by calling ' + str(cmd) + ':' + else: + print 'Error! Failed to connect to B2G device debugger socket at address ' + HOST + ':' + str(PORT) + '!' + sys.exit(1) + try: + retcode = subprocess.check_call(cmd) + except Exception, e: + print 'Error! Failed to execute adb: ' + str(e) + print "Check that the device is connected properly, call 'adb devices' to list the detected devices." + sys.exit(1) + if retcode is not 0: + print 'Error! Failed to connect to B2G device and executing adb failed with return code ' + retcode + '!' + sys.exit(1) + time.sleep(3) + # Try again: + try: + b2g_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + b2g_socket.connect((HOST, PORT)) + except Exception, e: + print 'Error! Failed to connect to B2G device debugger socket at address ' + HOST + ':' + str(PORT) + '!' + sys.exit(1) + + handshake = read_b2g_response() + logv('Connected. Handshake: ' + str(handshake)) + + data = send_b2g_cmd('root', 'listTabs') + deviceActorName = data['deviceActor'] + logv('deviceActor: ' + deviceActorName) + webappsActorName = data['webappsActor'] + logv('webappsActor: ' + webappsActorName) + + send_b2g_cmd(deviceActorName, 'getDescription') + send_b2g_cmd(deviceActorName, 'getRawPermissionsTable') + + apps = b2g_get_appslist() + + if sys.argv[1] == 'list': + running_app_manifests = b2g_get_runningapps() + printed_apps = apps + print_only_running = '--running' in sys.argv and not '--all' in sys.argv + if print_only_running: # Print running apps only? + print 'Running applications by id:' + printed_apps = filter(lambda x: x['manifestURL'] in running_app_manifests, apps) + else: + print 'Installed applications by id:' + num_printed = print_applist(printed_apps, running_app_manifests, '--all' in sys.argv or print_only_running) + if num_printed == 0: + if print_only_running: + print ' No applications running.' + else: + print ' No applications installed.' + if not '--all' in sys.argv and not print_only_running: + print 'Not showing built-in apps that cannot be uninstalled. Pass --all to include those in the listing.' + elif sys.argv[1] == 'launch' or sys.argv[1] == 'close' or sys.argv[1] == 'uninstall' or sys.argv[1] == 'getAppActor': + if len(sys.argv) < 3: + print 'Error! No application name given! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <app>' + return 1 + for app in apps: + if str(app['localId']) == sys.argv[2] or app['name'] == sys.argv[2] or app['manifestURL'] == sys.argv[2]: + send_b2g_cmd(webappsActorName, sys.argv[1], { 'manifestURL': app['manifestURL'] }) + return 0 + print 'Error! Application "' + sys.argv[2] + '" was not found! Use the \'list\' command to find installed applications.' + return 1 + elif sys.argv[1] == 'install': + if len(sys.argv) < 3: + print 'Error! No application path given! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <path>' + return 1 + target_app_path = sys.argv[2] + if os.path.isdir(target_app_path): + print 'Zipping up the contents of directory "' + target_app_path + '"...' + (oshandle, tempzip) = tempfile.mkstemp(suffix='.zip', prefix='ffdb_temp_') + zipdir(target_app_path, tempzip) + target_app_path = tempzip + # Remember to delete the temporary package after we quit. + def delete_temp_file(): + os.remove(tempzip) + atexit.register(delete_temp_file) + + print 'Uploading application package "' + target_app_path + '"...' + print 'Size of compressed package: ' + sizeof_fmt(os.path.getsize(target_app_path)) + '.' + uploadResponse = send_b2g_cmd(webappsActorName, 'uploadPackage') + packageUploadActor = uploadResponse['actor'] + app_file = open(target_app_path, 'rb') + data = app_file.read() + file_size = len(data) + chunk_size = 4*1024*1024 + i = 0 + start_time = time.time() + while i < file_size: + chunk = data[i:i+chunk_size] + + send_b2g_data_chunk(packageUploadActor, chunk) + i += chunk_size + bytes_uploaded = min(i, file_size) + cur_time = time.time() + secs_elapsed = cur_time - start_time + percentage_done = bytes_uploaded * 1.0 / file_size + total_time = secs_elapsed / percentage_done + time_left = total_time - secs_elapsed + print sizeof_fmt(bytes_uploaded) + " uploaded, {:5.1f} % done.".format(percentage_done*100.0) + ' Elapsed: ' + str(int(secs_elapsed)) + ' seconds. Time left: ' + str(datetime.timedelta(seconds=int(time_left))) + '. Data rate: {:5.2f} KB/second.'.format(bytes_uploaded / 1024.0 / secs_elapsed) + send_b2g_cmd(webappsActorName, 'install', { 'appId': str(uuid.uuid4()), 'upload': packageUploadActor }) + + cur_time = time.time() + secs_elapsed = cur_time - start_time + print 'Upload of ' + sizeof_fmt(file_size) + ' finished. Total time elapsed: ' + str(int(secs_elapsed)) + ' seconds. Data rate: {:5.2f} KB/second.'.format(file_size / 1024.0 / secs_elapsed) + elif sys.argv[1] == 'navigate': + if len(sys.argv) < 3: + print 'Error! No URL given! Usage: ' + sys.argv[0] + ' ' + sys.argv[1] + ' <url>' + return 1 + browserActor = '' + for app in apps: + if app['name'] == 'Browser': + browserActor = send_b2g_cmd(webappsActorName, 'getAppActor', { 'manifestURL': app['manifestURL'] }) + break + if 'actor' in browserActor: + browserActor = browserActor['actor']['actor'] + send_b2g_cmd(browserActor, 'navigateTo', { 'url': sys.argv[2]}) + else: + print 'Web browser is not running!' + elif sys.argv[1] == 'log': + appActor = '' + for app in apps: + if str(app['localId']) == sys.argv[2] or app['name'] == sys.argv[2] or app['manifestURL'] == sys.argv[2]: + appActor = send_b2g_cmd(webappsActorName, 'getAppActor', { 'manifestURL': app['manifestURL'] }) + break + if 'actor' in appActor: + consoleActor = appActor['actor']['consoleActor'] + + if '-c' in sys.argv or '-clear' in sys.argv or '--clear' in sys.argv: + send_b2g_cmd(consoleActor, 'clearMessagesCache') + print 'Cleared message log.' + sys.exit(0) + + msgs = send_b2g_cmd(consoleActor, 'startListeners', { 'listeners': ['PageError','ConsoleAPI','NetworkActivity','FileActivity'] }) + + def log_b2g_message(msg): + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = "\033[1m" + msgs = [] + if 'type' in msg and msg['type'] == 'consoleAPICall': + msgs = [msg['message']] + elif 'messages' in msg: + msgs = msg['messages'] + + for m in msgs: + args = m['arguments'] + + for arg in args: + if m['level'] == 'log': + color = 'I/' + elif m['level'] == 'warn': + color = WARNING + 'W/' + elif m['level'] == 'error': + color = FAIL + 'E/' + else: + color = m['level'] + '/' + + print color + str(m['functionName']) + '@' + str(m['filename']) + ':' + str(m['lineNumber']) + ': ' + str(arg) + ENDC + + msgs = send_b2g_cmd(consoleActor, 'getCachedMessages', { 'messageTypes': ['PageError', 'ConsoleAPI'] }) + log_b2g_message(msgs) + + while True: + msg = read_b2g_response() + log_b2g_message(msg) + else: + print 'Application "' + sys.argv[2] + '" is not running!' + else: + print "Unknown command '" + sys.argv[1] + "'! Pass --help for instructions." + + b2g_socket.close() + return 0 + +if __name__ == '__main__': + returncode = main() + logv('ffdb.py quitting with process exit code ' + str(returncode)) + sys.exit(returncode) diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 32c26c51..2914b6e8 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1342,13 +1342,21 @@ var ASM_DOUBLE = 1; var ASM_FLOAT = 2; var ASM_NONE = 3; -function detectAsmCoercion(node, asmInfo) { +var ASM_FLOAT_ZERO = null; // TODO: share the entire node? + +function detectAsmCoercion(node, asmInfo, inVarDef) { // for params, +x vs x|0, for vars, 0.0 vs 0 if (node[0] === 'num' && node[1].toString().indexOf('.') >= 0) return ASM_DOUBLE; if (node[0] === 'unary-prefix') return ASM_DOUBLE; if (node[0] === 'call' && node[1][0] === 'name' && node[1][1] === 'Math_fround') return ASM_FLOAT; if (asmInfo && node[0] == 'name') return getAsmType(node[1], asmInfo); - if (node[0] === 'name') return ASM_NONE; + if (node[0] === 'name') { + if (!inVarDef) return ASM_NONE; + // We are in a variable definition, where Math_fround(0) optimized into a global constant becomes f0 = Math_fround(0) + if (!ASM_FLOAT_ZERO) ASM_FLOAT_ZERO = node[1]; + else assert(ASM_FLOAT_ZERO === node[1]); + return ASM_FLOAT; + } return ASM_INT; } @@ -1366,7 +1374,13 @@ function makeAsmVarDef(v, type) { switch (type) { case ASM_INT: return [v, ['num', 0]]; case ASM_DOUBLE: return [v, ['unary-prefix', '+', ['num', 0]]]; - case ASM_FLOAT: return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]]; + case ASM_FLOAT: { + if (ASM_FLOAT_ZERO) { + return [v, ['name', ASM_FLOAT_ZERO]]; + } else { + return [v, ['call', ['name', 'Math_fround'], [['num', 0]]]]; + } + } default: throw 'wha? ' + JSON.stringify([node, type]) + new Error().stack; } } @@ -1409,9 +1423,7 @@ function normalizeAsm(func) { var name = v[0]; var value = v[1]; if (!(name in data.vars)) { - assert(value[0] === 'num' || (value[0] === 'unary-prefix' && value[2][0] === 'num') // must be valid coercion no-op - || (value[0] === 'call' && value[1][0] === 'name' && value[1][1] === 'Math_fround')); - data.vars[name] = detectAsmCoercion(value); + data.vars[name] = detectAsmCoercion(value, null, true); v.length = 1; // make an un-assigning var } else { assert(j === 0, 'cannot break in the middle'); @@ -1425,22 +1437,6 @@ function normalizeAsm(func) { traverse(stats[i], function(node, type) { if (type === 'var') { assert(0, 'should be no vars to fix! ' + func[1] + ' : ' + JSON.stringify(node)); - /* - for (var j = 0; j < node[1].length; j++) { - var v = node[1][j]; - var name = v[0]; - var value = v[1]; - if (!(name in data.vars)) { - if (value[0] != 'name') { - data.vars[name] = detectAsmCoercion(value); // detect by coercion - } else { - var origin = value[1]; - data.vars[name] = data.vars[origin] || ASM_INT; // detect by origin variable, or assume int for non-locals - } - } - } - unVarify(node[1], node); - */ } else if (type === 'call' && node[1][0] === 'function') { assert(!node[1][1]); // anonymous functions only data.inlines.push(node[1]); @@ -3721,7 +3717,7 @@ function minifyGlobals(ast) { var first = true; // do not minify initial 'var asm =' // find the globals traverse(ast, function(node, type) { - if (type === 'var') { + if (type === 'var' || type === 'const') { if (first) { first = false; return; @@ -4926,36 +4922,44 @@ function safeHeap(ast) { } } } else if (type === 'sub') { - var heap = node[1][1]; - if (heap[0] !== 'H') return; - var ptr = fixPtr(node[2], heap); - // SAFE_HEAP_LOAD(ptr, bytes, isFloat) - switch (heap) { - case 'HEAP8': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '0']]], ASM_INT); - } - case 'HEAPU8': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '1']]], ASM_INT); - } - case 'HEAP16': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '0']]], ASM_INT); - } - case 'HEAPU16': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '1']]], ASM_INT); - } - case 'HEAP32': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '0']]], ASM_INT); - } - case 'HEAPU32': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '1']]], ASM_INT); - } - case 'HEAPF32': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '1'], ['num', '0']]], ASM_DOUBLE); - } - case 'HEAPF64': { - return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 8], ['num', '1'], ['num', '0']]], ASM_DOUBLE); + var target = node[1][1]; + if (target[0] === 'H') { + // heap access + var heap = target; + var ptr = fixPtr(node[2], heap); + // SAFE_HEAP_LOAD(ptr, bytes, isFloat) + switch (heap) { + case 'HEAP8': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '0']]], ASM_INT); + } + case 'HEAPU8': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 1], ['num', '0'], ['num', '1']]], ASM_INT); + } + case 'HEAP16': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '0']]], ASM_INT); + } + case 'HEAPU16': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 2], ['num', '0'], ['num', '1']]], ASM_INT); + } + case 'HEAP32': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '0']]], ASM_INT); + } + case 'HEAPU32': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '0'], ['num', '1']]], ASM_INT); + } + case 'HEAPF32': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 4], ['num', '1'], ['num', '0']]], ASM_DOUBLE); + } + case 'HEAPF64': { + return makeAsmCoercion(['call', ['name', 'SAFE_HEAP_LOAD'], [ptr, ['num', 8], ['num', '1'], ['num', '0']]], ASM_DOUBLE); + } + default: throw 'bad heap ' + heap; } - default: throw 'bad heap ' + heap; + } else { + assert(target[0] == 'F'); + // function table indexing mask + assert(node[2][0] === 'binary' && node[2][1] === '&'); + node[2][2] = makeAsmCoercion(['call', ['name', 'SAFE_FT_MASK'], [makeAsmCoercion(node[2][2], ASM_INT), makeAsmCoercion(node[2][3], ASM_INT)]], ASM_INT); } } }); @@ -4963,10 +4967,19 @@ function safeHeap(ast) { function optimizeFrounds(ast) { // collapse fround(fround(..)), which can happen due to elimination + // also emit f0 instead of fround(0) (except in returns) + var inReturn = false; function fix(node) { + if (node[0] === 'return') inReturn = true; traverseChildren(node, fix); - if (node[0] === 'call' && node[1][0] === 'name' && node[1][1] === 'Math_fround' && node[2][0][0] === 'call' && node[2][0][1][0] === 'name' && node[2][0][1][1] === 'Math_fround') { - return node[2][0]; + if (node[0] === 'return') inReturn = false; + if (node[0] === 'call' && node[1][0] === 'name' && node[1][1] === 'Math_fround') { + var arg = node[2][0]; + if (arg[0] === 'num') { + if (!inReturn && arg[1] === 0) return ['name', 'f0']; + } else if (arg[0] === 'call' && arg[1][0] === 'name' && arg[1][1] === 'Math_fround') { + return arg; + } } } traverseChildren(ast, fix); diff --git a/tools/jsrun.py b/tools/jsrun.py index f74a1492..d63451db 100644 --- a/tools/jsrun.py +++ b/tools/jsrun.py @@ -14,10 +14,10 @@ def timeout_run(proc, timeout=None, note='unnamed process', full_output=False): out = proc.communicate() out = map(lambda o: '' if o is None else o, out) if TRACK_PROCESS_SPAWNS: - logging.info('Process ' + str(proc.pid) + ' finished after ' + str(time.time() - start) + ' seconds.') + logging.info('Process ' + str(proc.pid) + ' finished after ' + str(time.time() - start) + ' seconds. Exit code: ' + str(proc.returncode)) return '\n'.join(out) if full_output else out[0] -def run_js(filename, engine=None, args=[], check_timeout=False, stdin=None, stdout=PIPE, stderr=None, cwd=None, full_output=False): +def run_js(filename, engine=None, args=[], check_timeout=False, stdin=None, stdout=PIPE, stderr=None, cwd=None, full_output=False, assert_returncode=None): if type(engine) is not list: engine = [engine] command = engine + [filename] + (['--'] if 'd8' in engine[0] or 'jsc' in engine[0] else []) + args @@ -30,8 +30,11 @@ def run_js(filename, engine=None, args=[], check_timeout=False, stdin=None, stdo timeout = 15*60 if check_timeout else None if TRACK_PROCESS_SPAWNS: logging.info('Blocking on process ' + str(proc.pid) + ': ' + str(command) + (' for ' + str(timeout) + ' seconds' if timeout else ' until it finishes.')) - return timeout_run( + ret = timeout_run( proc, timeout, 'Execution', full_output=full_output) + if assert_returncode is not None and proc.returncode is not assert_returncode: + raise Exception('Expected the command ' + str(command) + ' to finish with return code ' + str(assert_returncode) + ', but it returned with code ' + str(proc.returncode) + ' instead! Output: ' + str(ret)) + return ret diff --git a/tools/shared.py b/tools/shared.py index 82bdd98b..826baa83 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -1650,12 +1650,17 @@ class JS: return '+0' @staticmethod - def make_coercion(value, sig, settings=None): + def make_coercion(value, sig, settings=None, ffi_arg=False, ffi_result=False): settings = settings or Settings if sig == 'i': return value + '|0' elif sig == 'f' and settings.get('PRECISE_F32'): - return 'Math_fround(' + value + ')' + if ffi_arg: + return '+Math_fround(' + value + ')' + elif ffi_result: + return 'Math_fround(+(' + value + '))' + else: + return 'Math_fround(' + value + ')' elif sig == 'd' or sig == 'f': return '+' + value else: diff --git a/tools/test-js-optimizer-asm-pre-f32.js b/tools/test-js-optimizer-asm-pre-f32.js index 5471deeb..be515b36 100644 --- a/tools/test-js-optimizer-asm-pre-f32.js +++ b/tools/test-js-optimizer-asm-pre-f32.js @@ -14,4 +14,10 @@ function dupe() { x = Math_fround(Math_fround(Math_fround(x))); x = Math_fround(Math_fround(Math_fround(Math_fround(x)))); } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["badf", "badf2", "dupe"] +function zeros(x) { + x = Math_fround(x); + var y = Math_fround(0); + print(Math_fround(y) + Math_fround(0)); + return Math_fround(0); // return needs to stay as is +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["badf", "badf2", "dupe", "zeros"] diff --git a/tools/test-js-optimizer-asm-pre-output-f32.js b/tools/test-js-optimizer-asm-pre-output-f32.js index 19059619..f0f2d0da 100644 --- a/tools/test-js-optimizer-asm-pre-output-f32.js +++ b/tools/test-js-optimizer-asm-pre-output-f32.js @@ -4,7 +4,7 @@ function badf() { HEAP32[$gep23_asptr >> 2] = $9; } function badf2() { - var $9 = Math_fround(0); + var $9 = f0; $9 = Math_fround($8); HEAPF32[$gep23_asptr >> 2] = $9; } @@ -14,4 +14,10 @@ function dupe() { x = Math_fround(x); x = Math_fround(x); } +function zeros(x) { + x = Math_fround(x); + var y = f0; + print(Math_fround(y) + f0); + return Math_fround(0); +} diff --git a/tools/webidl_binder.py b/tools/webidl_binder.py new file mode 100644 index 00000000..0507cc78 --- /dev/null +++ b/tools/webidl_binder.py @@ -0,0 +1,432 @@ + +''' +WebIDL binder + +https://github.com/kripken/emscripten/wiki/WebIDL-Binder +''' + +import os, sys + +import shared + +sys.path.append(shared.path_from_root('third_party')) +sys.path.append(shared.path_from_root('third_party', 'ply')) + +import WebIDL + +class Dummy: + def __init__(self, init): + for k, v in init.iteritems(): + self.__dict__[k] = v + + def getExtendedAttribute(self, name): + return None + +input_file = sys.argv[1] +output_base = sys.argv[2] + +shared.try_delete(output_base + '.cpp') +shared.try_delete(output_base + '.js') + +p = WebIDL.Parser() +p.parse(open(input_file).read()) +data = p.finish() + +interfaces = {} +implements = {} + +for thing in data: + if isinstance(thing, WebIDL.IDLInterface): + interfaces[thing.identifier.name] = thing + elif isinstance(thing, WebIDL.IDLImplementsStatement): + implements.setdefault(thing.implementor.identifier.name, []).append(thing.implementee.identifier.name) + +#print interfaces +#print implements + +pre_c = [] +mid_c = [] +mid_js = [] + +pre_c += [r''' +#include <emscripten.h> +'''] + +mid_c += [r''' +extern "C" { +'''] + +def emit_constructor(name): + global mid_js + mid_js += [r'''%s.prototype = %s; +%s.prototype.constructor = %s; +%s.prototype.__class__ = %s; +%s.__cache__ = {}; +Module['%s'] = %s; +''' % (name, 'Object.create(%s.prototype)' % (implements[name][0] if implements.get(name) else 'WrapperObject'), name, name, name, name, name, name, name)] + + +mid_js += [''' +// Bindings utilities + +function WrapperObject() { +} +'''] + +emit_constructor('WrapperObject') + +mid_js += [''' +function getCache(__class__) { + return (__class__ || WrapperObject).__cache__; +} +Module['getCache'] = getCache; + +function wrapPointer(ptr, __class__) { + var cache = getCache(__class__); + var ret = cache[ptr]; + if (ret) return ret; + ret = Object.create((__class__ || WrapperObject).prototype); + ret.ptr = ptr; + return cache[ptr] = ret; +} +Module['wrapPointer'] = wrapPointer; + +function castObject(obj, __class__) { + return wrapPointer(obj.ptr, __class__); +} +Module['castObject'] = castObject; + +Module['NULL'] = wrapPointer(0); + +function destroy(obj) { + if (!obj['__destroy__']) throw 'Error: Cannot destroy object. (Did you create it yourself?)'; + obj['__destroy__'](); + // Remove from cache, so the object can be GC'd and refs added onto it released + delete getCache(obj.__class__)[obj.ptr]; +} +Module['destroy'] = destroy; + +function compare(obj1, obj2) { + return obj1.ptr === obj2.ptr; +} +Module['compare'] = compare; + +function getPointer(obj) { + return obj.ptr; +} +Module['getPointer'] = getPointer; + +function getClass(obj) { + return obj.__class__; +} +Module['getClass'] = getClass; + +// Converts a value into a C-style string. +function ensureString(value) { + if (typeof value == 'string') return allocate(intArrayFromString(value), 'i8', ALLOC_STACK); + return value; +} + +'''] + +C_FLOATS = ['float', 'double'] + +def type_to_c(t, non_pointing=False): + #print 'to c ', t + t = t.replace(' (Wrapper)', '') + if t == 'Long': + return 'int' + elif t == 'Short': + return 'short' + elif t == 'Void': + return 'void' + elif t == 'String': + return 'char*' + elif t == 'Float': + return 'float' + elif t == 'Double': + return 'double' + elif t == 'Boolean': + return 'bool' + elif t in interfaces: + return (interfaces[t].getExtendedAttribute('Prefix') or [''])[0] + t + ('' if non_pointing else '*') + else: + return t + +def take_addr_if_nonpointer(m): + if m.getExtendedAttribute('Ref') or m.getExtendedAttribute('Value'): + return '&' + return '' + +def deref_if_nonpointer(m): + if m.getExtendedAttribute('Ref') or m.getExtendedAttribute('Value'): + return '*' + return '' + +def type_to_cdec(raw): + name = ret = type_to_c(raw.type.name, non_pointing=True) + if raw.getExtendedAttribute('Const'): ret = 'const ' + ret + if name not in interfaces: return ret + if raw.getExtendedAttribute('Ref'): + return ret + '&' + if raw.getExtendedAttribute('Value'): + return ret + return ret + '*' + +def render_function(class_name, func_name, sigs, return_type, non_pointer, copy, operator, constructor, func_scope, call_content=None, const=False): + global mid_c, mid_js, js_impl_methods + + #print 'renderfunc', class_name, func_name, sigs, return_type, constructor + + bindings_name = class_name + '_' + func_name + min_args = min(sigs.keys()) + max_args = max(sigs.keys()) + + c_names = {} + + # JS + + cache = ('getCache(%s)[this.ptr] = this;' % class_name) if constructor else '' + call_prefix = '' if not constructor else 'this.ptr = ' + call_postfix = '' + if return_type != 'Void' and not constructor: call_prefix = 'return ' + if not constructor: + if return_type in interfaces: + call_prefix += 'wrapPointer(' + call_postfix += ', ' + return_type + ')' + + args = ['arg%d' % i for i in range(max_args)] + if not constructor: + body = ' var self = this.ptr;\n' + pre_arg = ['self'] + else: + body = '' + pre_arg = [] + + for i in range(max_args): + # note: null has typeof object, but is ok to leave as is, since we are calling into asm code where null|0 = 0 + body += " if (arg%d && typeof arg%d === 'object') arg%d = arg%d.ptr;\n" % (i, i, i, i) + body += " else arg%d = ensureString(arg%d);\n" % (i, i) + + for i in range(min_args, max_args): + c_names[i] = 'emscripten_bind_%s_%d' % (bindings_name, i) + body += ' if (arg%d === undefined) { %s%s(%s)%s%s }\n' % (i, call_prefix, '_' + c_names[i], ', '.join(pre_arg + args[:i]), call_postfix, '' if 'return ' in call_prefix else '; ' + (cache or ' ') + 'return') + c_names[max_args] = 'emscripten_bind_%s_%d' % (bindings_name, max_args) + body += ' %s%s(%s)%s;\n' % (call_prefix, '_' + c_names[max_args], ', '.join(pre_arg + args), call_postfix) + if cache: + body += ' ' + cache + '\n' + mid_js += [r'''function%s(%s) { +%s +}''' % ((' ' + func_name) if constructor else '', ', '.join(args), body[:-1])] + + # C + + for i in range(min_args, max_args+1): + raw = sigs.get(i) + if raw is None: continue + sig = [arg.type.name for arg in raw] + + c_arg_types = map(type_to_c, sig) + + normal_args = ', '.join(['%s arg%d' % (c_arg_types[j], j) for j in range(i)]) + if constructor: + full_args = normal_args + else: + full_args = type_to_c(class_name, non_pointing=True) + '* self' + ('' if not normal_args else ', ' + normal_args) + call_args = ', '.join(['%sarg%d' % ('*' if raw[j].getExtendedAttribute('Ref') else '', j) for j in range(i)]) + if constructor: + call = 'new ' + type_to_c(class_name, non_pointing=True) + call += '(' + call_args + ')' + elif call_content is not None: + call = call_content + else: + call = 'self->' + func_name + call += '(' + call_args + ')' + + if operator: + assert '=' in operator, 'can only do += *= etc. for now, all with "="' + cast_self = 'self' + if class_name != func_scope: + # this function comes from an ancestor class; for operators, we must cast it + cast_self = 'dynamic_cast<' + type_to_c(func_scope) + '>(' + cast_self + ')' + call = '(*%s %s %sarg0)' % (cast_self, operator, '*' if sig[0] in interfaces else '') + + pre = '' + + basic_return = 'return ' if constructor or return_type is not 'Void' else '' + return_prefix = basic_return + return_postfix = '' + if non_pointer: + return_prefix += '&'; + if copy: + pre += ' static %s temp;\n' % type_to_c(return_type, non_pointing=True) + return_prefix += '(temp = ' + return_postfix += ', &temp)' + + c_return_type = type_to_c(return_type) + mid_c += [r''' +%s%s EMSCRIPTEN_KEEPALIVE %s(%s) { +%s %s%s%s; +} +''' % ('const ' if const else '', type_to_c(class_name) if constructor else c_return_type, c_names[i], full_args, pre, return_prefix, call, return_postfix)] + + if not constructor: + if i == max_args: + dec_args = ', '.join(map(lambda j: type_to_cdec(raw[j]) + ' arg' + str(j), range(i))) + js_call_args = ', '.join(['%sarg%d' % (('(int)' if sig[j] in interfaces else '') + ('&' if raw[j].getExtendedAttribute('Ref') or raw[j].getExtendedAttribute('Value') else ''), j) for j in range(i)]) + + js_impl_methods += [r''' %s %s(%s) { + %sEM_ASM_%s({ + var self = Module['getCache'](Module['%s'])[$0]; + if (!self.hasOwnProperty('%s')) throw 'a JSImplementation must implement all functions, you forgot %s::%s.'; + %sself.%s(%s)%s; + }, (int)this%s); + }''' % (c_return_type, func_name, dec_args, + basic_return, 'INT' if c_return_type not in C_FLOATS else 'DOUBLE', + class_name, + func_name, class_name, func_name, + return_prefix, + func_name, + ','.join(['$%d' % i for i in range(1, max_args)]), + return_postfix, + (', ' if js_call_args else '') + js_call_args)] + + +for name, interface in interfaces.iteritems(): + js_impl = interface.getExtendedAttribute('JSImplementation') + if not js_impl: continue + implements[name] = [js_impl[0]] + +names = interfaces.keys() +names.sort(lambda x, y: 1 if implements.get(x) and implements[x][0] == y else (-1 if implements.get(y) and implements[y][0] == x else 0)) + +for name in names: + interface = interfaces[name] + + mid_js += ['\n// ' + name + '\n'] + mid_c += ['\n// ' + name + '\n'] + + global js_impl_methods + js_impl_methods = [] + + cons = interface.getExtendedAttribute('Constructor') + if type(cons) == list: raise Exception('do not use "Constructor", instead create methods with the name of the interface') + + js_impl = interface.getExtendedAttribute('JSImplementation') + if js_impl: + js_impl = js_impl[0] + + # Methods + + seen_constructor = False # ensure a constructor, even for abstract base classes + for m in interface.members: + if m.identifier.name == name: + seen_constructor = True + break + if not seen_constructor: + mid_js += ['function %s() { throw "cannot construct a %s, no constructor in IDL" }\n' % (name, name)] + emit_constructor(name) + + for m in interface.members: + if not m.isMethod(): continue + constructor = m.identifier.name == name + if not constructor: + parent_constructor = False + temp = m.parentScope + while temp.parentScope: + if temp.identifier.name == m.identifier.name: + parent_constructor = True + temp = temp.parentScope + if parent_constructor: + continue + if not constructor: + mid_js += [r''' +%s.prototype.%s = ''' % (name, m.identifier.name)] + sigs = {} + return_type = None + for ret, args in m.signatures(): + if return_type is None: + return_type = ret.name + else: + assert return_type == ret.name, 'overloads must have the same return type' + for i in range(len(args)+1): + if i == len(args) or args[i].optional: + assert i not in sigs, 'overloading must differentiate by # of arguments (cannot have two signatures that differ by types but not by length)' + sigs[i] = args[:i] + render_function(name, + m.identifier.name, sigs, return_type, + m.getExtendedAttribute('Ref'), + m.getExtendedAttribute('Value'), + (m.getExtendedAttribute('Operator') or [None])[0], + constructor, + func_scope=m.parentScope.identifier.name) + mid_js += [';\n'] + if constructor: + emit_constructor(name) + + for m in interface.members: + if not m.isAttr(): continue + attr = m.identifier.name + + get_name = 'get_' + attr + mid_js += [r''' + %s.prototype.%s= ''' % (name, get_name)] + render_function(name, + get_name, { 0: [] }, m.type.name, + None, + None, + None, + False, + func_scope=interface, + call_content=take_addr_if_nonpointer(m) + 'self->' + attr, + const=m.getExtendedAttribute('Const')) + + set_name = 'set_' + attr + mid_js += [r''' + %s.prototype.%s= ''' % (name, set_name)] + render_function(name, + set_name, { 1: [Dummy({ 'type': m.type })] }, 'Void', + None, + None, + None, + False, + func_scope=interface, + call_content='self->' + attr + ' = ' + deref_if_nonpointer(m) + 'arg0', + const=m.getExtendedAttribute('Const')) + + if not interface.getExtendedAttribute('NoDelete'): + mid_js += [r''' + %s.prototype.__destroy__ = ''' % name] + render_function(name, + '__destroy__', { 0: [] }, 'Void', + None, + None, + None, + False, + func_scope=interface, + call_content='delete self') + + # Emit C++ class implementation that calls into JS implementation + + if js_impl: + pre_c += [r''' +class %s : public %s { +public: +%s +}; +''' % (name, type_to_c(js_impl, non_pointing=True), '\n'.join(js_impl_methods))] + +mid_c += ['\n}\n\n'] +mid_js += ['\n'] + +# Write + +c = open(output_base + '.cpp', 'w') +for x in pre_c: c.write(x) +for x in mid_c: c.write(x) +c.close() + +js = open(output_base + '.js', 'w') +for x in mid_js: js.write(x) +js.close() + |