com.xruby.compiler.codegen.ClassGeneratorForRubyProgram.java Source code

Java tutorial

Introduction

Here is the source code for com.xruby.compiler.codegen.ClassGeneratorForRubyProgram.java

Source

/**
 * Copyright 2005-2007 Xue Yong Zhi
 * Distributed under the BSD License
 */

package com.xruby.compiler.codegen;

import org.objectweb.asm.*;
import org.objectweb.asm.commons.Method;
import com.xruby.runtime.lang.RubyBinding;

class ClassGeneratorForRubyProgram extends ClassGenerator {
    private final RubyBinding binding;
    private final String fileName;

    public ClassGeneratorForRubyProgram(String name, String fileName, RubyBinding binding, boolean create_main,
            boolean is_singleton) {
        super(name);
        this.fileName = fileName;
        this.binding = binding;
        mg_for_run_method_ = startRubyProgram(create_main, is_singleton);
    }

    public String getFileName() {
        return fileName;
    }

    private static final Method RUBY_PROGRAM_RUN = CgUtil.getMethod("run", Types.RUBY_VALUE_TYPE,
            Types.RUBY_VALUE_TYPE, Types.RUBY_ARRAY_TYPE, Types.RUBY_BLOCK_TYPE, Types.RUBY_MODULE_TYPE);

    private MethodGenerator startRubyProgram(boolean createMain, boolean is_singleton) {
        cv_.visit(CgConfig.TARGET_VERSION, Opcodes.ACC_PUBLIC, name_, null, // signature
                Types.RUBY_PROGRAM_TYPE.getInternalName(), // superName
                null // interface
        );

        // set source file's name, for debug
        if (this.fileName != null) {
            cv_.visitSource(this.fileName, null);
        }

        CgUtil.createImplicitConstructor(this.cv_, Types.RUBY_PROGRAM_TYPE);

        if (createMain) {
            createStaticVoidMain(cv_);
        }

        //Implement RubyProgram
        return new MethodGenerator(Opcodes.ACC_PROTECTED, RUBY_PROGRAM_RUN, cv_, this.binding, null, is_singleton);
    }

    private void createStaticVoidMain(ClassVisitor cv) {
        MethodGenerator mg = new MethodGenerator(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
                Method.getMethod("void main (String[])"), cv, null, null, false);

        mg.loadArg(0);
        mg.invokeStatic(Types.RUBY_RUNTIME_TYPE, Method.getMethod("void init(String[])"));

        Type program = Type.getType("L" + name_ + ";");
        mg.newInstance(program);
        mg.dup();
        mg.invokeConstructor(program, CgUtil.CONSTRUCTOR);
        mg.invokeVirtual(program, CgUtil.getMethod("invoke", Types.RUBY_VALUE_TYPE));
        mg.pop();

        mg.invokeStatic(Types.RUBY_RUNTIME_TYPE, CgUtil.getMethod("fini", Type.VOID_TYPE));

        mg.returnValue();
        mg.endMethod();
    }

    public void storeVariable(String name) {
        updateBinding(binding, name);

        super.storeVariable(name);
    }

    public void loadArgOfMethodForBlock() {
        MethodGenerator mg = getMethodGenerator();
        mg.pushNull();
        mg.loadArg(1);
    }
}