From: <th...@us...> - 2008-03-18 21:53:48
|
Revision: 4219 http://jython.svn.sourceforge.net/jython/?rev=4219&view=rev Author: thobes Date: 2008-03-18 14:53:46 -0700 (Tue, 18 Mar 2008) Log Message: ----------- First outline of the AST -> PBC bridge of the new compiler. It still needs some fixing, mainly in the org.python.newcompiler.ast package. The translations to PBC are not perfect yet. In particular generator comprehension comes to mind. Also the JBC generating layer has not been adapted to the updated interfaces yet. Although this is a rather simple task, since the interfaces are both based on PBC. Next steps: * Update the PBC->JBC back end. Block-handling needs a complete refactoring. * Implement a PBC interpreter. These tasks are quite possible to get done during the rest of the sprint. Modified Paths: -------------- trunk/sandbox/pyasm/build.xml trunk/sandbox/pyasm/marshal.py trunk/sandbox/pyasm/pyasm.py Added Paths: ----------- trunk/sandbox/pyasm/agent/ trunk/sandbox/pyasm/agent/org/ trunk/sandbox/pyasm/agent/org/python/ trunk/sandbox/pyasm/agent/org/python/javaagent/ trunk/sandbox/pyasm/agent/org/python/javaagent/DeferringAgent.java trunk/sandbox/pyasm/astimport.py trunk/sandbox/pyasm/compiler/ trunk/sandbox/pyasm/compiler/org/ trunk/sandbox/pyasm/compiler/org/python/ trunk/sandbox/pyasm/compiler/org/python/bytecode/ trunk/sandbox/pyasm/compiler/org/python/bytecode/BinaryOperator.java trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInfo.java trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInstruction.java trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeVersion.java trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeVisitor.java trunk/sandbox/pyasm/compiler/org/python/bytecode/CharReader.java trunk/sandbox/pyasm/compiler/org/python/bytecode/ComparisonOperator.java trunk/sandbox/pyasm/compiler/org/python/bytecode/ConstantStore.java trunk/sandbox/pyasm/compiler/org/python/bytecode/Instruction.java trunk/sandbox/pyasm/compiler/org/python/bytecode/Label.java trunk/sandbox/pyasm/compiler/org/python/bytecode/LineNumberBuilder.java trunk/sandbox/pyasm/compiler/org/python/bytecode/LineNumberTable.java trunk/sandbox/pyasm/compiler/org/python/bytecode/RawBytecodeVisitor.java trunk/sandbox/pyasm/compiler/org/python/bytecode/RawInstruction.java trunk/sandbox/pyasm/compiler/org/python/bytecode/ReferenceResolver.java trunk/sandbox/pyasm/compiler/org/python/bytecode/SliceMode.java trunk/sandbox/pyasm/compiler/org/python/bytecode/UnaryOperator.java trunk/sandbox/pyasm/compiler/org/python/bytecode/VariableContext.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/ trunk/sandbox/pyasm/compiler/org/python/newcompiler/AbstractEnvironment.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/BytecodeBundle.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/BytecodeLoader.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/ClassEnvironment.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/CodeInfo.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/CompilerFlag.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/CompilerVariable.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/Environment.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/EnvironmentError.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/EnvironmentHolder.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/EnvironmentInfo.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/FunctionEnvironment.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/Future.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/GlobalEnvironment.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/YieldPoint.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/ast/ trunk/sandbox/pyasm/compiler/org/python/newcompiler/ast/AstToBytecode.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/ast/ContextBuilder.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/bytecode/ trunk/sandbox/pyasm/compiler/org/python/newcompiler/bytecode/BytecodeCompiler.java trunk/sandbox/pyasm/compiler/org/python/newcompiler/bytecode/PythonBytecodeCompilingBundle.java trunk/sandbox/pyasm/newcompiler.py Added: trunk/sandbox/pyasm/agent/org/python/javaagent/DeferringAgent.java =================================================================== --- trunk/sandbox/pyasm/agent/org/python/javaagent/DeferringAgent.java (rev 0) +++ trunk/sandbox/pyasm/agent/org/python/javaagent/DeferringAgent.java 2008-03-18 21:53:46 UTC (rev 4219) @@ -0,0 +1,65 @@ +package org.python.javaagent; + +import java.lang.instrument.Instrumentation; + +/** + * A foreign agent that provides access to the Bytecode instrumentation library. + * + * @author Tobias Ivarsson + */ +public class DeferringAgent { + + private final Instrumentation instrumentation; + + private static DeferringAgent agent = null; + + private DeferringAgent(Instrumentation inst) { + this.instrumentation = inst; + } + + /** + * Get the instrumentation this agent received upon attachment, or try to attach the agent by + * invoking the provided attacher. + * + * @param attacher + * A task that gets executed to attach the agent if it has not already been attached. + * @return The instrumentation associated with this agent. + */ + public static Instrumentation getInstrumentation(Runnable attacher) { + if (agent == null) { + attacher.run(); + if (agent == null) { + synchronized (DeferringAgent.class) { + if (agent == null) { + agent = new DeferringAgent(null); + } + } + } + } + return agent.instrumentation; + } + + /** + * Attach the agent upon start of the JVM. + * + * @param agentArgs + * Arguments are ignored. + * @param inst + * The instrumentation that will be associated with this agent. + */ + public static void premain(String agentArgs, Instrumentation inst) { + agentmain(agentArgs, inst); + } + + /** + * Attach the agent upon remote arrival to the JVM. + * + * @param agentArgs + * Arguments are ignored. + * @param inst + * The instrumentation that will be associated with this agent. + */ + public static void agentmain(String agentArgs, Instrumentation inst) { + agent = new DeferringAgent(inst); + } +} Added: trunk/sandbox/pyasm/astimport.py =================================================================== --- trunk/sandbox/pyasm/astimport.py (rev 0) +++ trunk/sandbox/pyasm/astimport.py 2008-03-18 21:53:46 UTC (rev 4219) @@ -0,0 +1,66 @@ +import sys +import os + +__debugging__ = False + +import org.python.antlr.Main as Parser +from org.python.newcompiler.ast import AstToBytecode +from newcompiler import Bundle +def _makeModule(name, code, path): + module = _imp.addModule(name) + builtins = _Py.getSystemState().builtins + frame = _Frame(code, module.__dict__, module.__dict__, builtins) + module.__file__ = path + code.call(frame) # execute module code + return module +def _parse(*files): + return Parser().parse(files) +def _pbc(ast, bundle, name): + return ast.accept(AstToBytecode(bundle, name)) +def _compile(filepath, name, *args,**kwargs): + return _pbc(_parse(filepath), Bundle(*args,**kwargs), name) + +class _Importer(object): + def __init__(self, path): + if __debugging__: print "Importer invoked" + self.__path = path + def find_module(self, fullname, path=None): + if __debugging__: + print "Importer.find_module(fullname=%s, path=%s)" % ( + repr(fullname), repr(path)) + path = fullname.split('.') + filename = path[-1] + path = path[:-1] + pyfile = os.path.join(self.__path, *(path + [filename + '.py'])) + if os.path.exists(pyfile): + return self + else: + return None + def load_module(self, fullname): + path = fullname.split('.') + path[-1] += '.py' + filename = os.path.join(self.__path, *path) + code = _compile(filename, fullname) + return __makeModule(fullname, code, filename) + +class _MetaImporter(object): + def __init__(self): + self.__importers = {} + def find_module(self, fullname, path): + if __debugging__: print "MetaImporter.find_module(%s, %s)" % ( + repr(fullname), repr(path)) + for _path in sys.path: + if _path not in self.__importers: + try: + self.__importers[_path] = _Importer(_path) + except: + self.__importers[_path] = None + importer = self.__importers[_path] + if importer is not None: + loader = importer.find_module(fullname, path) + if loader is not None: + return loader + else: + return None + +sys.meta_path.insert(0, _MetaImporter()) Modified: trunk/sandbox/pyasm/build.xml =================================================================== --- trunk/sandbox/pyasm/build.xml 2008-03-18 16:42:02 UTC (rev 4218) +++ trunk/sandbox/pyasm/build.xml 2008-03-18 21:53:46 UTC (rev 4219) @@ -3,7 +3,15 @@ <property file="${basedir}/build.properties"/> <property name="dist.dir" value="${jython.dir}/dist"/> <property name="script.file" value="${jython.dir}/jython"/> - + <property name="agent.dir" value="${basedir}/agent"/> + <property name="compiler.dir" value="${basedir}/compiler"/> + <property name="build.dir" value="${basedir}/build"/> + <property name="jdk.target.version" value="1.5"/> + <property name="jdk.source.version" value="1.5"/> + <property name="agent.class" value="org.python.javaagent.DeferringAgent"/> + + <target name="all" depends="pyasm-copy,agent,script"/> + <target name="jython"> <ant dir="${jython.dir}" target="developer-build" inheritAll="false"/> </target> @@ -19,6 +27,39 @@ </copy> </target> + <target name="compile"> + <mkdir dir="${build.dir}"/> + <javac destdir="${build.dir}" + source="${jdk.source.version}" target="${jdk.target.version}"> + <src path="${agent.dir}"/> + <src path="${compiler.dir}"/> + </javac> + </target> + + <target name="agent" depends="compile"> + <jar destfile="${dist.dir}/agent.jar" update="true"> + <fileset dir="${build.dir}"> + <include name="org/python/javaagent/**" /> + </fileset> + <manifest> + <!-- Instrumentation agent, for a more dynamic newcompiler --> + <attribute name="Premain-Class" value="${agent.class}" /> + <attribute name="Can-Redefine-Classes" value="true" /> + <!-- Java 6 stuff, more powerful agents --> + <attribute name="Agent-Class" value="${agent.class}" /> + <attribute name="Can-Retransform-Classes" value="true" /> + </manifest> + </jar> + </target> + + <target name="compiler" depends="compile"> + <jar destfile="${dist.dir}/compiler.jar" update="true"> + <fileset dir="${build.dir}"> + <exclude name="org/python/javaagent/**" /> + </fileset> + </jar> + </target> + <target name="script"> <echo file="${script.file}">#!/bin/sh EXE=$0 @@ -26,15 +67,20 @@ EXE=`readlink $EXE` done BASE=`dirname $EXE` +AGENT=$BASE/dist/agent.jar JVMFLAGS="-server -Dpython.home=$BASE/dist/ -Dpython.executable=$0 $JVMFLAGS" +if [ -e $AGENT ]; then + JVMFLAGS="$JVMFLAGS -javaagent:$AGENT" +fi ###JVMFLAGS="$JVMFLAGS -Djava.security.policy=${BASE}security.policy" #JVMFLAGS="$JVMFLAGS -Dcom.sun.management.jmxremote" REQ=$BASE/extlibs/asm-3.1.jar +REQ=$REQ:$BASE/build/jarjar.jar REQ=$REQ:$BASE/extlibs/asm-commons-3.1.jar REQ=$REQ:$BASE/extlibs/asm-util-3.1.jar REQ=$REQ:$BASE/extlibs/junit-3.8.2.jar -REQ=$REQ:$BASE/build/exposed/ -REQ=$REQ:$BASE/build/classes/ +REQ=$REQ:$BASE/extlibs/jython-engine.jar +REQ=$REQ:$BASE/dist/jython.jar if [ "$CLASSPATH" = "" ]; then CLASSPATH=. fi Added: trunk/sandbox/pyasm/compiler/org/python/bytecode/BinaryOperator.java =================================================================== --- trunk/sandbox/pyasm/compiler/org/python/bytecode/BinaryOperator.java (rev 0) +++ trunk/sandbox/pyasm/compiler/org/python/bytecode/BinaryOperator.java 2008-03-18 21:53:46 UTC (rev 4219) @@ -0,0 +1,6 @@ +package org.python.bytecode; + + +public enum BinaryOperator { + POWER, MULTIPLY, DIVIDE, MODULO, ADD, SUBTRACT, FLOOR_DIVIDE, TRUE_DIVIDE, SHIFT_LEFT, SHIFT_RIGHT, AND, XOR, OR +} Added: trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInfo.java =================================================================== --- trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInfo.java (rev 0) +++ trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInfo.java 2008-03-18 21:53:46 UTC (rev 4219) @@ -0,0 +1,64 @@ +package org.python.bytecode; + +import java.util.Set; + +import org.python.newcompiler.CodeInfo; +import org.python.newcompiler.CompilerFlag; + +public class BytecodeInfo implements CodeInfo { + + private final String name; + + private final String filename; + + private final int argcount; + + private final int nlocals; + + private final int stacksize; + + private final Set<CompilerFlag> flags; + + public BytecodeInfo(String name, + String filename, + int argcount, + int nlocals, + int stacksize, + int flags) { + this.name = name; + this.filename = filename; + this.argcount = argcount; + this.nlocals = nlocals; + this.stacksize = stacksize; + this.flags = CompilerFlag.parseFlags(flags); + } + + @Override + public int getArgumentCount() { + return argcount; + } + + @Override + public String getFilename() { + return filename; + } + + @Override + public int getLocalsCount() { + return nlocals; + } + + @Override + public int getMaxStackSize() { + return stacksize; + } + + @Override + public String getName() { + return name; + } + + public Set<CompilerFlag> getCompilerFlags() { + return flags; + } +} Added: trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInstruction.java =================================================================== --- trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInstruction.java (rev 0) +++ trunk/sandbox/pyasm/compiler/org/python/bytecode/BytecodeInstruction.java 2008-03-18 21:53:46 UTC (rev 4219) @@ -0,0 +1,1717 @@ +package org.python.bytecode; + +public enum BytecodeInstruction implements Instruction, RawInstruction { + /** Marks the end of the byte code segment. */ + STOP_CODE(0, false, null, null) { + + @Override + public void acceptRaw(RawBytecodeVisitor visitor) { + visitor.visitStop(this); + } + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStop(); + } + }, + /** + * Remove the top stack element. + * + * Stack: element -> - + */ + POP_TOP(1, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPop(); + } + }, + /** + * Swap the top two stack elements. + * + * Stack: element1, element2 -> element2, element1 + */ + ROT_TWO(2, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitRot(2); + } + }, + /** + * Rotate down the top stack element to position three. + * + * Stack: element1, element2, element3 -> element2, element3, element1 + */ + ROT_THREE(3, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitRot(3); + } + }, + /** + * Duplicate the top stack element. + * + * Stack: element -> element, element + */ + DUP_TOP(4, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDup(1); + } + }, + /** + * Rotate down the top stack element to position four. + * + * Stack: element1, element2, element3, element4 -> element2, element3, element4, element1 + */ + ROT_FOUR(5, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitRot(4); + } + }, + /** Do-nothing instruction. */ + NOP(9, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitNop(); + } + }, + /** + * Apply the positive operator to the top stack element. + * + * Stack: element -> +element + */ + UNARY_POSITIVE(10, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.POSITIVE); + } + }, + /** + * Apply the negative operator to the top stack element. + * + * Stack: element -> -element + */ + UNARY_NEGATIVE(11, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.NEGATIVE); + } + }, + /** + * Apply the not operator to the top stack element. + * + * Stack: element -> not element + */ + UNARY_NOT(12, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.NOT); + } + }, + /** + * Apply the conversion operator to the top stack element. + * + * Stack: element -> repr(element) + */ + UNARY_CONVERT(13, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.CONVERT); + } + }, + /** + * Apply the inversion operator to the top stack element. + * + * Stack: element -> ~element + */ + UNARY_INVERT(15, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.INVERT); + } + }, + /** + * TODO: document this + */ + SET_ADD(17, false, BytecodeVersion.Python_3000__build_set, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitSetAdd(); + } + }, + /** + * Append the top stack element to the list in the second stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: list.append(element2, element1) + */ + LIST_APPEND(18, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitListAppend(); + } + }, + /** + * Raise the second stack element to the power of the top stack element. + * + * Stack: element1, element2 -> element2 ** element1 + */ + BINARY_POWER(19, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.POWER); + } + }, + /** + * Multiply the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 * element1 + */ + BINARY_MULTIPLY(20, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.MULTIPLY); + } + }, + /** + * Divide the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 / element1 + */ + BINARY_DIVIDE(21, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.DIVIDE); + } + }, + /** + * Compute the top stack element modulo of the second stack element. + * + * Stack: element1, element2 -> element2 % element1 + */ + BINARY_MODULO(22, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.MODULO); + } + }, + /** + * Add the top stack element to the second stack element. + * + * Stack: element1, element2 -> element2 + element1 + */ + BINARY_ADD(23, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.ADD); + } + }, + /** + * Remove the top stack element from the second stack element. + * + * Stack: element1, element2 -> element2 - element1 + */ + BINARY_SUBTRACT(24, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.SUBTRACT); + } + }, + /** + * Load the top stack element subscript of the second stack element. + * + * Stack: element1, element2 -> element2[element1] + */ + BINARY_SUBSCR(25, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadSubscript(); + } + }, + /** + * Floor divide the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 // element1 + */ + BINARY_FLOOR_DIVIDE(26, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.FLOOR_DIVIDE); + } + }, + /** + * True divide the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 / element1 + */ + BINARY_TRUE_DIVIDE(27, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.TRUE_DIVIDE); + } + }, + /** + * Floor divide the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 // element1 + */ + INPLACE_FLOOR_DIVIDE(28, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.FLOOR_DIVIDE); + } + }, + /** + * True divide the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 / element1 + */ + INPLACE_TRUE_DIVIDE(29, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.TRUE_DIVIDE); + } + }, + /** + * Load the entire sequence slice of the top stack element. + * + * Stack: element -> element[:] + */ + SLICE__0(30, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadSlice(SliceMode.PLUS_0); + } + }, + /** + * Load the slice from the top stack element of the second stack element. + * + * Stack: element1, element2 -> element2[element1:] + */ + SLICE__1(31, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadSlice(SliceMode.PLUS_1); + } + }, + /** + * Load the slice to the top stack element of the second stack element. + * + * Stack: element1, element2 -> element2[:element1] + */ + SLICE__2(32, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadSlice(SliceMode.PLUS_2); + } + }, + /** + * Load the slice from the second stack element to the top stack element of the third stack + * element. + * + * Stack: element1, element2, element3 -> element3[element2:element1] + */ + SLICE__3(33, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadSlice(SliceMode.PLUS_3); + } + }, + /** + * Store the second stack element in the entire sequence slice of the top stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: element1[:] = element2 + */ + STORE_SLICE__0(40, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStoreSlice(SliceMode.PLUS_0); + } + }, + /** + * Store the third stack element in the slice from the first stack element of the second stack + * element. + * + * Stack: element1, element2, element3 -> - + * + * Side effect: element2[element1:] = element3 + */ + STORE_SLICE__1(41, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStoreSlice(SliceMode.PLUS_1); + } + }, + /** + * Store the third stack element in the slice to the first stack element of the second stack + * element. + * + * Stack: element1, element2, element3 -> - + * + * Side effect: element2[:element1] = element3 + */ + STORE_SLICE__2(42, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStoreSlice(SliceMode.PLUS_2); + } + }, + /** + * Store the fourth stack element in the slice from the second stack element to the first stack + * element of the third stack element. + * + * Stack: element1, element2, element3, element4 -> - + * + * Side effect: element3[element2:element1] = element4 + */ + STORE_SLICE__3(43, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStoreSlice(SliceMode.PLUS_3); + } + }, + /** + * Delete the entire sequence slice of the top stack element. + * + * Stack: element1 -> - + * + * Side effect: del element3[:] + */ + DELETE_SLICE__0(50, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDeleteSlice(SliceMode.PLUS_0); + } + }, + /** + * Delete the slice from the top stack element of the second stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: element2[element1:] + */ + DELETE_SLICE__1(51, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDeleteSlice(SliceMode.PLUS_1); + } + }, + /** + * Delete the slice to the top stack element of the second stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: element2[:element1] + */ + DELETE_SLICE__2(52, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDeleteSlice(SliceMode.PLUS_2); + } + }, + /** + * Delete the slice from the second stack element to the top stack element of the third stack + * element. + * + * Stack: element1, element2, element3 -> - + * + * Side effect: element3[element2:element1] + */ + DELETE_SLICE__3(53, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDeleteSlice(SliceMode.PLUS_3); + } + }, + /** + * Add the top stack element to the second stack element in-place. + * + * Stack: element1, element2 -> element2 + element1 + */ + INPLACE_ADD(55, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.ADD); + } + }, + /** + * Subtract the top stack element from the second stack element in-place. + * + * Stack: element1, element2 -> element2 + element1 + */ + INPLACE_SUBTRACT(56, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.SUBTRACT); + } + }, + /** + * Multiply the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 * element1 + */ + INPLACE_MULTIPLY(57, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.MULTIPLY); + } + }, + /** + * Divide the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 / element1 + */ + INPLACE_DIVIDE(58, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.DIVIDE); + } + }, + /** + * Compute the top stack element modulo of the second stack element in-place. + * + * Stack: element1, element2 -> element2 % element1 + */ + INPLACE_MODULO(59, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.MODULO); + } + }, + /** + * Store the third stack element in the top stack element subscript of the second stack element. + * + * Stack: element1, element2, element3 -> - + * + * Side effect: element2[element1] = element3 + */ + STORE_SUBSCR(60, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitStoreSubscript(); + } + }, + /** + * Delete the item at the top stack position in the second stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: del element2[element1] + */ + DELETE_SUBSCR(61, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDeleteSubscript(); + } + }, + /** + * Left shift the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 << element1 + */ + BINARY_LSHIFT(62, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.SHIFT_LEFT); + } + }, + /** + * Right shift the second stack element by the top stack element. + * + * Stack: element1, element2 -> element2 >> element1 + */ + BINARY_RSHIFT(63, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.SHIFT_RIGHT); + } + }, + /** + * Compute the logic and between the second stack element and the top stack element. + * + * Stack: element1, element2 -> element2 & element1 + */ + BINARY_AND(64, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.AND); + } + }, + /** + * Compute the exclusive logic or between the second stack element and the top stack element. + * + * Stack: element1, element2 -> element2 ^ element1 + */ + BINARY_XOR(65, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.XOR); + } + }, + /** + * Compute the inclusive logic or between the second stack element and the top stack element. + * + * Stack: element1, element2 -> element2 | element1 + */ + BINARY_OR(66, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBinaryOperator(BinaryOperator.OR); + } + }, + /** + * Raise the second stack element to the power of the top stack element in-place. + * + * Stack: element1, element2 -> element2 ** element1 + */ + INPLACE_POWER(67, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.POWER); + } + }, + /** + * Get the iterator from the top stack element. + * + * Stack: element -> iter(element) + */ + GET_ITER(68, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnaryOperator(UnaryOperator.ITERATOR); + } + }, + /** + * TODO: document this + */ + STORE_LOCALS(69, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + // TODO implement this + super.accept(visitor); + } + }, + /** + * Print the top stack element in interactive mode. + * + * Stack: element -> - + * + * Side effect: print element + */ + PRINT_EXPR(70, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPrintExpression(); + } + }, + /** + * Print the top stack element. + * + * Stack: element -> - + * + * Side effect: print element, + */ + PRINT_ITEM(71, false, null, BytecodeVersion.Python_3000) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPrintItem(); + } + }, + /** + * TODO: document this + */ + LOAD_BUILD_CLASS(71, false, BytecodeVersion.Python_3000, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + // TODO: implement this + super.accept(visitor); + } + }, + /** + * Print a newline. + * + * Stack: - -> - + * + * Side effect: print + */ + PRINT_NEWLINE(72, false, null, BytecodeVersion.Python_3000) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPrintNewline(); + } + }, + /** + * Print the second stack element to the file object at the top stack element. + * + * Stack: element1, element2 -> - + * + * Side effect: print >>element1, element2 + */ + PRINT_ITEM_TO(73, false, null, BytecodeVersion.Python_3000) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPrintItemTo(); + } + }, + /** + * Print a newline to the file object at the top stack element. + * + * Stack: element -> - + * + * Side effect: print >>element + */ + PRINT_NEWLINE_TO(74, false, null, BytecodeVersion.Python_3000) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPrintNewlineTo(); + } + }, + /** + * Left shift the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 << element1 + */ + INPLACE_LSHIFT(75, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.SHIFT_LEFT); + } + }, + /** + * Right shift the second stack element by the top stack element in-place. + * + * Stack: element1, element2 -> element2 << element1 + */ + INPLACE_RSHIFT(76, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.SHIFT_RIGHT); + } + }, + /** + * Compute the logic and between the second stack element and the top stack element in-place. + * + * Stack: element1, element2 -> element2 & element1 + */ + INPLACE_AND(77, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.AND); + } + }, + /** + * Compute the exclusive logic or between the second stack element and the top stack element + * in-place. + * + * Stack: element1, element2 -> element2 ^ element1 + */ + INPLACE_XOR(78, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.XOR); + } + }, + /** + * Compute the inclusive logic or between the second stack element and the top stack element + * in-place. + * + * Stack: element1, element2 -> element2 | element1 + */ + INPLACE_OR(79, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitInplaceOperator(BinaryOperator.OR); + } + }, + /** Break out of the nearest loop. */ + BREAK_LOOP(80, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBreak(); + } + }, + /** + * Invoke the context manager exit function from the top of the stack with the current exception + * status. + * + * Stack: element -> - + * + * Side effect: element(*sys.exc_info()) + */ + WITH_CLEANUP(81, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitWithCleanup(); + } + }, + /** + * Load the local variables to the top of the stack. + * + * Stack: - -> locals() + */ + LOAD_LOCALS(82, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitLoadLocals(); + } + }, + /** + * Return the top stack value. + */ + RETURN_VALUE(83, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitReturn(); + } + }, + /** + * Import all the names from module on the top of the stack. + * + * Stack: module -> - + * + * Side effects: stores a lot of names... + */ + IMPORT_STAR(84, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitImportAll(); + } + }, + /** + * Execute the code element in the third stack element in the global context of the second stack + * element and the local context of the top stack element. + * + * Stack: element1, element2, element3 -> - + * + * Side effect: exec element3, element2, element1 + */ + EXEC_STMT(85, false, null, BytecodeVersion.Python_3000) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitExec(); + } + }, + /** + * TODO: document this + */ + MAKE_BYTES(85, false, BytecodeVersion.Python_3000, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + // TODO: implement this + super.accept(visitor); + } + }, + /** + * Yield the top stack value. + * + * Stack: element -> sent-value + */ + YIELD_VALUE(86, false, null, null) { + + @Override + public void acceptRaw(RawBytecodeVisitor visitor) { + visitor.visitYield(); + } + }, + /** Pop the closest block on the block stack. */ + POP_BLOCK(87, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitPopBlock(); + } + }, + /** Terminate a finally clause. */ + END_FINALLY(88, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitEndFinally(); + } + }, + /** + * Build a class. + * + * Stack: element1(dict), element2(bases), element3(name) -> class + */ + BUILD_CLASS(89, false, null, null) { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildClass(); + } + }, + /** + * Store the top stack value in the variable named co_names[index], where index is the opcode + * argument. + * + * Stack: element -> - + * + * Side effect: local[co_names[index]] = element + */ + STORE_NAME(90, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitStore(VariableContext.UNQUALIFIED, argument); + } + }, + /** + * Delete variable named co_names[index], where index is the opcode argument. + * + * Stack: - -> - + * + * Side effect: del local[co_names[index]] + */ + DELETE_NAME(91, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitDelete(VariableContext.UNQUALIFIED, argument); + } + }, + /** + * Unpack count arguments from the iterable in the top stack element, where count is the opcode + * argument. + * + * Stack: element -> [elements]*count + */ + UNPACK_SEQUENCE(92, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnpackSequence(argument, false, 0); + } + }); + } + }, + /** + * Get the next element from the iterator at the top of the stack, or jump to the relative + * address given by the opcode argument. + * + * Stack: element1(iterator) -> element1, element2(iterator.next()) + */ + FOR_ITER(93, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitForIteration(argument); + } + }, + /** + * TODO: document this + */ + UNPACK_EX(94, false, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + final int after = argument >> 8; + final int before = argument % (1 << 8); + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitUnpackSequence(before, true, after); + } + }); + } + }, + /** + * Store the second stack element at the attribute with the name at co_names[index] of the top + * stack element, where index is the opcode argument. + * + * Stack: element1, element2 -> - + * + * Side effect: setattr(element1, co_names[index], element2) + */ + STORE_ATTR(95, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitStoreAttribute(argument); + } + }, + /** + * Delete the attribute with the name at co_names[index] of the top stack element, where index + * is the opcode argument. + * + * Stack: element1 -> - + * + * Side effect: delattr(element1, co_names[index]) + */ + DELETE_ATTR(96, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitDeleteAttribute(argument); + } + }, + /** + * Store the top stack element in the global variable with the name from co_names[index], where + * index is the opcode argument. + * + * Stack: element -> - + * + * Side effect: globals()[co_names[index]] = element + */ + STORE_GLOBAL(97, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitStore(VariableContext.GLOBAL, argument); + } + }, + /** + * Deletes the global variable with the name from co_names[index], where index is the opcode + * argument. + * + * Stack: - -> - + * + * Side effect: del globals()[co_names[index]] + */ + DELETE_GLOBAL(98, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitDelete(VariableContext.GLOBAL, argument); + } + }, + /** + * Duplicate the top X stack elements. + * + * Stack: element1, element2, ... -> element1, element2, ..., element1, element2, ... + */ + DUP_TOPX(99, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitDup(argument); + } + }); + } + }, + /** + * Loads the constant in co_consts[index] to the stack, where index is the opcode argument. + * + * Stack: - -> co_consts[index] + */ + LOAD_CONST(100, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitLoadConstant(argument); + } + }, + /** + * Load the value from the variable named co_names[index] to the stack, where index is the + * opcode argument. + * + * Stack: - -> local[co_names[index]] + */ + LOAD_NAME(101, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitLoad(VariableContext.UNQUALIFIED, argument); + } + }, + /** + * Builds a tuple of the size specified in the opcode argument from that many elements from the + * stack. + * + * Stack: element1, ... -> tuple(elemen1, ...) + */ + BUILD_TUPLE(102, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildTuple(argument); + } + }); + } + }, + /** + * Builds a list of the size specified in the opcode argument from that many elements from the + * stack. + * + * Stack: element1, ... -> list(elemen1, ...) + */ + BUILD_LIST(103, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildList(argument); + } + }); + } + }, + /** + * Build a map. The argument is expected to be zero. + * + * Stack: - -> {} + */ + BUILD_MAP(104, true, null, BytecodeVersion.Python_3000) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildMap(argument); + } + }); + } + }, + /** + * TODO: document this + */ + BUILD_SET(104, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildSet(argument); + } + }); + } + }, + /** + * Load the attribute named co_names[index] from the top stack element to the stack. + * + * Stack: element -> getattr(element, co_names[index]) + */ + LOAD_ATTR(105, true, null, BytecodeVersion.Python_3000) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitLoadAttribute(argument); + } + }, + /** + * @see #BUILD_MAP + */ + py3k_BUILD_MAP(105, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + BUILD_MAP.acceptRaw(visitor, argument); + } + }, + /** + * Compare the second stack element to the first stack element using the comparison operator + * identified by the opcode argument. + * + * Stack: element1, element2 -> element2 OP element1 + */ + COMPARE_OP(106, true, null, BytecodeVersion.Python_3000) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + final ComparisonOperator operator = ComparisonOperator.values()[argument]; + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitCompareOperator(operator); + } + }); + } + }, + /** + * @see #LOAD_ATTR + */ + py3k_LOAD_ATTR(106, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + LOAD_ATTR.acceptRaw(visitor, argument); + } + }, + /** + * Imports the module named co_names[index] to the stack, where index is the opcode argument. + * + * Stack: - -> module + */ + IMPORT_NAME(107, true, null, BytecodeVersion.Python_3000) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitImportName(argument); + } + }, + /** + * @see #COMPARE_OP + */ + py3k_COMPARE_OP(107, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + COMPARE_OP.acceptRaw(visitor, argument); + } + }, + /** + * Import the name co_names[index] from the module at the top of the stack, where index is the + * opcode argument. + * + * Stack: module -> getattr(module, co_names[index]) + */ + IMPORT_FROM(108, true, null, BytecodeVersion.Python_3000) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitImportFrom(argument); + } + }, + /** + * @see #IMPORT_NAME + */ + py3k_IMPORT_NAME(108, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + IMPORT_NAME.acceptRaw(visitor, argument); + } + }, + /** + * @see #IMPORT_FROM + */ + py3k_IMPORT_FROM(109, false, BytecodeVersion.Python_3000, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + IMPORT_FROM.acceptRaw(visitor, argument); + } + }, + /** + * Increase the program counter by the argument of the opcode. + * + * Stack: - -> - + */ + JUMP_FORWARD(110, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitRelativeJump(argument); + } + }, + /** + * Increase the program counter by the argument of the opcode if the element on the top of the + * stack is false. + * + * Stack: element -> element + */ + JUMP_IF_FALSE(111, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitJumpIfFalse(argument); + } + }, + /** + * Increase the program counter by the argument of the opcode if the element on the top of the + * stack is true. + * + * Stack: element -> element + */ + JUMP_IF_TRUE(112, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitJumpIfTrue(argument); + } + }, + /** + * Set the program counter to the value of the argument of the opcode. + * + * Stack: - -> - + */ + JUMP_ABSOLUTE(113, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitAbsouteJump(argument); + } + }, + /** + * Loads the global name co_names[index] to the stack, where index is the argument of the + * opcode. + * + * Stack: - -> globals()[co_names[index]] + */ + LOAD_GLOBAL(116, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitLoad(VariableContext.GLOBAL, argument); + } + }, + /** + * Jumps to the next iteration of the current loop. + * + * Stack: - -> - + */ + CONTINUE_LOOP(119, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitContinue(argument); + } + }, + /** + * Setup a new loop block on the block stack. + * + * Stack: - -> - + */ + SETUP_LOOP(120, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitSetupLoop(argument); + } + }, + /** + * Setup a new exception handling block on the block stack. + * + * Stack: - -> - + */ + SETUP_EXCEPT(121, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitSetupExcept(argument); + } + }, + /** + * Setup a new finally block on the block stack. + * + * Stack: - -> - + */ + SETUP_FINALLY(122, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitSetupFinally(argument); + } + }, + /** + * Load the local variable at the index given by the opcode argument to the stack. + * + * Stack: - -> element + */ + LOAD_FAST(124, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitLoad(VariableContext.LOCAL, argument); + } + }, + /** + * Store the element on the top of the stack to the local variable at the index given by the + * opcode argument. + * + * Stack: element -> - + * + * Side effect: Store local variable + */ + STORE_FAST(125, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitStore(VariableContext.LOCAL, argument); + } + }, + /** + * Delete the local variable at the index given by the opcode argument. + * + * Stack: - -> - + * + * Side effect: Delete local variable + */ + DELETE_FAST(126, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + visitor.visitDelete(VariableContext.LOCAL, argument); + } + }, + /** + * Raise the X elements from the stack, where X is the opcode argument. + * + * Stack: [exception, [value, [trace]]] -> - + * + * Side effect: raise [exception, [value, [trace]]] + * + * If X is zero, the exception will be retrieved from sys.exc_info() + */ + RAISE_VARARGS(130, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitRaise(argument); + } + }); + } + }, + /** + * Calls the function on the stack with the arguments on the stack above the function. The + * function is called with numKeys keyword arguments, and numArgs positional arguments, where + * numKeys and numArgs are specified by the opcode arguments. + * + * Stack: [key,arg]*numKeys, [arg]*numArgs, function -> return-value + */ + CALL_FUNCTION(131, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, int argument) { + final int numPos = argument >> 8; + final int numKey = argument % (1 << 8); + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitCall(false, false, numPos, numKey); + } + }); + } + }, + /** + * Makes a function from a code object found on the top of the stack and count default variables + * found on the stack below the code object, where count is the argument of the opcode. + * + * Stack: code, [default_arg]*count -> function + */ + MAKE_FUNCTION(132, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildFunction(false, argument); + } + }); + } + }, + /** + * Create a slice object from count items from the top of the stack. + * + * Stack: element1, element2[, element3] -> slice([element3,] element2, element1) + */ + BUILD_SLICE(133, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildSlice(argument); + } + }); + } + }, + /** + * Makes a function from a code object found on the top of the stack, free_count closure + * variables and count default variables found on the stack below the code object, where count + * is the argument of the opcode. free_count is the number of free variables specified by the + * code object. + * + * Stack: code, tuple([cell_vars]*free_count), [default_arg]*count -> function + */ + MAKE_CLOSURE(134, true, null, null) { + + @Override + protected void acceptRaw(RawBytecodeVisitor visitor, final int argument) { + visitor.visitInstruction(new Instruction() { + + @Override + public void accept(BytecodeVisitor visitor) { + visitor.visitBuildFunction(true, argument); + } + }); + } + }, + /** + * Load the closure variable from the current scope with the index specified by the opcode + * argument. + * + * Stack: - -> closure_variable[index] + */ + LOAD_CLOSURE(135, true, null, null) { + + ... [truncated message content] |