''' Processes an LLVM assembly (.ll) file, adding debugging information. You can then run the .ll file in the LLVM interpreter (lli) and compare that to the output when compiled using emscripten. Warning: You probably want to compile with SKIP_STACK_IN_SMALL=0! Otherwise there may be weird errors. ''' import os, sys, re ALLOW_POINTERS = False ALLOW_MISC = True MEMCPY = False NO_DLMALLOC = True POSTAMBLE = ''' @.emscripten.autodebug.str = private constant [10 x i8] c"AD:%d,%d\\0A\\00", align 1 ; [#uses=1] @.emscripten.autodebug.str.f = private constant [11 x i8] c"AD:%d,%lf\\0A\\00", align 1 ; [#uses=1] @.emscripten.autodebug.str.64 = private constant [13 x i8] c"AD:%d,%d,%d\\0A\\00", align 1 ; [#uses=1] ; [#uses=1] define void @emscripten_autodebug_i64(i32 %line, i64 %value) { entry: %0 = trunc i64 %value to i32 %1 = lshr i64 %value, 32 %2 = trunc i64 %1 to i32 %3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.emscripten.autodebug.str.64, i32 0, i32 0), i32 %line, i32 %0, i32 %2) ; [#uses=0] br label %return return: ; preds = %entry ret void } ; [#uses=1] define void @emscripten_autodebug_i32(i32 %line, i32 %value) { entry: %0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %value) ; [#uses=0] br label %return return: ; preds = %entry ret void } ; [#uses=1] define void @emscripten_autodebug_i16(i32 %line, i16 %value) { entry: %0 = zext i16 %value to i32 ; [#uses=1] %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %0) ; [#uses=0] br label %return return: ; preds = %entry ret void } ; [#uses=1] define void @emscripten_autodebug_i8(i32 %line, i8 %value) { entry: %0 = zext i8 %value to i32 ; [#uses=1] %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %0) ; [#uses=0] br label %return return: ; preds = %entry ret void } ; [#uses=1] define void @emscripten_autodebug_float(i32 %line, float %value) { entry: %0 = fpext float %value to double ; [#uses=1] %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %0) ; [#uses=0] br label %return return: ; preds = %entry ret void } ; [#uses=1] define void @emscripten_autodebug_double(i32 %line, double %value) { entry: %0 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %value) ; [#uses=0] br label %return return: ; preds = %entry ret void } ''' POSTAMBLE_NEW = ''' @.emscripten.autodebug.str = private constant [10 x i8] c"AD:%d,%d\\0A\\00", align 1 ; [#uses=1] @.emscripten.autodebug.str.f = private constant [11 x i8] c"AD:%d,%lf\\0A\\00", align 1 ; [#uses=1] ; [#uses=1] define void @emscripten_autodebug_i64(i32 %line, i64 %value) { %1 = sitofp i64 %value to double %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %1) ; [#uses=0] ret void } ; [#uses=1] define void @emscripten_autodebug_i32(i32 %line, i32 %value) { %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %value) ; [#uses=0] ret void } ; [#uses=1] define void @emscripten_autodebug_i16(i32 %line, i16 %value) { %1 = zext i16 %value to i32 ; [#uses=1] %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %1) ; [#uses=0] ret void } ; [#uses=1] define void @emscripten_autodebug_i8(i32 %line, i8 %value) { %1 = zext i8 %value to i32 ; [#uses=1] %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10 x i8]* @.emscripten.autodebug.str, i32 0, i32 0), i32 %line, i32 %1) ; [#uses=0] ret void } ; [#uses=1] define void @emscripten_autodebug_float(i32 %line, float %value) { %1 = fpext float %value to double ; [#uses=1] %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %1) ; [#uses=0] ret void } ; [#uses=1] define void @emscripten_autodebug_double(i32 %line, double %value) { %1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %value) ; [#uses=0] ret void } ''' filename, ofilename = sys.argv[1], sys.argv[2] f = open(filename, 'r') data = f.read() f.close() if 'declare i32 @printf(' not in data: POSTAMBLE += ''' ; [#uses=1] declare i32 @printf(i8*, ...) ''' LLVM_STYLE_OLD = '