• Derp (unregistered)

    Frist

  • itsme (unregistered)

    it still could have been a switch in the original source code. but in the compiling step it could have been rendered with ifs and several inlined functions

  • Hugo (unregistered)

    I would be neither surprised nor shocked to see code as this being created by a code generator. I really hope that nobody every actually typed this.

  • Bert (unregistered)

    So let me guess, TRWTF is the decompiler couldn't recognise a sequence of check/branch statements as a switch block, and instead output a big nested block of ifs?

  • TheCPUWizard (unregistered)

    The decompilation comments are spot on - NEVER that that output as the original developers input.

    Now if one want to focus on OO, then neither nested ifs or cases would have been appropriate, instead a proper registerable dispatch mechanism would have been utilized; making the "some case statements would have been nice" potentially TRWTF.

  • Oliver Jones (google)

    Yeah. Compiler processing switch(string) statement. For sure.

  • Puzzl´d (unregistered)

    Flash, ah ah, savior of the universe...

  • Falco20019 (unregistered)

    I can see the JNE (jump not equal) operations here...

  • Appalled (unregistered)

    No clue what language that is but I wouldn't even have used Case. I'd have used Positive, not negative if's, and a GoTo AllDone as the last statement for each positive block. Of course, if JNE in this language means some sort of GoTo, i'm in partial agreement as long as there's a straight JMP as well. Negative logic sucks eggs.

    Finally for all you GOTO less freaks, take a hike and stick to the (very) few (thank god) languages that have deprecated GOTO.

    Finally, you all realize that the actual machine code the compiler produces is all GOTO's, right?

  • Andrew (unregistered)

    I worked at a place that had a Java EE app that I later figured out was written by a bunch of Oracle DB admins. There were some strange patterns everywhere, like:

    if (condition) { } else { // actual logic }

    They had lots of class level date formatters in singletons. (They aren't thread safe!) I wonder how many support tickets for changing a date were caused by that. And no one even bothered to build or figure out a universal nav menu system, since each page had its own buggy nav menu.

  • Angela Anuszewski (google) in reply to Andrew

    I have seen a handful of occasions where doing that is useful from a self-documenting code standpoint, but I can't imagine it becoming a regular practice.

  • Ron Fox (google) in reply to Appalled

    Well in FORTRAN you could have also used an arithmetic if to get both sides at once :-)

  • Publius (unregistered) in reply to Appalled

    Finally, you all realize that the actual machine code the compiler produces is all GOTO's, right?

    So my question is, what are you even doing in a 3GL then? You realize that the actual machine code the compiler produces is all machine code, right?

  • jcabello (unregistered) in reply to Puzzl´d

    Flash, a ah he'll save everyone of us

  • What ever happened to jump tables (unregistered)

    I mean really?

    Even 30 years ago people would drive that with a table of strings with function pointers rather than nested if statements or switch/case statements.

  • isthisunique (unregistered) in reply to Appalled

    No one should ever use if statements or switchs when you can use LUTS. Javascript and Action script support this directly in RPC style. objmethod

  • ab (unregistered)

    Lisp anyone?

  • Martin (unregistered)

    LOL!!! I remembered my childhood. WARNING: You have 10 seconds to deactivate the instruction inside the IF nest before this message self destructs :)

  • Junell (unregistered)

    I agree with Hugo, this really looks like something produced by a code generator or a compiler that compiles to javascript rather than something that a human would code.

  • wtf (unregistered)

    TRWTF is Flash.

  • Foo AKA Fooo (unregistered) in reply to Publius

    I wonder if goto proponents really believe this, or they're just trolling.

    Funnily, this is exactly the same kind of confusion (compiler input vs. output) as (probably) the non-WTF today (confusing the decompiler output with the original source).

    It would be fun to see such people comment on the decompiled output of some highly optimized C++ compiled code (no local variable names, many inlined functions and rearranged code blocks, return value optimizations, tail calls, register reuse, etc.).

  • drkstr101 (unregistered) in reply to itsme

    As someone who has worked on/with the Falcon compiler, I can say that this is exactly what happened. This is auto-generated source from something that basically amounts to byte code. Fail submission.

  • Me (unregistered)

    Source code that is generated from a decompiler is worthy of submission to TDWTF?

  • Sham (unregistered)

    Decompiled code isn't pretty, who knew? TRWTF is this article.

  • Norman Diamond (unregistered)

    You realize that the actual machine code the compiler produces is all machine code, right?

    Not always. Some compilers produce assembly source code which has to be run through an assembler.

    When I wrote a compiler to translate LISP to C, or one to translate MATLAB to C++, the source code that I generated was pretty miserable too. The output didn't have to be human readable, it just had to be compilable by a C or C++ compiler and produce correct results. Of course the machine code (or assembly source code) produced by each C or C++ compiler would be pretty miserable, and if decompiled they would be unpretty miserable just like the stuff that confused the submitter and editor of this article.

  • LK (unregistered)

    Posting code from a decompiler.
    Come on, what's next, posting 20 year old VB projects?

  • FRED (unregistered)

    If that's compiled code, it does appear to be pretty f'd code coming out of that compiler. I've never seen anything this bad come out of an ordinary 3G language: my guess is that this is the result of something like a registerable dispatch mechanism.

  • Scott Christian Simmons (unregistered)

    There are an astonishing number of people here who think Flash compiles to machine code.

    News flash: Flash doesn't compile to machine code. A decent decompiler should recover the actual structure of the original source code, unless the compiler was designed to intentionally obfuscate it.

  • Watson (nodebb)

    Assuming that the translation to the target language can and does retain all the semantics of the control structures used in the source language. If not (such as Flash p-code, which has "jump if true" as its sole branch construct), then the decompiler has to throw a bunch of pattern-matching heuristics at the compiled code and guess.

  • Steve_The_Cynic (nodebb) in reply to Norman Diamond

    And don't forget the first C++ compiler, cfront, which compiled (a primitive version of) C++ to C.

  • Appalled (unregistered)

    If you've never coded in Assembly Language, you don't know what you're talking about in regards to machine code, goto's, compiling, or decompiling. You're just guessing at the way you think things ought to be.

    Compiling means generating machine code, PERIOD. In Assembler your looking at the actual machine code, just dressed up with variable names so you don't have to key in (and somehow keep track of) all the Op Codes and Hex addresses. So except for pretty names (limited to 8 characters in a lot of them) you're working at the machine code level itself. And there are no If statements in Assembler/Machine code, only compares and branches (goto's). So, somewhat facetiously, I said you may as well use goto's yourself since that's what you wind up with any way.

    Now that I've read a lot of comments and understand that it was Flash generating the Javascript code seen in the article, it seems there is no compiling or de-compiing going on at all here. The Flash-->Javascript and reverse is called Translating (or generating) and detranslating, not compiling.

    We also have one final layer Javascript-->machine code at the client. This compiles temporary machine code from the Javascript source and immediately runs it. But it's called Interpreting because it's at run-time rather than ahead of time.

  • Koen van Dratel (unregistered) in reply to Appalled

    You are so right, we should stay in tune with how computer work. Personally, I not only reject GoTo-less code, but also any code snippet that uses more than 8 variables in one context. Someday people will realize that abstracting from registers in 3GL was another huge mistake! Don't get me started on those pesky "functions"; their only purpose is to obfuscate what stacks are about, making modern languages just about unreadable.

  • Steve_The_Cynic (nodebb) in reply to Appalled

    We won't speak about macro assemblers, then, I guess...

    Nor about instructions like DJNZ (Z-80), REP (x86), LOOP (also x86), etc., nor the IBM System/370's EDIT, nor the 6809's BRN(1), nor indirect jumps using registers as pre- or post-lookup offsets, nor a thousand and one other oddities.

    And, to be honest, what you wrote sounds very much like someone who has heard of assembly language rather than used it.

    (1) A decoding oddity in its branching instruction group, which was organised into pairs of instructions, one of which branched if the condition was true, while the other branched if the condition was false. The conditions were the usual stuff like "zero-flag set" or "carry flag set", and, of course, one of the conditions was "true". That pair of instructions was "BRA" (no giggles from the back row, please) for BRanch Always, and BRN for BRanch Never.

    AND...

    No, it wasn't Flash generating JavaScript in the article. The code in the article was the result of decompiling Flash's ActionScript. JavaScript and ActionScript are both versions of (or at least derived from, although the history is a little murky) ECMAScript, and consequently they do somewhat resemble each other.

  • Appalled (unregistered) in reply to Steve_The_Cynic

    12 years OS 360/370/390 full time applications programmer half and half Assembler and COBOL. Batch and CICS. 100's of Dump reads for both.

    I know how to operate at the machine level, albeit mainframes only. I toned it down for this audience.

    How bout you tell us why using the EX instruction is the worst thing you could do to posterity. I came across it twice in my travels and "refactored" it, cussing at the idiot who used it all the way.

  • Steve_The_Cynic (nodebb) in reply to Appalled

    Good Lord, EX? I know just enough to remember that that instruction exists. I eventually found a resource that explained (fairly clearly) what it does, and ... um ... no. Just no.

    https://sites.google.com/site/ibmmainframeassembly/Home/mnemonics/ex--execute

    If they had made it only work with MVC, then it is marginally reasonable on a very, very good day because it becomes a selectable-length move (but a proper selectable-length move would have been better). However, the examples in the page make it clear that it's fragile and only marginally better than actual self-modifying code. (Alternative interpretation: significantly worse, because at least with self-modifying code, you know something's up, while EX looks like a legitimate mechanism...)

    The effect is dependent on the specific details of the target instruction (which is part of the badness), but the main thing is that it is a rather twisted variation on eval, and little more needs to be said.

    And microcomputer assembly is a little different because the most popular CPUs lack the facilities of mainframe and minicomputer instruction sets. (That said, at least every microprocessor I've ever worked on actually has a real machine stack with actual push and pop instructions, something I don't recall on the 360 family - whence a message about memory allocation failures when my studentish Pascal program on a 3081D got a case of runaway recursion. It was calling a heap allocator to allocate activation records, and ran out of memory, but the message was a little surprising.)

  • Norman Diamond (unregistered)

    That pair of instructions was "BRA" (no giggles from the back row, please)

    Yeah, save your giggles for the sign exchange instruction.

  • Norman Diamond (unregistered)
    Comment held for moderation.
  • Steve_The_Cynic (nodebb) in reply to Norman Diamond

    Sign EXtend, not EXchange, but yeah, that's problematic. Probably why it's called CBW (Convert Byte to Word) in Intel's 8086 mnemonics...

    That said, there's always SeT Interrupt (flag) on those same mnemonics. STI FTW!

  • Appalled (unregistered) in reply to Norman Diamond

    Self-modifying code is OK? Yeah I guess you're right, nowadays. Who gives a shit. No-one reads dumps (executables) any more , regardless of platform, except Virus Anlayzers. Just Reboot, Restart the Server, etc. and cross your fingers. If that don't work, figure out what record was in process and examine it for peculiarities. When all else fails run it in Debug/Trace until you stumble into the offending instruction. It doesn't really matter HOW you get there right? But that wasn't my question. My question was why EX is the worst thing for posterity on an IBM OS 360/370/390 platform. You apparently understnad what it is, but find it perfectly acceptable, an impasse that will never be broken. BTW, macros generate small bits of code to insert into the Assembler stream, it's still Code, it's still compiled, it still produces machine code. So what's your point?

    Steve, EX in OS 3xx means, "Alter the instruction at Address (In assembler it would have a label for ease of use, to become such and such, execute it right now, and every time the code next walks into that instruction. Typically, and probably invented for, First-Time logic rather than checking a flag. As compiled the instruction would say "B FirstADDR". After the EX (usually the last statement in the code-block for FirstADDR) it will say (in the executable ONLY) "B MainAddr". But you can do ANYTHING you want. So you're reading a dump to solve a problem and the Code doesn't match the source and you go WTFFFFFFFFFFFFFFFFFFFFFFFF? After searching Source Libraries, recompiling, rerunning, etc., when you finally figure it out, more curses start. BTW the Alter verb in COBOL compiles directly into an EX. Google up COBOL Alter. It may give a better description of this atrocity.

    I read the Story of Mel. It's pretty barbaric. I'd like to think it wouldn't have taken me "two weeks", but new to the language it could have been 2 months of continuous "WTF did he do? WTF did he do? WTF did he DOOOOOOOOOOOOOOOOOO???"

  • Janez (unregistered)

    It is always nice to scroll through this code. Makes you dizzy.

  • Norman Diamond (unregistered)

    "I've used self-modifying code on a machine older than the 360."

    'Self-modifying code is OK? Yeah I guess you're right, nowadays.'

    If you mean "nowadays" in a geological sense.

    'No-one reads dumps (executables) any more , regardless of platform, except Virus Anlayzers.'

    Not even to find which driver caused a BSOD? (When it's not Windows 10's memory manager, it might be a driver.)

    'My question was why EX is the worst thing for posterity on an IBM OS 360/370/390 platform. You apparently understnad what it is, but find it perfectly acceptable'

    I said self-modifying code is worse than the EX instruction, but you apparently DON'T understand what it is, and you find that perfectly acceptable. OK that's enough for me, bye.

  • foxyshadis (unregistered) in reply to Watson

    "If not (such as Flash p-code, which has "jump if true" as its sole branch construct), then the decompiler has to throw a bunch of pattern-matching heuristics at the compiled code and guess."

    Morons like you should be tagged so that everyone knows that you will spout complete nonsense you pulled out of your ass. AS3 has 15 separate branch statements: jump jumpifeq jumpiffalse jumpifge jumpifgt jumpifle jumpiflt jumpifne jumpifnge jumpifngt jumpifnle jumpifnlt jumpifstricteq jumpifstrictne jumpiftrue

    And because unobfuscated Flash isn't optimized, there's no need for "heuristics" in finding switch statements: There's just one pattern, that's been used for over a decade. While that's a serious weakness in Flash and an ongoing source of its shittiness, it's a huge boon to reversers.

  • Appalled (unregistered) in reply to Norman Diamond

    Hey Moron,

    1. You never explicitly said "self-modifying code is worse than the EX instruction" until your latest rant.

    2. The EX Instruction IS self-modifying code.

    3. How can it be better or worse than itself?

    4. You're an idiot, go back to pretending you're a Windows programmer.

  • Former VM/MVS SysProg (unregistered) in reply to Appalled

    EX is not self-modifying, not in the sense that memory the code resides in is being changed. (EX takes a copy of the IN-MEMORY target instruction, modifies it IN-PROCESSOR with the operand, and executes that instruction. But the IN-MEMORY target instruction is not altered.) EX can be used gracefully to simplify code. Use with, for example, MVC. Or, it can be used poorly, in ways that obfuscate the code.

  • Norman Diamond (unregistered)

    ex-VM/MVS SysProg is correct.

    Though incidentally Cobol's ALTER is like self-modifying code, equally persistent as self-modifying code and some appalling stupidity. Thar's why EX isn't the worst thing ever.

  • Hannes (unregistered)

    Looks like some of the code my pre-predecessor wrote. 32 nested if-else-statemens, repeated 4 times in the same method. Oh, the fun...

Leave a comment on “It Takes One Function”

Log In or post as a guest

Replying to comment #:

« Return to Article