-- Inlines nested code blocks -- $Id$ module InlineCodeblocks; metamodel EMFTVM; transform M : EMFTVM; -- ====================================================================== -- Inline INVOKE_CB stage -- ====================================================================== rule LocalVariableInstructionWithoutSlot { from lv : EMFTVM!LocalVariable, lvi : EMFTVM!LocalVariableInstruction (localVariable =~ lv, slot =~ -1) to lv : EMFTVM!LocalVariable, lvi : EMFTVM!LocalVariableInstruction (localVariable =~ lv) } rule RetargetInvokeCbLocalVariableStart { from lv : EMFTVM!LocalVariable (startInstruction =~ invokeCb), invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock (code =~ first), first : EMFTVM!Instruction to lv : EMFTVM!LocalVariable (startInstruction =~ first), invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock (code =~ first), first : EMFTVM!Instruction } rule RetargetInvokeCbLocalVariableEnd { from lv : EMFTVM!LocalVariable (endInstruction =~ invokeCb), invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock (code =~| last), last : EMFTVM!Instruction to lv : EMFTVM!LocalVariable (endInstruction =~ last), invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock (code =~ last), last : EMFTVM!Instruction } abstract rule InvokeCb { from cb : EMFTVM!CodeBlock (code =~ invokeCb), invokeCb : EMFTVM!InvokeCb to cb : EMFTVM!CodeBlock (code =~ invokeCb), invokeCb : EMFTVM!InvokeCb } rule InvokeCb_InlineLocals extends InvokeCb { from cb : EMFTVM!CodeBlock, invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock (localVariables =~ lv), lv : EMFTVM!LocalVariable (slot =~ lv.slot) to cb : EMFTVM!CodeBlock (localVariables =~ lv), invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock, lv : EMFTVM!LocalVariable } rule InvokeCb_Inline extends InvokeCb { from cb : EMFTVM!CodeBlock, invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock not nestedCb : EMFTVM!CodeBlock (localVariables =~ lv), lv : EMFTVM!LocalVariable to cb : EMFTVM!CodeBlock ( code =~ nestedCb.code before invokeCb, lineNumbers =~ nestedCb.lineNumbers, nested =~ nestedCb.nested before nestedCb), invokeCb : EMFTVM!InvokeCb } rule InvokeCb_ResetMax extends InvokeCb { from cb : EMFTVM!CodeBlock ( maxLocals =~ cb.maxLocals, maxStack =~ cb.maxStack), invokeCb : EMFTVM!InvokeCb not invokeCb : EMFTVM!InvokeCb (codeBlock =~ nestedCb), nestedCb : EMFTVM!CodeBlock to cb : EMFTVM!CodeBlock } rule EmptyLineNumber { from ln : EMFTVM!LineNumber not instr : EMFTVM!Instruction (lineNumber =~ ln) } -- ====================================================================== -- Inline INVOKE_ALL_CBS stage -- ====================================================================== abstract rule InvokeAllCbs { from cb : EMFTVM!CodeBlock (code =~ invokeAllCbs), invokeAllCbs : EMFTVM!InvokeAllCbs to cb : EMFTVM!CodeBlock (code =~ invokeAllCbs), invokeAllCbs : EMFTVM!InvokeAllCbs } rule RetargetInvokeAllCbsLocalVariableStart extends InvokeAllCbs { from cb : EMFTVM!CodeBlock (nested =~ nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, lv : EMFTVM!LocalVariable (startInstruction =~ invokeAllCbs), nestedCb : EMFTVM!CodeBlock (code =~ first), first : EMFTVM!Instruction to cb : EMFTVM!CodeBlock (nested =~ nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, lv : EMFTVM!LocalVariable (startInstruction =~ first), nestedCb : EMFTVM!CodeBlock (code =~ first), first : EMFTVM!Instruction } rule RetargetInvokeAllCbsLocalVariableEnd extends InvokeAllCbs { from cb : EMFTVM!CodeBlock (nested =~| nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, lv : EMFTVM!LocalVariable (endInstruction =~ invokeAllCbs), nestedCb : EMFTVM!CodeBlock (code =~| last), last : EMFTVM!Instruction to cb : EMFTVM!CodeBlock (nested =~ nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, lv : EMFTVM!LocalVariable (endInstruction =~ last), nestedCb : EMFTVM!CodeBlock (code =~ last), last : EMFTVM!Instruction } rule InvokeAllCbs_inline_locals extends InvokeAllCbs { from cb : EMFTVM!CodeBlock (nested =~ nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, nestedCb : EMFTVM!CodeBlock (localVariables =~ lv), lv : EMFTVM!LocalVariable (slot =~ lv.slot) to cb : EMFTVM!CodeBlock ( nested =~ nestedCb, localVariables =~ lv), invokeAllCbs : EMFTVM!InvokeAllCbs, nestedCb : EMFTVM!CodeBlock, lv : EMFTVM!LocalVariable } rule InvokeAllCbs_inline extends InvokeAllCbs { from cb : EMFTVM!CodeBlock (nested =~ nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs, nestedCb : EMFTVM!CodeBlock not nestedCb : EMFTVM!CodeBlock (localVariables =~ lv), lv : EMFTVM!LocalVariable to cb : EMFTVM!CodeBlock ( code =~ nestedCb.code before invokeAllCbs, lineNumbers =~ nestedCb.lineNumbers, nested =~ nestedCb.nested before nestedCb), invokeAllCbs : EMFTVM!InvokeAllCbs } rule InvokeAllCbs_maxreset extends InvokeAllCbs { from cb : EMFTVM!CodeBlock ( maxStack =~ cb.maxStack, maxLocals =~ cb.maxLocals), invokeAllCbs : EMFTVM!InvokeAllCbs not cb : EMFTVM!CodeBlock (nested =~ nestedCb), nestedCb : EMFTVM!CodeBlock to cb : EMFTVM!CodeBlock } abstract rule EmptyCodeBlock { from r : EMFTVM!Rule (applier =~ cb), cb : EMFTVM!CodeBlock not cb : EMFTVM!CodeBlock (code =~ instr), instr : EMFTVM!Instruction to r : EMFTVM!Rule (applier =~ cb), cb : EMFTVM!CodeBlock } rule EmptyCodeBlockWithLocals extends EmptyCodeBlock { from cb : EMFTVM!CodeBlock (localVariables =~ lv), lv : EMFTVM!LocalVariable to cb : EMFTVM!CodeBlock } rule EmptyCodeBlockWithLineNumbers extends EmptyCodeBlock { from cb : EMFTVM!CodeBlock (lineNumbers =~ ln), ln : EMFTVM!LineNumber to cb : EMFTVM!CodeBlock } rule EmptyCodeBlockWithoutAnything extends EmptyCodeBlock { from cb : EMFTVM!CodeBlock }