comparison 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
comparison
equal deleted inserted replaced
13513:64a23ce736a0 13514:0fbee3eb71f0
1 /*
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
4 * redistribute it and/or modify it under the terms of the:
5 *
6 * Eclipse Public License version 1.0
7 * GNU General Public License version 2
8 * GNU Lesser General Public License version 2.1
9 */
10 package com.oracle.truffle.ruby.runtime.core;
11
12 import java.io.*;
13 import java.math.*;
14 import java.util.*;
15
16 import com.oracle.truffle.api.*;
17 import com.oracle.truffle.ruby.runtime.*;
18 import com.oracle.truffle.ruby.runtime.core.array.*;
19 import com.oracle.truffle.ruby.runtime.objects.*;
20
21 public class CoreLibrary {
22
23 private final RubyContext context;
24
25 private RubyClass argumentErrorClass;
26 private RubyClass arrayClass;
27 private RubyClass basicObjectClass;
28 private RubyClass bignumClass;
29 private RubyClass bindingClass;
30 private RubyClass classClass;
31 private RubyClass continuationClass;
32 private RubyClass dirClass;
33 private RubyClass exceptionClass;
34 private RubyClass falseClass;
35 private RubyClass fiberClass;
36 private RubyClass fileClass;
37 private RubyClass fixnumClass;
38 private RubyClass floatClass;
39 private RubyClass hashClass;
40 private RubyClass integerClass;
41 private RubyClass ioClass;
42 private RubyClass loadErrorClass;
43 private RubyClass localJumpErrorClass;
44 private RubyClass matchDataClass;
45 private RubyClass moduleClass;
46 private RubyClass nameErrorClass;
47 private RubyClass nilClass;
48 private RubyClass noMethodErrorClass;
49 private RubyClass numericClass;
50 private RubyClass objectClass;
51 private RubyClass procClass;
52 private RubyClass processClass;
53 private RubyClass rangeClass;
54 private RubyClass rangeErrorClass;
55 private RubyClass regexpClass;
56 private RubyClass rubyTruffleErrorClass;
57 private RubyClass runtimeErrorClass;
58 private RubyClass standardErrorClass;
59 private RubyClass stringClass;
60 private RubyClass structClass;
61 private RubyClass symbolClass;
62 private RubyClass syntaxErrorClass;
63 private RubyClass systemCallErrorClass;
64 private RubyClass systemExitClass;
65 private RubyClass threadClass;
66 private RubyClass timeClass;
67 private RubyClass trueClass;
68 private RubyClass typeErrorClass;
69 private RubyClass zeroDivisionErrorClass;
70
71 private RubyModule comparableModule;
72 private RubyModule configModule;
73 private RubyModule errnoModule;
74 private RubyModule kernelModule;
75 private RubyModule mathModule;
76 private RubyModule objectSpaceModule;
77 private RubyModule signalModule;
78
79 private RubyModule debugModule;
80 private RubyArray argv;
81 private RubyBasicObject globalVariablesObject;
82 private RubyBasicObject mainObject;
83 private RubyFalseClass falseObject;
84 private RubyNilClass nilObject;
85 private RubyTrueClass trueObject;
86
87 public CoreLibrary(RubyContext context) {
88 this.context = context;
89 }
90
91 public void initialize() {
92 // Create the cyclic classes and modules
93
94 classClass = new RubyClass.RubyClassClass(context);
95 basicObjectClass = new RubyClass(context, classClass, null, null, "BasicObject");
96 objectClass = new RubyClass(null, basicObjectClass, "Object");
97 moduleClass = new RubyModule.RubyModuleClass(context);
98
99 // Close the cycles
100
101 moduleClass.unsafeSetRubyClass(classClass);
102 classClass.unsafeSetSuperclass(moduleClass);
103 moduleClass.unsafeSetSuperclass(objectClass);
104 classClass.unsafeSetRubyClass(classClass);
105
106 // Create all other classes and modules
107
108 numericClass = new RubyClass(null, objectClass, "Numeric");
109 integerClass = new RubyClass(null, numericClass, "Integer");
110
111 exceptionClass = new RubyException.RubyExceptionClass(objectClass, "Exception");
112 standardErrorClass = new RubyException.RubyExceptionClass(exceptionClass, "StandardError");
113
114 ioClass = new RubyClass(null, objectClass, "IO");
115
116 argumentErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ArgumentError");
117 arrayClass = new RubyArray.RubyArrayClass(objectClass);
118 bignumClass = new RubyClass(null, integerClass, "Bignum");
119 bindingClass = new RubyClass(null, objectClass, "Binding");
120 continuationClass = new RubyClass(null, objectClass, "Continuation");
121 comparableModule = new RubyModule(moduleClass, null, "Comparable");
122 configModule = new RubyModule(moduleClass, null, "Config");
123 debugModule = new RubyModule(moduleClass, null, "Debug");
124 dirClass = new RubyClass(null, objectClass, "Dir");
125 errnoModule = new RubyModule(moduleClass, null, "Errno");
126 falseClass = new RubyClass(null, objectClass, "FalseClass");
127 fiberClass = new RubyFiber.RubyFiberClass(objectClass);
128 fileClass = new RubyClass(null, ioClass, "File");
129 fixnumClass = new RubyClass(null, integerClass, "Fixnum");
130 floatClass = new RubyClass(null, objectClass, "Float");
131 hashClass = new RubyHash.RubyHashClass(objectClass);
132 kernelModule = new RubyModule(moduleClass, null, "Kernel");
133 loadErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LoadError");
134 localJumpErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LocalJumpError");
135 matchDataClass = new RubyClass(null, objectClass, "MatchData");
136 mathModule = new RubyModule(moduleClass, null, "Math");
137 nameErrorClass = new RubyClass(null, standardErrorClass, "NameError");
138 nilClass = new RubyClass(null, objectClass, "NilClass");
139 noMethodErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "NoMethodError");
140 objectSpaceModule = new RubyModule(moduleClass, null, "ObjectSpace");
141 procClass = new RubyProc.RubyProcClass(objectClass);
142 processClass = new RubyClass(null, objectClass, "Process");
143 rangeClass = new RubyClass(null, objectClass, "Range");
144 rangeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RangeError");
145 regexpClass = new RubyRegexp.RubyRegexpClass(objectClass);
146 rubyTruffleErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RubyTruffleError");
147 runtimeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RuntimeError");
148 stringClass = new RubyString.RubyStringClass(objectClass);
149 structClass = new RubyClass(null, ioClass, "Struct");
150 signalModule = new RubyModule(moduleClass, null, "Signal");
151 symbolClass = new RubyClass(null, objectClass, "Symbol");
152 syntaxErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SyntaxError");
153 systemCallErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SystemCallError");
154 systemExitClass = new RubyException.RubyExceptionClass(exceptionClass, "SystemExit");
155 threadClass = new RubyThread.RubyThreadClass(objectClass);
156 timeClass = new RubyTime.RubyTimeClass(objectClass);
157 trueClass = new RubyClass(null, objectClass, "TrueClass");
158 typeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "TypeError");
159 zeroDivisionErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ZeroDivisionError");
160
161 // Includes
162
163 objectClass.include(kernelModule);
164
165 // Set constants
166
167 objectClass.setConstant("RUBY_VERSION", new RubyString(stringClass, context.getConfiguration().getRubyVersion().getVersion()));
168 objectClass.setConstant("RUBY_PATCHLEVEL", context.getConfiguration().getRubyVersion().getPatch());
169 objectClass.setConstant("RUBY_ENGINE", new RubyString(stringClass, "rubytruffle"));
170 objectClass.setConstant("RUBY_PLATFORM", new RubyString(stringClass, "jvm"));
171
172 argv = new RubyArray(arrayClass, new ObjectArrayStore());
173 objectClass.setConstant("ARGV", argv);
174 objectClass.setConstant("ENV", getEnv());
175
176 final RubyHash configHash = new RubyHash(hashClass);
177 configHash.put(new RubyString(stringClass, "ruby_install_name"), new RubyString(stringClass, "rubytruffle"));
178 configHash.put(new RubyString(stringClass, "RUBY_INSTALL_NAME"), new RubyString(stringClass, "rubytruffle"));
179 configHash.put(new RubyString(stringClass, "host_os"), new RubyString(stringClass, "unknown"));
180 configHash.put(new RubyString(stringClass, "exeext"), new RubyString(stringClass, ""));
181 configHash.put(new RubyString(stringClass, "EXEEXT"), new RubyString(stringClass, "rubytruffle"));
182 configModule.setConstant("CONFIG", configHash);
183 objectClass.setConstant("RbConfig", configModule);
184
185 mathModule.setConstant("PI", Math.PI);
186
187 fileClass.setConstant("SEPARATOR", new RubyString(stringClass, File.separator));
188 fileClass.setConstant("Separator", new RubyString(stringClass, File.separator));
189 fileClass.setConstant("ALT_SEPARATOR", NilPlaceholder.INSTANCE);
190 fileClass.setConstant("PATH_SEPARATOR", new RubyString(stringClass, File.pathSeparator));
191 fileClass.setConstant("FNM_SYSCASE", 0);
192
193 errnoModule.setConstant("ENOENT", new RubyClass(null, systemCallErrorClass, "ENOENT"));
194 errnoModule.setConstant("EPERM", new RubyClass(null, systemCallErrorClass, "EPERM"));
195 errnoModule.setConstant("ENOTEMPTY", new RubyClass(null, systemCallErrorClass, "ENOTEMPTY"));
196 errnoModule.setConstant("EEXIST", new RubyClass(null, systemCallErrorClass, "EEXIST"));
197 errnoModule.setConstant("EXDEV", new RubyClass(null, systemCallErrorClass, "EXDEV"));
198 errnoModule.setConstant("EACCES", new RubyClass(null, systemCallErrorClass, "EACCES"));
199
200 // Add all classes and modules as constants in Object
201
202 final RubyModule[] modules = {argumentErrorClass, //
203 arrayClass, //
204 basicObjectClass, //
205 bignumClass, //
206 bindingClass, //
207 classClass, //
208 continuationClass, //
209 comparableModule, //
210 configModule, //
211 debugModule, //
212 dirClass, //
213 errnoModule, //
214 exceptionClass, //
215 falseClass, //
216 fiberClass, //
217 fileClass, //
218 fixnumClass, //
219 floatClass, //
220 hashClass, //
221 integerClass, //
222 ioClass, //
223 kernelModule, //
224 loadErrorClass, //
225 localJumpErrorClass, //
226 matchDataClass, //
227 mathModule, //
228 moduleClass, //
229 nameErrorClass, //
230 nilClass, //
231 noMethodErrorClass, //
232 numericClass, //
233 objectClass, //
234 objectSpaceModule, //
235 procClass, //
236 processClass, //
237 rangeClass, //
238 rangeErrorClass, //
239 regexpClass, //
240 rubyTruffleErrorClass, //
241 runtimeErrorClass, //
242 signalModule, //
243 standardErrorClass, //
244 stringClass, //
245 structClass, //
246 symbolClass, //
247 syntaxErrorClass, //
248 systemCallErrorClass, //
249 systemExitClass, //
250 threadClass, //
251 timeClass, //
252 trueClass, //
253 typeErrorClass, //
254 zeroDivisionErrorClass};
255
256 for (RubyModule module : modules) {
257 objectClass.setConstant(module.getName(), module);
258 }
259
260 // Create some key objects
261
262 mainObject = new RubyObject(objectClass);
263 nilObject = new RubyNilClass(nilClass);
264 trueObject = new RubyTrueClass(trueClass);
265 falseObject = new RubyFalseClass(falseClass);
266
267 // Create the globals object
268
269 globalVariablesObject = new RubyBasicObject(objectClass);
270 globalVariablesObject.switchToPrivateLayout();
271 globalVariablesObject.setInstanceVariable("$:", new RubyArray(arrayClass, new ObjectArrayStore()));
272 }
273
274 public void initializeAfterMethodsAdded() {
275 bignumClass.getSingletonClass().undefMethod("new");
276 falseClass.getSingletonClass().undefMethod("new");
277 fixnumClass.getSingletonClass().undefMethod("new");
278 floatClass.getSingletonClass().undefMethod("new");
279 integerClass.getSingletonClass().undefMethod("new");
280 nilClass.getSingletonClass().undefMethod("new");
281 numericClass.getSingletonClass().undefMethod("new");
282 trueClass.getSingletonClass().undefMethod("new");
283 }
284
285 public RubyBasicObject box(Object object) {
286 assert RubyContext.shouldObjectBeVisible(object);
287
288 // TODO(cs): pool common object instances like small Fixnums?
289
290 if (object instanceof RubyBasicObject) {
291 return (RubyBasicObject) object;
292 }
293
294 if (object instanceof Boolean) {
295 if ((boolean) object) {
296 return trueObject;
297 } else {
298 return falseObject;
299 }
300 }
301
302 if (object instanceof Integer) {
303 return new RubyFixnum(fixnumClass, (int) object);
304 }
305
306 if (object instanceof BigInteger) {
307 return new RubyBignum(bignumClass, (BigInteger) object);
308 }
309
310 if (object instanceof Double) {
311 return new RubyFloat(floatClass, (double) object);
312 }
313
314 if (object instanceof NilPlaceholder) {
315 return nilObject;
316 }
317
318 CompilerDirectives.transferToInterpreter();
319
320 throw new UnsupportedOperationException("Don't know how to box " + object.getClass().getName());
321 }
322
323 public RubyException runtimeError(String message) {
324 return new RubyException(runtimeErrorClass, message);
325 }
326
327 public RubyException frozenError(String className) {
328 return runtimeError(String.format("can't modify frozen %s", className));
329 }
330
331 public RubyException argumentError(String message) {
332 return new RubyException(argumentErrorClass, message);
333 }
334
335 public RubyException argumentError(int passed, int required) {
336 return argumentError(String.format("wrong number of arguments (%d for %d)", passed, required));
337 }
338
339 public RubyException argumentErrorUncaughtThrow(Object tag) {
340 return argumentError(String.format("uncaught throw `%s'", tag));
341 }
342
343 public RubyException localJumpError(String message) {
344 return new RubyException(localJumpErrorClass, message);
345 }
346
347 public RubyException unexpectedReturn() {
348 return localJumpError("unexpected return");
349 }
350
351 public RubyException typeError(String message) {
352 return new RubyException(typeErrorClass, message);
353 }
354
355 public RubyException typeError(String from, String to) {
356 return typeError(String.format("can't convert %s to %s", from, to));
357 }
358
359 public RubyException typeErrorIsNotA(String value, String expectedType) {
360 return typeError(String.format("%s is not a %s", value, expectedType));
361 }
362
363 public RubyException typeErrorNeedsToBe(String name, String expectedType) {
364 return typeError(String.format("%s needs to be %s", name, expectedType));
365 }
366
367 public RubyException rangeError(String message) {
368 return new RubyException(rangeErrorClass, message);
369 }
370
371 public RubyException nameError(String message) {
372 return new RubyException(nameErrorClass, message);
373 }
374
375 public RubyException nameErrorUninitializedConstant(String name) {
376 return nameError(String.format("uninitialized constant %s", name));
377 }
378
379 public RubyException nameErrorNoMethod(String name, String object) {
380 return nameError(String.format("undefined local variable or method `%s' for %s", name, object));
381 }
382
383 public RubyException nameErrorInstanceNameNotAllowable(String name) {
384 return nameError(String.format("`%s' is not allowable as an instance variable name", name));
385 }
386
387 public RubyException nameErrorUncaughtThrow(Object tag) {
388 return nameError(String.format("uncaught throw `%s'", tag));
389 }
390
391 public RubyException noMethodError(String message) {
392 return new RubyException(context.getCoreLibrary().getNoMethodErrorClass(), message);
393 }
394
395 public RubyException noMethodError(String name, String object) {
396 return noMethodError(String.format("undefined method `%s' for %s", name, object));
397 }
398
399 public RubyException loadError(String message) {
400 return new RubyException(context.getCoreLibrary().getLoadErrorClass(), message);
401 }
402
403 public RubyException loadErrorCannotLoad(String name) {
404 return loadError(String.format("cannot load such file -- %s", name));
405 }
406
407 public RubyException zeroDivisionError() {
408 return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0");
409 }
410
411 public RubyContext getContext() {
412 return context;
413 }
414
415 public RubyClass getArgumentErrorClass() {
416 return argumentErrorClass;
417 }
418
419 public RubyClass getArrayClass() {
420 return arrayClass;
421 }
422
423 public RubyClass getBasicObjectClass() {
424 return basicObjectClass;
425 }
426
427 public RubyClass getBignumClass() {
428 return bignumClass;
429 }
430
431 public RubyClass getBindingClass() {
432 return bindingClass;
433 }
434
435 public RubyClass getClassClass() {
436 return classClass;
437 }
438
439 public RubyModule getComparableClass() {
440 return comparableModule;
441 }
442
443 public RubyClass getContinuationClass() {
444 return continuationClass;
445 }
446
447 public RubyClass getDirClass() {
448 return dirClass;
449 }
450
451 public RubyClass getExceptionClass() {
452 return exceptionClass;
453 }
454
455 public RubyClass getFalseClass() {
456 return falseClass;
457 }
458
459 public RubyClass getFiberClass() {
460 return fiberClass;
461 }
462
463 public RubyClass getFileClass() {
464 return fileClass;
465 }
466
467 public RubyClass getFixnumClass() {
468 return fixnumClass;
469 }
470
471 public RubyClass getFloatClass() {
472 return floatClass;
473 }
474
475 public RubyClass getHashClass() {
476 return hashClass;
477 }
478
479 public RubyClass getIntegerClass() {
480 return integerClass;
481 }
482
483 public RubyClass getIoClass() {
484 return ioClass;
485 }
486
487 public RubyClass getLoadErrorClass() {
488 return loadErrorClass;
489 }
490
491 public RubyClass getLocalJumpErrorClass() {
492 return localJumpErrorClass;
493 }
494
495 public RubyClass getMatchDataClass() {
496 return matchDataClass;
497 }
498
499 public RubyClass getModuleClass() {
500 return moduleClass;
501 }
502
503 public RubyClass getNameErrorClass() {
504 return nameErrorClass;
505 }
506
507 public RubyClass getNilClass() {
508 return nilClass;
509 }
510
511 public RubyClass getNoMethodErrorClass() {
512 return noMethodErrorClass;
513 }
514
515 public RubyClass getNumericClass() {
516 return numericClass;
517 }
518
519 public RubyClass getObjectClass() {
520 return objectClass;
521 }
522
523 public RubyClass getProcClass() {
524 return procClass;
525 }
526
527 public RubyClass getProcessClass() {
528 return processClass;
529 }
530
531 public RubyClass getRangeClass() {
532 return rangeClass;
533 }
534
535 public RubyClass getRangeErrorClass() {
536 return rangeErrorClass;
537 }
538
539 public RubyClass getRegexpClass() {
540 return regexpClass;
541 }
542
543 public RubyClass getRubyTruffleErrorClass() {
544 return rubyTruffleErrorClass;
545 }
546
547 public RubyClass getRuntimeErrorClass() {
548 return runtimeErrorClass;
549 }
550
551 public RubyModule getSignalModule() {
552 return signalModule;
553 }
554
555 public RubyClass getStandardErrorClass() {
556 return standardErrorClass;
557 }
558
559 public RubyClass getStringClass() {
560 return stringClass;
561 }
562
563 public RubyClass getStructClass() {
564 return structClass;
565 }
566
567 public RubyClass getSymbolClass() {
568 return symbolClass;
569 }
570
571 public RubyClass getSyntaxErrorClass() {
572 return syntaxErrorClass;
573 }
574
575 public RubyClass getSystemCallErrorClass() {
576 return systemCallErrorClass;
577 }
578
579 public RubyClass getThreadClass() {
580 return threadClass;
581 }
582
583 public RubyClass getTimeClass() {
584 return timeClass;
585 }
586
587 public RubyClass getTrueClass() {
588 return trueClass;
589 }
590
591 public RubyClass getTypeErrorClass() {
592 return typeErrorClass;
593 }
594
595 public RubyClass getZeroDivisionErrorClass() {
596 return zeroDivisionErrorClass;
597 }
598
599 public RubyModule getKernelModule() {
600 return kernelModule;
601 }
602
603 public RubyModule getMathModule() {
604 return mathModule;
605 }
606
607 public RubyModule getObjectSpaceModule() {
608 return objectSpaceModule;
609 }
610
611 public RubyModule getDebugModule() {
612 return debugModule;
613 }
614
615 public RubyArray getArgv() {
616 return argv;
617 }
618
619 public RubyBasicObject getGlobalVariablesObject() {
620 return globalVariablesObject;
621 }
622
623 public RubyBasicObject getMainObject() {
624 return mainObject;
625 }
626
627 public RubyFalseClass getFalseObject() {
628 return falseObject;
629 }
630
631 public RubyNilClass getNilObject() {
632 return nilObject;
633 }
634
635 public RubyTrueClass getTrueObject() {
636 return trueObject;
637 }
638
639 public RubyHash getEnv() {
640 final RubyHash hash = new RubyHash(context.getCoreLibrary().getHashClass());
641
642 for (Map.Entry<String, String> variable : System.getenv().entrySet()) {
643 hash.put(context.makeString(variable.getKey()), context.makeString(variable.getValue()));
644 }
645
646 return hash;
647 }
648
649 }