Mercurial > hg > graal-compiler
view graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/CoreLibrary.java @ 13514:0fbee3eb71f0
Ruby: import project.
author | Chris Seaton <chris.seaton@oracle.com> |
---|---|
date | Mon, 06 Jan 2014 17:12:09 +0000 |
parents | |
children | 497fada09efb |
line wrap: on
line source
/* * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This * code is released under a tri EPL/GPL/LGPL license. You can use it, * redistribute it and/or modify it under the terms of the: * * Eclipse Public License version 1.0 * GNU General Public License version 2 * GNU Lesser General Public License version 2.1 */ package com.oracle.truffle.ruby.runtime.core; import java.io.*; import java.math.*; import java.util.*; import com.oracle.truffle.api.*; import com.oracle.truffle.ruby.runtime.*; import com.oracle.truffle.ruby.runtime.core.array.*; import com.oracle.truffle.ruby.runtime.objects.*; public class CoreLibrary { private final RubyContext context; private RubyClass argumentErrorClass; private RubyClass arrayClass; private RubyClass basicObjectClass; private RubyClass bignumClass; private RubyClass bindingClass; private RubyClass classClass; private RubyClass continuationClass; private RubyClass dirClass; private RubyClass exceptionClass; private RubyClass falseClass; private RubyClass fiberClass; private RubyClass fileClass; private RubyClass fixnumClass; private RubyClass floatClass; private RubyClass hashClass; private RubyClass integerClass; private RubyClass ioClass; private RubyClass loadErrorClass; private RubyClass localJumpErrorClass; private RubyClass matchDataClass; private RubyClass moduleClass; private RubyClass nameErrorClass; private RubyClass nilClass; private RubyClass noMethodErrorClass; private RubyClass numericClass; private RubyClass objectClass; private RubyClass procClass; private RubyClass processClass; private RubyClass rangeClass; private RubyClass rangeErrorClass; private RubyClass regexpClass; private RubyClass rubyTruffleErrorClass; private RubyClass runtimeErrorClass; private RubyClass standardErrorClass; private RubyClass stringClass; private RubyClass structClass; private RubyClass symbolClass; private RubyClass syntaxErrorClass; private RubyClass systemCallErrorClass; private RubyClass systemExitClass; private RubyClass threadClass; private RubyClass timeClass; private RubyClass trueClass; private RubyClass typeErrorClass; private RubyClass zeroDivisionErrorClass; private RubyModule comparableModule; private RubyModule configModule; private RubyModule errnoModule; private RubyModule kernelModule; private RubyModule mathModule; private RubyModule objectSpaceModule; private RubyModule signalModule; private RubyModule debugModule; private RubyArray argv; private RubyBasicObject globalVariablesObject; private RubyBasicObject mainObject; private RubyFalseClass falseObject; private RubyNilClass nilObject; private RubyTrueClass trueObject; public CoreLibrary(RubyContext context) { this.context = context; } public void initialize() { // Create the cyclic classes and modules classClass = new RubyClass.RubyClassClass(context); basicObjectClass = new RubyClass(context, classClass, null, null, "BasicObject"); objectClass = new RubyClass(null, basicObjectClass, "Object"); moduleClass = new RubyModule.RubyModuleClass(context); // Close the cycles moduleClass.unsafeSetRubyClass(classClass); classClass.unsafeSetSuperclass(moduleClass); moduleClass.unsafeSetSuperclass(objectClass); classClass.unsafeSetRubyClass(classClass); // Create all other classes and modules numericClass = new RubyClass(null, objectClass, "Numeric"); integerClass = new RubyClass(null, numericClass, "Integer"); exceptionClass = new RubyException.RubyExceptionClass(objectClass, "Exception"); standardErrorClass = new RubyException.RubyExceptionClass(exceptionClass, "StandardError"); ioClass = new RubyClass(null, objectClass, "IO"); argumentErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ArgumentError"); arrayClass = new RubyArray.RubyArrayClass(objectClass); bignumClass = new RubyClass(null, integerClass, "Bignum"); bindingClass = new RubyClass(null, objectClass, "Binding"); continuationClass = new RubyClass(null, objectClass, "Continuation"); comparableModule = new RubyModule(moduleClass, null, "Comparable"); configModule = new RubyModule(moduleClass, null, "Config"); debugModule = new RubyModule(moduleClass, null, "Debug"); dirClass = new RubyClass(null, objectClass, "Dir"); errnoModule = new RubyModule(moduleClass, null, "Errno"); falseClass = new RubyClass(null, objectClass, "FalseClass"); fiberClass = new RubyFiber.RubyFiberClass(objectClass); fileClass = new RubyClass(null, ioClass, "File"); fixnumClass = new RubyClass(null, integerClass, "Fixnum"); floatClass = new RubyClass(null, objectClass, "Float"); hashClass = new RubyHash.RubyHashClass(objectClass); kernelModule = new RubyModule(moduleClass, null, "Kernel"); loadErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LoadError"); localJumpErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LocalJumpError"); matchDataClass = new RubyClass(null, objectClass, "MatchData"); mathModule = new RubyModule(moduleClass, null, "Math"); nameErrorClass = new RubyClass(null, standardErrorClass, "NameError"); nilClass = new RubyClass(null, objectClass, "NilClass"); noMethodErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "NoMethodError"); objectSpaceModule = new RubyModule(moduleClass, null, "ObjectSpace"); procClass = new RubyProc.RubyProcClass(objectClass); processClass = new RubyClass(null, objectClass, "Process"); rangeClass = new RubyClass(null, objectClass, "Range"); rangeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RangeError"); regexpClass = new RubyRegexp.RubyRegexpClass(objectClass); rubyTruffleErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RubyTruffleError"); runtimeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RuntimeError"); stringClass = new RubyString.RubyStringClass(objectClass); structClass = new RubyClass(null, ioClass, "Struct"); signalModule = new RubyModule(moduleClass, null, "Signal"); symbolClass = new RubyClass(null, objectClass, "Symbol"); syntaxErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SyntaxError"); systemCallErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SystemCallError"); systemExitClass = new RubyException.RubyExceptionClass(exceptionClass, "SystemExit"); threadClass = new RubyThread.RubyThreadClass(objectClass); timeClass = new RubyTime.RubyTimeClass(objectClass); trueClass = new RubyClass(null, objectClass, "TrueClass"); typeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "TypeError"); zeroDivisionErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ZeroDivisionError"); // Includes objectClass.include(kernelModule); // Set constants objectClass.setConstant("RUBY_VERSION", new RubyString(stringClass, context.getConfiguration().getRubyVersion().getVersion())); objectClass.setConstant("RUBY_PATCHLEVEL", context.getConfiguration().getRubyVersion().getPatch()); objectClass.setConstant("RUBY_ENGINE", new RubyString(stringClass, "rubytruffle")); objectClass.setConstant("RUBY_PLATFORM", new RubyString(stringClass, "jvm")); argv = new RubyArray(arrayClass, new ObjectArrayStore()); objectClass.setConstant("ARGV", argv); objectClass.setConstant("ENV", getEnv()); final RubyHash configHash = new RubyHash(hashClass); configHash.put(new RubyString(stringClass, "ruby_install_name"), new RubyString(stringClass, "rubytruffle")); configHash.put(new RubyString(stringClass, "RUBY_INSTALL_NAME"), new RubyString(stringClass, "rubytruffle")); configHash.put(new RubyString(stringClass, "host_os"), new RubyString(stringClass, "unknown")); configHash.put(new RubyString(stringClass, "exeext"), new RubyString(stringClass, "")); configHash.put(new RubyString(stringClass, "EXEEXT"), new RubyString(stringClass, "rubytruffle")); configModule.setConstant("CONFIG", configHash); objectClass.setConstant("RbConfig", configModule); mathModule.setConstant("PI", Math.PI); fileClass.setConstant("SEPARATOR", new RubyString(stringClass, File.separator)); fileClass.setConstant("Separator", new RubyString(stringClass, File.separator)); fileClass.setConstant("ALT_SEPARATOR", NilPlaceholder.INSTANCE); fileClass.setConstant("PATH_SEPARATOR", new RubyString(stringClass, File.pathSeparator)); fileClass.setConstant("FNM_SYSCASE", 0); errnoModule.setConstant("ENOENT", new RubyClass(null, systemCallErrorClass, "ENOENT")); errnoModule.setConstant("EPERM", new RubyClass(null, systemCallErrorClass, "EPERM")); errnoModule.setConstant("ENOTEMPTY", new RubyClass(null, systemCallErrorClass, "ENOTEMPTY")); errnoModule.setConstant("EEXIST", new RubyClass(null, systemCallErrorClass, "EEXIST")); errnoModule.setConstant("EXDEV", new RubyClass(null, systemCallErrorClass, "EXDEV")); errnoModule.setConstant("EACCES", new RubyClass(null, systemCallErrorClass, "EACCES")); // Add all classes and modules as constants in Object final RubyModule[] modules = {argumentErrorClass, // arrayClass, // basicObjectClass, // bignumClass, // bindingClass, // classClass, // continuationClass, // comparableModule, // configModule, // debugModule, // dirClass, // errnoModule, // exceptionClass, // falseClass, // fiberClass, // fileClass, // fixnumClass, // floatClass, // hashClass, // integerClass, // ioClass, // kernelModule, // loadErrorClass, // localJumpErrorClass, // matchDataClass, // mathModule, // moduleClass, // nameErrorClass, // nilClass, // noMethodErrorClass, // numericClass, // objectClass, // objectSpaceModule, // procClass, // processClass, // rangeClass, // rangeErrorClass, // regexpClass, // rubyTruffleErrorClass, // runtimeErrorClass, // signalModule, // standardErrorClass, // stringClass, // structClass, // symbolClass, // syntaxErrorClass, // systemCallErrorClass, // systemExitClass, // threadClass, // timeClass, // trueClass, // typeErrorClass, // zeroDivisionErrorClass}; for (RubyModule module : modules) { objectClass.setConstant(module.getName(), module); } // Create some key objects mainObject = new RubyObject(objectClass); nilObject = new RubyNilClass(nilClass); trueObject = new RubyTrueClass(trueClass); falseObject = new RubyFalseClass(falseClass); // Create the globals object globalVariablesObject = new RubyBasicObject(objectClass); globalVariablesObject.switchToPrivateLayout(); globalVariablesObject.setInstanceVariable("$:", new RubyArray(arrayClass, new ObjectArrayStore())); } public void initializeAfterMethodsAdded() { bignumClass.getSingletonClass().undefMethod("new"); falseClass.getSingletonClass().undefMethod("new"); fixnumClass.getSingletonClass().undefMethod("new"); floatClass.getSingletonClass().undefMethod("new"); integerClass.getSingletonClass().undefMethod("new"); nilClass.getSingletonClass().undefMethod("new"); numericClass.getSingletonClass().undefMethod("new"); trueClass.getSingletonClass().undefMethod("new"); } public RubyBasicObject box(Object object) { assert RubyContext.shouldObjectBeVisible(object); // TODO(cs): pool common object instances like small Fixnums? if (object instanceof RubyBasicObject) { return (RubyBasicObject) object; } if (object instanceof Boolean) { if ((boolean) object) { return trueObject; } else { return falseObject; } } if (object instanceof Integer) { return new RubyFixnum(fixnumClass, (int) object); } if (object instanceof BigInteger) { return new RubyBignum(bignumClass, (BigInteger) object); } if (object instanceof Double) { return new RubyFloat(floatClass, (double) object); } if (object instanceof NilPlaceholder) { return nilObject; } CompilerDirectives.transferToInterpreter(); throw new UnsupportedOperationException("Don't know how to box " + object.getClass().getName()); } public RubyException runtimeError(String message) { return new RubyException(runtimeErrorClass, message); } public RubyException frozenError(String className) { return runtimeError(String.format("can't modify frozen %s", className)); } public RubyException argumentError(String message) { return new RubyException(argumentErrorClass, message); } public RubyException argumentError(int passed, int required) { return argumentError(String.format("wrong number of arguments (%d for %d)", passed, required)); } public RubyException argumentErrorUncaughtThrow(Object tag) { return argumentError(String.format("uncaught throw `%s'", tag)); } public RubyException localJumpError(String message) { return new RubyException(localJumpErrorClass, message); } public RubyException unexpectedReturn() { return localJumpError("unexpected return"); } public RubyException typeError(String message) { return new RubyException(typeErrorClass, message); } public RubyException typeError(String from, String to) { return typeError(String.format("can't convert %s to %s", from, to)); } public RubyException typeErrorIsNotA(String value, String expectedType) { return typeError(String.format("%s is not a %s", value, expectedType)); } public RubyException typeErrorNeedsToBe(String name, String expectedType) { return typeError(String.format("%s needs to be %s", name, expectedType)); } public RubyException rangeError(String message) { return new RubyException(rangeErrorClass, message); } public RubyException nameError(String message) { return new RubyException(nameErrorClass, message); } public RubyException nameErrorUninitializedConstant(String name) { return nameError(String.format("uninitialized constant %s", name)); } public RubyException nameErrorNoMethod(String name, String object) { return nameError(String.format("undefined local variable or method `%s' for %s", name, object)); } public RubyException nameErrorInstanceNameNotAllowable(String name) { return nameError(String.format("`%s' is not allowable as an instance variable name", name)); } public RubyException nameErrorUncaughtThrow(Object tag) { return nameError(String.format("uncaught throw `%s'", tag)); } public RubyException noMethodError(String message) { return new RubyException(context.getCoreLibrary().getNoMethodErrorClass(), message); } public RubyException noMethodError(String name, String object) { return noMethodError(String.format("undefined method `%s' for %s", name, object)); } public RubyException loadError(String message) { return new RubyException(context.getCoreLibrary().getLoadErrorClass(), message); } public RubyException loadErrorCannotLoad(String name) { return loadError(String.format("cannot load such file -- %s", name)); } public RubyException zeroDivisionError() { return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0"); } public RubyContext getContext() { return context; } public RubyClass getArgumentErrorClass() { return argumentErrorClass; } public RubyClass getArrayClass() { return arrayClass; } public RubyClass getBasicObjectClass() { return basicObjectClass; } public RubyClass getBignumClass() { return bignumClass; } public RubyClass getBindingClass() { return bindingClass; } public RubyClass getClassClass() { return classClass; } public RubyModule getComparableClass() { return comparableModule; } public RubyClass getContinuationClass() { return continuationClass; } public RubyClass getDirClass() { return dirClass; } public RubyClass getExceptionClass() { return exceptionClass; } public RubyClass getFalseClass() { return falseClass; } public RubyClass getFiberClass() { return fiberClass; } public RubyClass getFileClass() { return fileClass; } public RubyClass getFixnumClass() { return fixnumClass; } public RubyClass getFloatClass() { return floatClass; } public RubyClass getHashClass() { return hashClass; } public RubyClass getIntegerClass() { return integerClass; } public RubyClass getIoClass() { return ioClass; } public RubyClass getLoadErrorClass() { return loadErrorClass; } public RubyClass getLocalJumpErrorClass() { return localJumpErrorClass; } public RubyClass getMatchDataClass() { return matchDataClass; } public RubyClass getModuleClass() { return moduleClass; } public RubyClass getNameErrorClass() { return nameErrorClass; } public RubyClass getNilClass() { return nilClass; } public RubyClass getNoMethodErrorClass() { return noMethodErrorClass; } public RubyClass getNumericClass() { return numericClass; } public RubyClass getObjectClass() { return objectClass; } public RubyClass getProcClass() { return procClass; } public RubyClass getProcessClass() { return processClass; } public RubyClass getRangeClass() { return rangeClass; } public RubyClass getRangeErrorClass() { return rangeErrorClass; } public RubyClass getRegexpClass() { return regexpClass; } public RubyClass getRubyTruffleErrorClass() { return rubyTruffleErrorClass; } public RubyClass getRuntimeErrorClass() { return runtimeErrorClass; } public RubyModule getSignalModule() { return signalModule; } public RubyClass getStandardErrorClass() { return standardErrorClass; } public RubyClass getStringClass() { return stringClass; } public RubyClass getStructClass() { return structClass; } public RubyClass getSymbolClass() { return symbolClass; } public RubyClass getSyntaxErrorClass() { return syntaxErrorClass; } public RubyClass getSystemCallErrorClass() { return systemCallErrorClass; } public RubyClass getThreadClass() { return threadClass; } public RubyClass getTimeClass() { return timeClass; } public RubyClass getTrueClass() { return trueClass; } public RubyClass getTypeErrorClass() { return typeErrorClass; } public RubyClass getZeroDivisionErrorClass() { return zeroDivisionErrorClass; } public RubyModule getKernelModule() { return kernelModule; } public RubyModule getMathModule() { return mathModule; } public RubyModule getObjectSpaceModule() { return objectSpaceModule; } public RubyModule getDebugModule() { return debugModule; } public RubyArray getArgv() { return argv; } public RubyBasicObject getGlobalVariablesObject() { return globalVariablesObject; } public RubyBasicObject getMainObject() { return mainObject; } public RubyFalseClass getFalseObject() { return falseObject; } public RubyNilClass getNilObject() { return nilObject; } public RubyTrueClass getTrueObject() { return trueObject; } public RubyHash getEnv() { final RubyHash hash = new RubyHash(context.getCoreLibrary().getHashClass()); for (Map.Entry<String, String> variable : System.getenv().entrySet()) { hash.put(context.makeString(variable.getKey()), context.makeString(variable.getValue())); } return hash; } }