Giter Site home page Giter Site logo

rubinius / rubinius Goto Github PK

View Code? Open in Web Editor NEW
3.1K 3.1K 587.0 164.13 MB

The Rubinius Language Platform

Home Page: https://rubinius.com

License: Mozilla Public License 2.0

Ruby 25.31% Perl 0.04% Shell 2.94% C 57.90% C++ 7.48% DTrace 0.02% Python 0.02% HTML 0.11% Makefile 2.06% Batchfile 0.01% GDB 0.01% Roff 0.53% M4 0.34% Assembly 1.87% TeX 0.93% CMake 0.04% SAS 0.01% CLIPS 0.01% Pascal 0.17% Ada 0.21%
programming-languages rubinius virtual-machine

rubinius's Introduction

Gitter Build Status

The Rubinius Language Platform

Rubinius is a modern language platform that supports a number of programming languages.

The philosophy and high-level architecture of Rubinius are described below.

Rubinius runs on macOS and many Unix/Linux operating systems. Microsoft Windows is not supported.

Code of Conduct

Participation in the Rubinius project is governed by the Rubinius Code of Conduct.

Issues & Support

Please file tickets for bugs or problems.

For additional help, visit the Rubinius Gitter chat room.

Contributing

We welcome contributions. For more information, see the FAQ below and read the contributing file.

License

All source code in this repository is subject to the terms of the Mozilla Public License, version 2.0 unless stated otherwise. A copy of this license can be found the file "LICENSE" or at https://www.mozilla.org/MPL/2.0/.

Contributions made prior to January 3rd, 2016 are licensed under the old BSD 3-clause license. A copy of this license can be found in the file "BSD_LICENSE".

In the event a directory contains a "LICENSE", "LICENSE.txt" or "COPYING" file the license specified in said file applies to the contents of said directory and all sub directories, overwriting the licenses specified above.

Installing Rubinius

To install Rubinius from source, use the following steps:

  1. Ensure that MRI 2.0+, rubygems, rake, and git are installed
  2. git clone git://github.com/rubinius/rubinius.git
  3. cd rubinius
  4. ./configure --prefix=/path/to/install/dir && make install

When the install process finishes, follow the directions printed to the terminal to add the Rubinius executable (bin) directory to your PATH.

Certain setups of openssl require you to pass along additional options, --with-lib-dir and --with-include-dir pointing to include the relevant openssl directories.

E.g If you are installing via RVM / homebrew on OS X.

rvm install rbx-3 -C \
  --with-lib-dir=$(brew --prefix openssl)/lib \
  --with-include-dir=$(brew --prefix openssl)/include

See https://book.rubinius.com/manuscript/getting_rubinius.html for a more complete guide to installing Rubinius from source.

Philosophy & Architecture

Rubinius is a virtual computing machine. As a computing machine, it possesses several mechanisms that physical computers possess to support computation.

It runs in an environment that provides various capabilities. These are presented to the machine through the Environment object.

It has certain configuration values that influence how the machine operates. This is managed by the Configuration object.

The machine has a boot process that carefully builds up the components in a precise order until the machine is ready to run user code. When the user code completes executing, the machine halts, again following a precise sequence of deconstructing the various components.

The rest of the components of the machine are described below.

Instructions

The Rubinius instruction set includes different categories of instructions. One key aspect of the Rubinius philosophy is that the instruction set should represent any machine semantic. This contrasts with the way Rubinius has been implemented historically, which relied heavily on C++ "primitives" modeled on the Smalltalk 80 virtual machine. All the primitives are being replaced as the instruction set evolves richer capabilities.

The categories of instructions are:

  1. Stack instructions that push, pop, and get operands from a stack;
  2. Register instructions that read from and write to a set of registers;
  3. Assertion instructions that can halt execution but cannot change the semantics of the program;
  4. Instrumentation instructions that cannot change the semantics of the program but can emit data from the program;
  5. Parsing Expression Grammar (PEG) instructions. PEGs are an elegant formalism for describing recognizers;
  6. Foreign Function Interface (FFI) instructions for binding and calling external functions;
  7. Concurrency instructions for execution threads and concurrent data;
  8. System instructions for accessing files, directories, and other systam capabilities.

TODO: There's plenty of places to help out here if parsers, compilers, and instruction sets interest you.

Heaps & Garbage Collector

Rubinius has two kinds of managed objects: object-oriented ones that can support inheriting from a superclass, and data objects that have no concept of object-orientation.

Rubinius has three concepts for heaps, the space where managed objects live:

  1. The open heap is one where any object in the heap can contain a reference to any other object. Think normal Ruby land;
  2. The closed heap is one where an object in the heap can contain a reference to an object outside the closed heap, but no object outside can contain a reference to an object in the closed heap;
  3. The isolated heap is one where no object in the isolated heap can contain a reference to an object outside the heap, and no object outside can contain a reference to an object in the isolated heap.

Threads that use isolated heaps can execute fully independent of any other thread and only must synchronize with the process during boot, fork, and halt. The garbage collector for isolated heaps is run in that thread.

Rubinius uses a single mechanism for garbage collection, the Immix mark-region collector.

The Rubinius garbage collector currently runs on a single separate thread and must fully synchronize all threads that mutate managed memory (ie it stops the world). In the future, the single open heap will introduce a second generational area, and the isolated heaps will provide for parallel collection.

TODO: There's plenty of places to help out here if garbage collectors interest you.

CodeDB

The Rubinius CodeDB is where all compiled code for the core and standard libraries is stored. Every executable context (in Ruby, these are scripts, class & module bodies, methods, and blocks) has a unique ID and is cached in the CodeDB. In the future, all user code will also be cached in the CodeDB.

The unique ID of every executable context allows for associating arbitrary dimensions of data with that instance of executable code. For example, type information seen at run time, profile and coverage information, call graphs, and memory allocations data can all be associated with the executable code.

TODO: There's plenty of places to help out here if databases and code analytics interest you.

Console

The Console is an interprocess communication (IPC) mechanism. In contrast to Ruby's IRB, which executes in the same process, the Rubinius Console is intended to be a general purpose mechanism to interact with the virtual machine. The capabilities of the Console include the ability to execute code and return the result, start/step/stop the Debugger, start/stop the Profiler, access data from the Profiler and Diagnostics, and fetch the call graph and object graph data.

TODO: There's plenty of places to help out here if developer tools interest you.

Debugger

The Debugger uses instruction replacement (ie substituting the debug instruction for the existing instruction at that point in the instruction sequence) to cause an executing instance of code to stop and allow you to inspect values and step to the next instruction, or step into or out of another instance of code (eg a method, function, or block).

TODO: There's plenty of places to help out here if developer tools interest you.

Profiler

The Profiler is a randomized-interval sampling profiler that is always running. At a randomized interval, the code instances that are currently executing in a thread have their sample count incremented. In addition, all code instances have a call count that is incremented each time they are invoked. At every call site, the number of times the call site executes is tracked for each type of object seen. The call sites enable deriving the call graph for the program from the object graph because the call sites have a normal (Ruby) object interface.

TODO: There's plenty of places to help out here if developer tools interest you.

Diagnostics & Logging

The Diagnostics facility provides metrics on all components of the virtual machine. The logging facility includes different log levels (ie debug, info, warn, error) and provides a descriptive account of virtual machine lifecycle events.

TODO: There's plenty of places to help out here if developer tools interest you.

Machine-code Compiler

The machine-code compiler is based on LLVM and compiles a managed code instance to machine code. The first generation Rubinius JIT (just-in-time compiler) included type inference, custom code passes, and inlining facilities all implemented in C++. The next generation compiler uses a nanopass architecture and builds a single managed code instance that can be compiled to native machine code.

TODO: There's plenty of places to help out here if native machine code compilers interest you.

Data Types & Functions

Rubinius has functions. No, really.

$ bin/rbx compile -N plus -B -e 'fun plus(a, b) a + b end'

================ :plus =================
Arguments:   2 required, 0 post, 2 total
Arity:       2
Locals:      2: a, b
Stack size:  4
Registers:   0
Literals:    1: :+
Line:        1
Lines to IP:

0000:  push_local                 0    # a
0002:  push_local                 1    # b
0004:  send_stack                 :+, 1
0007:  unwind                     0
0009:  ret                        0
----------------------------------------

There are several ways that types can be added. First, it's important to distinguish the "behavior" of object-oriented code from the "types" of data. See Objects are for interactions, functions are for data.

For objects, instead of types, we want to be able to easily convey that objects should represent themselves differently:

class A
  def m(a: Integer(2), b: Integer(3))
    # If the values passed for a and b are not Integers,
    # the Integer() constructor will be called on them.
    # If a value isn't passed for a, the default value is 2.
    # Similarly for b, the default value is 3.
  end
end

For functions, the situation is similar, but different:

type :int, fun +(a: int, b: int)
  # The type of a and b must be machine integers.
  # The return type is specified by an annotation
end

fun +(a: int, b: int, return: int)
  # The type of the return value is int.
  # The 'return' argument is elided.
end

fun +(a: int, b: int): int
  # This form would require modifying the parser.
end

Each of these three represent a possibility for implementing types, including the return type for a function. The form that will be implemented hasn't been chosen yet.

Both namespacing and explicit data definition (using either type or data) are not implemented yet, but are definitely being considered. Examples of these would be:

namespace my_funcs
  data size_cat
    value = 'big' | 'small'
    
    fun big?
      value == 'big'
    end
    
    fun small?
      value == 'small'
    end
  end
end

a = my_funcs::size_cat('big')
my_funcs::size_cat::small?(a)  # => false

Functions became particularly interesting when they can be co-mingled with object-oriented code. In Rubinius, the lexical scope is represented by a Ruby object much like any other Ruby object. Since Ruby does not contain language features for manipulating the lexical scope, it's a natural place to stash functions so that lookup seems unsurprising.

class A
  import "my_funcs"
  
  def m(a, b)
    if small?(a) and big?(b)
      puts "We have a mixed mode"
    end
  end
end

A.new.m('small', 'big')
"We have a mixed mode"

In Ruby, any method call that does not explicitly use a receiver could resolve to a function that has been imported to that lexical scope or an exclosing lexical scope.

While the functions and types described in this part are experimental and may or may not actually exist when you read this, the ideas are legitimate. If you are really excited by these features, let us know.

TODO: There's plenty of places to help out here if functions and data types interest you.

C-API

The C-API provides an element of compatibility with Ruby C-extensions. However, the C-API is deprecated and will likely eventually be removed.

FAQ

Q. There's this other <programming language, project, concept, application> that seems <better, faster, cheaper>, shouldn't I use that instead?

A. Yes, absolutely. The sooner the better, really.

Q. Why are there no tickets tagged for beginners?

A. We have a lot of respect for your abilities, whether you've ever written a line of code before or not, whether you've ever worked on a compiler, virtual machine, garbage collector, or debugger before.

Find something that interests you and dive in. If you get stuck, ask a question.

Q. Why isn't <my pet feature> done already? When will it be done?

A. Do you have 1,000,000 USD? No, really.

Q. Why won't you accept my PR to rewrite the virtual machine in <Rust, Go, Node, TypeScript> or add static typing to the Ruby core library or my other terrific idea?

A. There are a lot of fascinating ideas out there. Fork Rubinius, whip up your idea, show that other people find it useful, and let's talk. You might find you've got a far better project than Rubinius. After all, that's what we're doing, trying to figure out what might be useful.

Q. Is there more documentation?

A. Yes, there is a book that needs a lot of love and attention.

Q. Can I embed Rubinius into my favorite C/C++ application?

A. Yes, you can! More of the facilities to support interacting with the Machine will be added over time.

#include "machine.hpp"

int main(int argc, char** argv) {
  rubinius::Machine machine(argc, argv);
  
  machine.boot();
  
  return machine.halt();
}

Q. What about the Ruby programming language?

A. Many popular Ruby applications, like Rails, may run on Rubinius, which aims to be compatible with the most recent stable Ruby version.

Rubinius provides the standard Ruby libraries, with the following exceptions:

  • Continuation
  • Ripper
  • TracePoint
  • Tracer

The following Ruby features are not supported on Rubinius:

  • Refinements
  • $SAFE levels

Q. Isn't Rubinius just a Ruby implementation?

A. No, it's not. Rubinius is an experiment that started as a Ruby implementation, but is attempting to look beyond the limitations of Ruby. Consider Rubinius a mostly compatible superset of Ruby for now.

Q. Why does Rubinius report the Ruby version as 10.0?

A. Rubinius is a time machine. When you use it, you travel into the future. Even this README is in the future.

Q. What is up with the weird version scheme in Rubinius?

A. Rubinius uses a simple epoch.sequence version scheme. For any sequence number N, N+1 will only add new capabilities, or remove something that has been listed as deprecated in <= N. Super simple.

Q. Why does Rubinius not support frozen and tainted?

A. Rubinius has better features; frozen and tainted are considered harmful. To elaborate...

Both frozen and tainted depend on strewing checks throughout the source code. As a classic weak-link system, only one of those checks needs to be misplaced for the guarantees offered by either to fail. Since the number of checks is high, and as new code is written new checks need to be considered, the features inherently constitute unbounded complexity and unbounded risk.

In place of frozen, Rubinius is implementing attributes on classes. One attribute is immutability. The way this works is that every machine instruction has an attribute for whether the instruction would mutate an object. When a method is added to a class, the attributes are checked and any method containing mutating instructions is disallowed. Additionally, dispatch that searches the superclasses of a class marked immutable would also perform this check. Immutability is an indelible attribute that is inherited by all subclasses.

In place of tainted, Rubinius is implementing sanitization functions at the IO boundary, similar to the transcoding facility.

In both cases, the places that the checks must be made are orders of magnitude fewer than in the case of frozen and tainted. The checks are more orderly as well.

Q. Why doesn't Rubinius allow me to set arbitrary encodings for Strings?

A. Rubinius only uses UTF-8 internally. Any transcoding must be performed at the IO boundary.

Q. How do I use RubyGems?

A. Rubinius comes with RubyGems built-in. To install a gem, run the following:

$ rbx -S gem install <gem_name>

Q. Why doesn't Rubinius install gem binaries in the same place as Ruby?

A. Rubinius is intended to be installed alongside Ruby without causing conflicts. Only the main executable, rbx, should be installed into a system directory. Edit your shell PATH to include the directories listed when Rubinius is installed to access other executables like gem binaries.

rubinius's People

Contributors

agardiner avatar ahmadsherif avatar argent-smith avatar arthurschreiber avatar brixen avatar cezarsa avatar chuckremes avatar dbussink avatar dgtized avatar drbrain avatar evanphx avatar ileitch avatar jc00ke avatar jfirebaugh avatar kachick avatar kamal avatar kronos avatar leocassarani avatar marcandre avatar marnen avatar mkhl avatar razielgn avatar rue avatar ryoqun avatar shoe avatar tilman2 avatar vvs avatar wilson avatar wycats avatar zenspider avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubinius's Issues

Module#append_features does not detect cyclic include

Reported by shugo, LH 779.

Module#append_features does not detect cyclic include.

$ cat t.rb          
module A
end

module B
  include A
end

begin
  A.send(:append_features, A)
rescue ArgumentError => e
  p e
end
begin
  B.send(:append_features, A)
rescue ArgumentError => e
  p e
end
p A.ancestors
p B.ancestors
$ ruby -v t.rb 
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
#<ArgumentError: cyclic include detected>
#<ArgumentError: cyclic include detected>
[A, B]
[B, A]
$ rbx -v t.rb
rubinius 0.11.0-dev (1.8.6 8679f8dd 12/31/2009) [i686-pc-linux-gnu]
[A, B, A]
[B, A]

Zlib failures

On ubuntu 9.04 using zlib1g-dev library for zlib, the standard spec run has 30 some odd failures do to Zlib.

  3) Ar#replace replaces a file ERROR
  ArgumentError: method 'to_i': given 1, expected 0
                           Ar#each {} at kernel/common/ar.rb:46
                            File.open at kernel/common/file.rb:69
                      Kernel(Ar)#open at kernel/common/kernel.rb:200
                              Ar#each at kernel/common/ar.rb:63
         Enumerable(Ar)#map (collect) at kernel/common/enumerable_186.rb:17
                              Ar#list at kernel/common/ar.rb:80
      #.__script__ {} at spec/core/ar/replace_spec.rb:66
         Kernel(Object)#instance_eval at kernel/common/eval.rb:119
            Enumerable(Array)#all? {} at kernel/common/enumerable.rb:266
                           Array#each at kernel/bootstrap/array.rb:152
               Enumerable(Array)#all? at kernel/common/enumerable.rb:266
                           Array#each at kernel/bootstrap/array.rb:152
                      main.__script__ at spec/core/ar/replace_spec.rb:5
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
         Compiler::Utils.unified_load at kernel/compiler/compile.rb:89
                          Kernel.load at kernel/common/kernel.rb:672
         Kernel(Object)#instance_eval at kernel/common/eval.rb:119
                           Array#each at kernel/bootstrap/array.rb:152
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
  Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:329
              Rubinius::Loader#script at kernel/loader.rb:326
                Rubinius::Loader#main at kernel/loader.rb:406
                    Object#__script__ at kernel/loader.rb:454

  4)  An exception occurred during: before :each
  Zlib::Deflate#deflate deflates some data ERROR
  Zlib::Error: unknown zlib error -6: incompatible version
                    Zlib.handle_error at lib/zlib.rb:1471
             Zlib::Deflate#initialize at lib/zlib.rb:627
      #.__script__ {} at spec/frozen/library/zlib/deflate/deflate_spec.rb:7
         Kernel(Object)#instance_eval at kernel/common/eval.rb:119
            Enumerable(Array)#all? {} at kernel/common/enumerable.rb:266
                           Array#each at kernel/bootstrap/array.rb:152
               Enumerable(Array)#all? at kernel/common/enumerable.rb:266
                           Array#each at kernel/bootstrap/array.rb:152
                      main.__script__ at spec/frozen/library/zlib/deflate/deflate_spec.rb:4
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
         Compiler::Utils.unified_load at kernel/compiler/compile.rb:89
                          Kernel.load at kernel/common/kernel.rb:672
         Kernel(Object)#instance_eval at kernel/common/eval.rb:119
                           Array#each at kernel/bootstrap/array.rb:152
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
  Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:329
              Rubinius::Loader#script at kernel/loader.rb:326
                Rubinius::Loader#main at kernel/loader.rb:406
                    Object#__script__ at kernel/loader.rb:454

A little more specific information on this bug:

$ cat exp/deflate.rb
require 'zlib'
 
data = "\000" * 10
zipped = Zlib::Deflate.deflate data
 
p zipped
 
$ ruby exp/deflate.rb
"x\234c`\200\001\000\000\n\000\001"
 
$ rbx exp/deflate.rb
An exception occurred running exp/deflate.rb
    No method 'end' on an instance of NilClass. (NoMethodError)
 
Backtrace:
  Kernel(NilClass)#end (method_missing) at kernel/delta/kernel.rb:47
                 Zlib::Deflate.deflate at lib/zlib.rb:601
                       main.__script__ at exp/deflate.rb:4
    Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
           Compiler::Utils.single_load at kernel/compiler/compile.rb:244
   Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:329
               Rubinius::Loader#script at kernel/loader.rb:326
                 Rubinius::Loader#main at kernel/loader.rb:404
                     Object#__script__ at kernel/loader.rb:452

The following example triggers the incompatible version error:

 
$ cat exp/deflate2.rb
require 'zlib'
 
d = Zlib::Deflate.new
d.set_dictionary 'aaaaaaaaaa'
d << 'abcdefghij'
 
p d.finish
 
$ ruby exp/deflate2.rb
"x\273\024\341\003\313KLJNIMK\317\310\314\002\000\025\206\003\370"
$ rbx exp/deflate2.rb
An exception occurred running exp/deflate2.rb
    unknown zlib error -6: incompatible version (Zlib::Error)
 
Backtrace:
                    Zlib.handle_error at lib/zlib.rb:1471
             Zlib::Deflate#initialize at lib/zlib.rb:627
                      main.__script__ at exp/deflate2.rb:3
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:219
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
  Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:329
              Rubinius::Loader#script at kernel/loader.rb:326
                Rubinius::Loader#main at kernel/loader.rb:404
                    Object#__script__ at kernel/loader.rb:452

Local variables in blocks leak their existence (in IRB)

LH 522 reported by manveru.

I found that there is a different behaviour in rubinius for local variables assigned in a block.

# Ruby 1.8:
10.times{ bar = 1 }; bar
#=> NameError: undefined local variable or method `bar' for main:Object

# Rubinius
10.times{ bar = 1 }; bar
# nil

According to evan, the following sexp has to change.

pp "10.times { bar = 1 }; bar".to_sexp
[:block,
 [:newline,
  1,
  "(eval)",
  [:iter,
   [:call, [:lit, 10], :times],
   nil,
   [:block,
    [:dasgn_curr, :bar],
    [:newline, 1, "(eval)", [:lasgn, :bar, [:lit, 1]]]]]],
 [:newline, 1, "(eval)", [:lvar, :bar, 0]]]

that should read

pp "10.times { bar = 1 }; bar".to_sexp
[:block,
 [:newline,
  1,
  "(eval)",
  [:iter,
   [:call, [:lit, 10], :times],
   nil,
   [:block,
    [:dasgn_curr, :bar],
    [:newline, 1, "(eval)", [:lasgn, :bar, [:lit, 1]]]]]],
 [:newline, 1, "(eval)", [:vcall, :bar, 0]]]

so the :lvar on the last line becomes :vcall

Class @subclasses is not a WeakRef

Since @subclasses stores the list of classes that are inherited, the class definition will not be garbage collected due to being referenced in this list.

can't install rubinius

running sudo rake install i get:
install -c -m 0644 vm/subtend/ruby.h /usr/local/lib/rubinius/0.11/lib/ext/ruby.h
rake aborted!
No such file or directory - vm/subtend/ruby.h
/work/research/rubinius/Rakefile:130

Const Assignment gives unexpected behaviour

Assigning to already defined constants gives unexpected behaviour or even segmentation faults. I have built from latest git. Examples:

String = nil
puts "foo"
=> Segmentation Fault

String = nil
class String; end
=> Segmentation Fault

Array = nil
puts "foo"
=> (Nothing gets printed)

Array = nil
class Array; end
=> (Nothing happens)

Fixnum = nil
puts 42
=> 42

Fixnum = nil
class Fixnum; end
=> Fixnum is not a class (TypeError) with backtrace: Exception occurred during top-level exception output! (THIS IS BAD)

In all of this, Fixnum seems to behave most correctly. I haven't tried any other constants.

Add a handler for SIGPIPE

Reported by Wilson LH 419

At the time, SIGPIPE would cause rbx to exit. There is currently a handler registered that ignores SIGPIPE. Do we need a handler that raises EPIPE?

OS X 10.5.{6,7} GCC 4.2.1 Non-debug Build Fails

Apparently the -O2 flag causes some type of a problem; -O1 etc. work fine, as does rake build:debug (-O0). Using GCC=gcc-4.0 on the same system works without problems.

This appears to be specifically related to the compiler. This is the end of the build output, same error occurs e.g. trying to run bin/mspec.

Compiling lib/sexp_processor.rb
cp kernel/bootstrap/load_order.txt runtime/bootstrap/load_order.txt
cp kernel/platform/load_order.txt runtime/platform/load_order.txt
cp kernel/common/load_order.txt runtime/common/load_order.txt
cp kernel/delta/load_order.txt runtime/delta/load_order.txt
cp kernel/compiler/load_order.txt runtime/compiler/load_order.txt
Building extension lib/ext/readline
./bin/rbx compile -p -I/Users/ruerue/code/rubinius/master/vm/capi -C,-pipe -C,-Wall -C,-DBASE_PATH="/Users/ruerue/code/rubinius/master" -C,-DRBA_PATH="/Users/ruerue/code/rubinius/master/runtime" lib/ext/readline
Compilation error detected: No method 'unshift' on an instance of NilClass.
near (unknown):0

Kernel(NilClass)#unshift (method_missing) at kernel/delta/kernel.rb:47
Compiler::Node::Arguments#consume {} at kernel/compiler/nodes.rb:130
Array(Sexp)#each at kernel/bootstrap/array_186.rb:9
Compiler::Node::Arguments#consume at kernel/compiler/nodes.rb:120
Compiler::Node::Arguments.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Define)#convert at kernel/compiler/node.rb:116
Compiler::Node::ClosedScope(Compiler::Node::Define)#consume {} at kernel/compiler/nodes.rb:586
Compiler#set at kernel/compiler/compiler.rb:282
Compiler::Node(Compiler::Node::Define)#set at kernel/compiler/node.rb:145
Compiler::Node::ClosedScope(Compiler::Node::Define)#consume at kernel/compiler/nodes.rb:585
Compiler::Node::Define#consume {} at kernel/compiler/nodes.rb:821
Compiler#set at kernel/compiler/compiler.rb:282
Compiler::Node(Compiler::Node::Define)#set at kernel/compiler/node.rb:145
Compiler::Node::Define#consume at kernel/compiler/nodes.rb:820
Compiler::Node::Define.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Block)#consume {} at kernel/compiler/node.rb:127
Array(Sexp)#each at kernel/bootstrap/array_186.rb:9
Compiler::Node(Compiler::Node::Block)#consume at kernel/compiler/node.rb:125
Compiler::Node::Block.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Scope)#convert at kernel/compiler/node.rb:116
Compiler::Node::Scope#consume at kernel/compiler/nodes.rb:2373
Compiler::Node::Scope.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Class)#convert at kernel/compiler/node.rb:116
Compiler::Node::ClosedScope(Compiler::Node::Class)#consume {} at kernel/compiler/nodes.rb:586
Compiler#set at kernel/compiler/compiler.rb:282
Compiler::Node(Compiler::Node::Class)#set at kernel/compiler/node.rb:145
Compiler::Node::ClosedScope(Compiler::Node::Class)#consume at kernel/compiler/nodes.rb:585
Compiler::Node::Class#consume {} at kernel/compiler/nodes.rb:530
Compiler#set at kernel/compiler/compiler.rb:282
Compiler::Node(Compiler::Node::Class)#set at kernel/compiler/node.rb:145
Compiler::Node::Class#consume at kernel/compiler/nodes.rb:529
Compiler::Node::Class.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Block)#consume {} at kernel/compiler/node.rb:127
Array(Sexp)#each at kernel/bootstrap/array_186.rb:9
Compiler::Node(Compiler::Node::Block)#consume at kernel/compiler/node.rb:125
Compiler::Node::Block.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler::Node(Compiler::Node::Script)#convert at kernel/compiler/node.rb:116
Compiler::Node::ClosedScope(Compiler::Node::Script)#consume {} at kernel/compiler/nodes.rb:586
Compiler#set at kernel/compiler/compiler.rb:282
Compiler::Node(Compiler::Node::Script)#set at kernel/compiler/node.rb:145
Compiler::Node::ClosedScope(Compiler::Node::Script)#consume at kernel/compiler/nodes.rb:585
Compiler::Node::Script.create at kernel/compiler/node.rb:84
Compiler#convert_sexp at kernel/compiler/compiler.rb:258
Compiler#into_script at kernel/compiler/compiler.rb:263
Compiler.compile_file at kernel/compiler/compiler.rb:55
Compiler::Utils.compile_file at kernel/compiler/compile.rb:36
Compiler::Utils.single_load {} at kernel/compiler/compile.rb:199
Compiler::Utils.compile_feature at kernel/compiler/compile.rb:142
Compiler::Utils.single_load at kernel/compiler/compile.rb:198
Compiler::Utils.unified_load at kernel/compiler/compile.rb:89
Kernel(Object)#load at kernel/common/kernel.rb:667
Object#script at kernel/loader.rb:268
rake aborted!
Command failed with status (1): [./bin/rbx compile -p -I/Users/ruerue/code...]

(See full trace by running task with --trace)
02:06:27 @paws /code/rubinius/master:master > uname -a
Darwin paws.local 9.7.0 Darwin Kernel Version 9.7.0: Tue Mar 31 22:52:17 PDT 2009; root:xnu-1228.12.14
1/RELEASE_I386 i386 i386
02:08:49 @paws /code/rubinius/master:master > gcc -v
Using built-in specs.
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc_42/gcc_42-5566
1/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/usr/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin9 --with-gxx-include-dir=/usr/include/c++/4.0.0 --host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5566)
02:08:55 @paws ~/code/rubinius/master:master >

regexp should consider $KCODE

Reported by pluskid LH 310

The second optional argument of Regexp.new can be used to indicate the language/encoding.

The default behavior:

re = Regexp.new(".")
str = "中文" # or "\344\270\255\346\226\207" in utf-8 encoding
re.match(str)[0] # => "\344"

When specifying the language/encoding:

re = Regexp.new(".", nil, 'u')
str = "中文" # or "\344\270\255\346\226\207" in utf-8 encoding
re.match(str)[0] # => "\344\270\255"

However, there's a global variable $KCODE that indicate the current language/encoding. When set, the regexp should behavior according to this, thus:

$KCODE = 'u'
re = Regexp.new(".")
str = "中文" # or "\344\270\255\346\226\207" in utf-8 encoding
re.match(str)[0] # => "中" or  "\344\270\255" in utf-8 encoding

Those are Ruby 1.8 behavior. Since Ruby 1.9 gains full Unicode support, the global variable $KCODE is no longer used. I think Rubinius is currently making capability mainly to Ruby 1.8, so this should be considered.

One way to fix this, I think, is to change the default value for the second optional argument (lang) of Regexp.new from "nil" to "$KCODE".

I don't know whether Rubinius and Ruby1.8 use the same regexp engine. But it seems that even though I set $KCODE to 'u' in Ruby1.8. The code

Regexp.new(".").inspect

will return "/./" but

Regexp.new(".", nil, "u").inspect

returns "/./u" . However, the "/./" can successfully match a multi-byte character when setting $KCODE to 'u', but fails in Rubinius. So I think maybe some better way is to patch the regexp engine to take care of the global variable instead of patch the Regexp.new method.

can't install rjb gem

i tried installing the rjb gem without installing rubinius (that is, running rbx directly after 'rake'. i didn't install since that did not succeed, see another issue)

bin/rbx gem install rjb-1.1.6.gem --no-rdoc --no-ri
Building native extensions. This could take a while...
ERROR: Error installing rjb-1.1.6.gem:
ERROR: Failed to build gem native extension.

/work/research/rubinius/bin/rbx extconf.rb
checking for jni.h... yes
checking for dl.h... no
checking for ruby/dl.h... no
*** extconf.rb failed ***

build fails: invalid conversion from 'const char*' to 'char*'

building the actual version (last pull 5min ago, but also some pulls before) fails with:

    vm/parser/grammar.y: In function 'long unsigned int rubinius::parser::scan_hex(const char*, int, int*)':
    vm/parser/grammar.y:5839: error: invalid conversion from 'const char*' to 'char*'
    rake aborted!

Problem defining or finding methods on a metaclass

LH 614 reported by Sam Aaron

Run this code: http://gist.github.com/204542

ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
A.cheese: edam
B.cheese: stilton
a.cheese: shropshire blue
b.cheese: cheddar
b_with_meta.cheese: cheshire
b_with_meta.metaclass.cheese: stilton
b_with_meta_meta.cheese: brie
b_with_meta_meta.metaclass.cheese: gouda
b_with_meta_meta.metaclass.metaclass.cheese: wensleydale
gauss:rubinius brian$ bin/rbx -v meta.rb
rubinius 0.13.0-dev (1.8.7 d300514e 2009-11-06 JI) [i686-apple-darwin9.8.0]
A.cheese: edam
B.cheese: stilton
a.cheese: shropshire blue
b.cheese: cheddar
b_with_meta.cheese: cheshire
An exception occurred running meta.rb
    No method 'cheese' on #> (MetaClass) (NoMethodError)

Backtrace:
  Kernel(MetaClass)#cheese (method_missing) at kernel/delta/kernel.rb:45
                       main.__script__ at meta.rb:57
    Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:221
           Compiler::Utils.single_load at kernel/compiler/compile.rb:244
   Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:330
               Rubinius::Loader#script at kernel/loader.rb:327
                 Rubinius::Loader#main at kernel/loader.rb:406
                     Object#__script__ at kernel/loader.rb:454

rbx accepts -vvvvv as a valid switch

Prints the version multiple times:

rubinius (master*) $ bin/rbx -vvv
rubinius 0.13.0-dev (1.8.7 5827f8d5 2009-11-06) [x86_64-apple-darwin10.0.0]
rubinius 0.13.0-dev (1.8.7 5827f8d5 2009-11-06) [x86_64-apple-darwin10.0.0]
rubinius 0.13.0-dev (1.8.7 5827f8d5 2009-11-06) [x86_64-apple-darwin10.0.0]
rubinius (master*) $ 

require "drb/unix" fails with an unbalanced stack error

ERROR in temp_server, 0
An exception occurred evaluating command line code
unbalanced stack at line 81 (151): 1 != 2 (RuntimeError)

Backtrace:
Compiler::StackDepthCalculator#run_from at kernel/compiler/stack.rb:48 (2 times)
Compiler::StackDepthCalculator#run at kernel/compiler/stack.rb:13
    Compiler::Generator#to_cmethod at kernel/compiler/generator.rb:185
Compiler::MethodDescription#to_cmethod at kernel/compiler/bytecode.rb:34
Compiler::Generator#encode_literals {} at kernel/compiler/generator.rb:142
                        Array#each at kernel/bootstrap/array.rb:152
Compiler::Generator#encode_literals at kernel/compiler/generator.rb:140
    Compiler::Generator#to_cmethod at kernel/compiler/generator.rb:193
Compiler::MethodDescription#to_cmethod at kernel/compiler/bytecode.rb:34
Compiler::Generator#encode_literals {} at kernel/compiler/generator.rb:142
                        Array#each at kernel/bootstrap/array.rb:152
Compiler::Generator#encode_literals at kernel/compiler/generator.rb:140
    Compiler::Generator#to_cmethod at kernel/compiler/generator.rb:193
Compiler::MethodDescription#to_cmethod at kernel/compiler/bytecode.rb:34
Compiler::Generator#encode_literals {} at kernel/compiler/generator.rb:142
                        Array#each at kernel/bootstrap/array.rb:152
Compiler::Generator#encode_literals at kernel/compiler/generator.rb:140
    Compiler::Generator#to_cmethod at kernel/compiler/generator.rb:193
Compiler::MethodDescription#to_cmethod at kernel/compiler/bytecode.rb:34
             Compiler.compile_file at kernel/compiler/compiler.rb:56
      Compiler::Utils.compile_file at kernel/compiler/compile.rb:36
    Compiler::Utils.single_load {} at kernel/compiler/compile.rb:199
   Compiler::Utils.compile_feature at kernel/compiler/compile.rb:142
       Compiler::Utils.single_load at kernel/compiler/compile.rb:198
   Compiler::Utils.unified_load {} at kernel/compiler/compile.rb:131
                        Array#each at kernel/bootstrap/array.rb:152
      Compiler::Utils.unified_load at kernel/compiler/compile.rb:95
            Kernel(Object)#require at kernel/common/kernel.rb:711
                   Object#__eval__ at (eval):1
     Kernel(Rubinius::Loader)#eval at kernel/common/eval.rb:85
         Rubinius::Loader#evals {} at kernel/loader.rb:304
                        Array#each at kernel/bootstrap/array.rb:152
            Rubinius::Loader#evals at kernel/loader.rb:303
             Rubinius::Loader#main at kernel/loader.rb:403
                 Object#__script__ at kernel/loader.rb:452

Rubinius allows method to be bound where MRI does not

Reported by wycats as Lighthouse issue 781.

module Annotations
  def self.extend(klass)
    klass.class_eval { include Annotation }
  end
  
  def annotate(module_name, &block)    
    new_module = Module.new do
      @@execute_method = Annotations.const_get(module_name).method(:execute)
      
      def self.method_added(name)
        original_method = instance_method(name)
        remove_method(name)
        
        method_module = Module.new do
          define_method(name, original_method)
        end
        
        execute_module = Module.new do
          define_method(name, @@execute_method)
        end
        
        include method_module
        include execute_module
      end
    end
    
    new_module.module_eval(&block)
    
    include new_module
  end
end

module Annotations
  module Logging
    def self.execute(*args, &block)
      puts "ARGS: #{args}"
      super
    end
  end
end

class Foo
  extend Annotations
  
  annotate :Logging do
    def hello
      puts "HELLO"
    end
  end
end

puts Foo.new.hello

Result in MRI:

annotations.rb:52:in `hello': singleton method bound for a different object (TypeError)
    from annotations.rb:52

Result in Rubinius

ARGS: 
An exception occurred running annotations.rb
    No method 'execute' on Annotations::Logging (Module) (NoMethodError)

Backtrace:
  Kernel(Module)#execute (method_missing) at kernel/delta/kernel.rb:45
          Annotations::Logging.execute at annotations.rb:37
                           Method#call at kernel/common/method.rb:70
        Rubinius::DelegatedMethod#call at kernel/common/delegated_method.rb:17
                       main.__script__ at annotations.rb:52
    Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:216
           Compiler::Utils.single_load at kernel/compiler/compile.rb:244
   Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:329
               Rubinius::Loader#script at kernel/loader.rb:326
                 Rubinius::Loader#main at kernel/loader.rb:406
                     Object#__script__ at kernel/loader.rb:454

Unknown VM -X Options Silently Ignored

The -X option parser in vm/configuration should warn or raise an error if encountering an option it does not understand rather than just ignoring it.

Event objects

Reported by Tony Arcieri LH 536

Multiplexing different types of events on Channels is presently pretty difficult, to the point that IO#select cannot be implemented.

Evan threw out the idea of event objects. These could hopefully store any data resulting from I/O completions, the source of the I/O event, or completely non-I/O related things as not all events are I/O related, such as timeout events.

Event objects could abstract interaction with scheduler directly, e.g.:

te = TimeoutEvent.perform chan, 5.0, value
re = ReadEvent.perform chan, io, 4096, value

(where value is an optional user-specified parameter)

when the event occurs, a corresponding Event object is written to the channel, which would include the event type through the nature of its class, and also provide accessors for the event source, any data that may have resulted from the event (e.g. data read from an IO object), and the user value, if it was specified.

This would make for easy case-based processing of IO events, e.g.:

ev = chan.receive
case ev
when ReadEvent then read_handler(ev)
when WriteEvent then write_handler(ev)
when TimeoutEvent then timeout_handler(ev)
...
end

Default method argument causes bytecode order to be incorrect

Reported in LH 293, code snippit from Wilson

## FAILS
def chaos(x = nil)
  puts (0...5).first
end
chaos

## WORKS
def chaos
  puts (0...5).first
end
chaos

The failing code in ticket.rb:

gauss:rubinius brian$ bin/rbx -v ticket.rb
rubinius 0.13.0-dev (1.8.7 f8ed1f04 2009-11-06 JI) [i686-apple-darwin9.8.0]
0...5
An exception occurred running ticket.rb
    No method 'first' on an instance of NilClass. (NoMethodError)

Backtrace:
  Kernel(NilClass)#first (method_missing) at kernel/delta/kernel.rb:47
                          Object#chaos at ticket.rb:2
                       main.__script__ at ticket.rb:4
    Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:221
           Compiler::Utils.single_load at kernel/compiler/compile.rb:244
   Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:330
               Rubinius::Loader#script at kernel/loader.rb:327
                 Rubinius::Loader#main at kernel/loader.rb:406
                     Object#__script__ at kernel/loader.rb:454

The bytecode is clearly being emitted in the wrong order (but it could be a parse issue):

=============== :chaos ===============
object_id: 0x9e
total args: 1 required: 0
stack size: 6, local count: 1
lines: #

0000:  passed_arg                 0
0002:  goto_if_true               8
0004:  push_nil                   
0005:  set_local                  0    # x
0007:  pop                        
0008:  push_self                  
0009:  push_cpath_top             
0010:  find_const                 :Range
0012:  meta_push_0                
0013:  push_int                   5
0015:  push_true                  
0016:  send_stack                 :new, 3
0019:  allow_private              
0020:  send_stack                 :puts, 1
0023:  send_method                :first
0025:  ret                        
--------------------------------------

vs

=============== :chaos ===============
object_id: 0x7a
total args: 0 required: 0
stack size: 5, local count: 0
lines: #

0000:  push_self                  
0001:  push_cpath_top             
0002:  find_const                 :Range
0004:  meta_push_0                
0005:  push_int                   5
0007:  push_true                  
0008:  send_stack                 :new, 3
0011:  send_method                :first
0013:  allow_private              
0014:  send_stack                 :puts, 1
0017:  ret                        
--------------------------------------

Incorrect Process.setrlimit spec on (some?) Linux

Reported by Wilson LH 378

The Process.setrlimit spec for RLIMIT_MEMLOCK needs revision on Linux.
It appears to fail because the lim/max return values are not necessarily valid arguments to setrlimit.
While this is retarded, it is real, and needs some work.

I am currently installing Ubuntu so that I can debug this mess.

Process.setrlimit and Process.getrlimit limit and get total size for mlock(2) (bytes) ERROR
Invalid argument: 
                   Errno.handle at kernel/core/errno.rb:19
              Process.setrlimit at kernel/core/process.rb:35
           Object#__script__ {} at ./spec/ruby/1.8/core/process/setrlimit_spec.rb:73

Invalid block local access causes segfault

A segfault results if the VM encounters a (set|push)_local_depth when the scope nesting does not match the depth given.

For example:

class Hash
  def self.allocate
    hash = super()
    Rubinius.privately { hash.setup }
    hash
  end
end

If the compiler does not fix up the local access for hash in hash.setup in Rubinius.privately, the push_local_depth insn will attempt call_frame->scope->parent() and parent is 0x0.

fresh build of rubinius-0.12-20091006, rake returns 1 spec failed

OS X, 10.6

$ tar xf rubinius-0.12-20091006.tar
$ cd rubinius-0.12/
$ ./configure --update-prebuilt
$ ./configure --enable-llvm
$ rake
....... Lots of spam .......
1)
Time.at converts to time object FAILED
Expected "Mon Jul 09 20:38:44 -0400 2007"
 to equal ""

```
                                    /expectations.rb:15
  #.__script__ {} at spec/frozen/core/time/at_spec.rb:8
     Kernel(Object)#instance_eval at kernel/common/eval.rb:119
        Enumerable(Array)#all? {} at kernel/common/enumerable.rb:257
                       Array#each at kernel/bootstrap/array.rb:151
           Enumerable(Array)#all? at kernel/common/enumerable.rb:257
                       Array#each at kernel/bootstrap/array.rb:151
                  main.__script__ at spec/frozen/core/time/at_spec.rb:4
```

   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:221
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
         Compiler::Utils.unified_load at kernel/compiler/compile.rb:89
                          Kernel.load at kernel/common/kernel.rb:688
         Kernel(Object)#instance_eval at kernel/common/eval.rb:119
                           Array#each at kernel/bootstrap/array.rb:151
   Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:221
          Compiler::Utils.single_load at kernel/compiler/compile.rb:244
  Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:330
              Rubinius::Loader#script at kernel/loader.rb:326
                Rubinius::Loader#main at kernel/loader.rb:405
                    Object#**script** at kernel/loader.rb:453

Finished in 219.385444 seconds

3000 files, 11782 examples, 35770 expectations, 1 failure, 0 errors

Segfault in bin/mspec ci with jit enabled

http://gist.github.com/152277

The two files in the above gist demonstrate the segfaults that occur executing bin/mspec ci -T-Xjit.enabled with DEV=1 and without DEV=1 set. Note that the segfault without DEV=1 occurs consistantly much sooner then the segfault when running with DEV=1.

This was observed on a 32bit Ubuntu 9.04 box (gcc 4.3.3)

assertion failure in commit 6536694b26a0021726e3785d5b245d7a8503f559

Running a simple ruby script that reads a file, parses through it, and generates a new file (same name) caused the latest commit to produce an assertion failure. I have a tarball of the script along with the sample file that caused it. I'll try to attach them here somehow... otherwise a followup message will contain pointers to gists containing the data.

Compilation issues on x86_64

When trying to compile on my Linux box (Ubuntu 9.04 x86_64, GCC 4.3.3), I get the following errors:

vm/builtin/object.cpp: In member function ‘rubinius::hashval rubinius::Object::hash(rubinius::VM*)’:
vm/builtin/object.cpp:237: error: cast from ‘rubinius::Object*’ to ‘uint32_t’ loses precision

cc1plus: warnings being treated as errors
vm/builtin/string.cpp: In function ‘unsigned int rubinius::finish_hash(unsigned int)’:
vm/builtin/string.cpp:140: error: right shift count >= width of type

Ad-hoc patches:

diff --git i/vm/builtin/object.cpp w/vm/builtin/object.cpp
index f5927cf..11d3e56 100644
--- i/vm/builtin/object.cpp
+++ w/vm/builtin/object.cpp
@@ -234,7 +234,7 @@ namespace rubinius {
   hashval Object::hash(STATE) {
     if(!reference_p()) {
       // See http://burtleburtle.net/bob/hash/integer.html
-      uint32_t a = (uint32_t)this;
+      uint32_t a = (uint32_t)(unsigned long)this;
       a = (a+0x7ed55d16) + (a<<12);
       a = (a^0xc761c23c) ^ (a>>19);
       a = (a+0x165667b1) + (a<<5);

diff --git i/vm/builtin/string.cpp w/vm/builtin/string.cpp
index 570044e..b1f32cc 100644
--- i/vm/builtin/string.cpp
+++ w/vm/builtin/string.cpp
@@ -137,7 +137,7 @@ namespace rubinius {
   }

   static inline unsigned int finish_hash(unsigned int hv) {
-    return (hv>>FIXNUM_WIDTH) ^ (hv & FIXNUM_MAX);
+    return (hv >> (FIXNUM_WIDTH < sizeof(hv) * 8) ? FIXNUM_WIDTH : 0) ^ (hv & F
   }

   hashval String::hash_str(const char *bp) {

Not correctly distinguishing vcall in IRB

LH 717 reported by Charles L

gauss:rubinius brian$ bin/rbx 
irb(main):001:0> a = 1; a()
=> 1
irb(main):002:0> b = 1
=> 1
irb(main):003:0> b()
=> 1
irb(main):004:0>
gauss:rubinius brian$ irb
>> a = 1; a()
NoMethodError: undefined method `a' for main:Object
        from (irb):1
>> b = 1
=> 1
>> b()
NoMethodError: undefined method `b' for main:Object
        from (irb):3
>>

Evan's comment:

I investigated this a bit more today. The fix is to, when vcall is normalized, remember that it was a vcall in some way.

That way, we can only check for a local variable override where a vcall was used. This is tricky right now, because adding things to the sexp form blows up the compiler, since it's using .last for a number of things related to inspecting a call sexp (and expecting an s(:arglist...))

I tried to add a @Style instance variable to the sexp, but it never makes it all the way through the pipeline, I'm assuming due to the sexp being pulled apart and rebuilt, which looses the ivars.

hang when running specs with JIT enabled on OSX 10.5.8 Intel

commit 8fbdff1
Darwin charles-remess-mac-pro.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386

bin/mspec ci --format specdoc -T -XJ

Hangs on spec:

ObjectSpace.define_finalizer

  • raises an ArgumentError if the action does not respond to call - accepts an object and a proc - accepts an object and a callable - doesn't call self-referencing finalizers <<---- hangs here

Attaching to the hung vm process (spinning at 100%) gives the following backtrace (gist http://gist.github.com/203222)

Send patch to get libxml-ruby gem to build

The libxml-ruby gem builds under the rbx C-API except for this error. Send a patch to not use st_foreach:

  case T_HASH:
    st_foreach(RHASH_TBL(nslist), iterate_ns_hash, self);
    break;
 
ruby_xml_xpath_context.c: In function ‘rxml_xpath_context_register_namespaces’:
ruby_xml_xpath_context.c:223: warning: implicit declaration of function ‘assert’
ruby_xml_xpath_context.c:223: error: syntax error before ‘?’ token
ruby_xml_xpath_context.c:223: error: syntax error before ‘)’ token

spec "Process.fork - return nil for child process" is hanging

After a clean build from rake, the normal ci spec run hangs at the above spec. While it is hung, if I do a ps -a | grep rbx, there are 3 entries, one of which is marked . Using gdb to connect to one of the pid's shows a backtrace like so:


(gdb) bt
#0  0xb80b5430 in __kernel_vsyscall ()
#1  0xb7e762cb in waitpid () from /lib/tls/i686/cmov/libc.so.6
#2  0x081085f9 in rubinius::System::vm_wait_pid (state=0x98630e8, pid_obj=0xebc7, no_hang=0xa) at vm/builtin/system.cpp:122
#3  0x080c1a41 in rubinius::Primitives::vm_wait_pid (state=0x98630e8, call_frame=0xbf8c9948, msg=@0x9a33c40, args=@0xbf8c97c8) at vm/gen/primitives_glue.gen.cpp:14264
#4  0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x9a33840, call_frame=0xbf8c9948, args=@0xbf8c9bc8) at vm/gen/instructions.cpp:759
#5  0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x9a33840, call_frame=0xbf8c9948, args=@0xbf8c9bc8) at vm/vmmethod.cpp:661
#6  0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c9ce4, msg=@0xad74d70, args=@0xbf8c9bc8) at vm/vmmethod.cpp:481
#7  0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xad74b78, call_frame=0xbf8c9ce4, args=@0xbf8c9fc8) at vm/gen/instructions.cpp:759
#8  0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xad74b78, call_frame=0xbf8c9ce4, args=@0xbf8c9fc8) at vm/vmmethod.cpp:661
#9  0x0811338e in rubinius::BlockEnvironment::execute_interpreter (state=0x98630e8, previous=0xbf8ca178, env=0xb7831738, args=@0xbf8c9fc8, invocation=@0xbf8c9e90) at vm/builtin/block_environment.cpp:87
#10 0x0811305c in rubinius::BlockEnvironment::call_under (this=0xb7831738, state=0x98630e8, exec=0xb765f330, call_frame=0xbf8ca178, msg=@0x999dac8, args=@0xbf8c9fc8) at vm/builtin/block_environment.cpp:141
#11 0x080d54dc in rubinius::Primitives::block_call_under (state=0x98630e8, call_frame=0xbf8ca178, msg=@0xbf8c9648, args=@0xbf8c9fc8) at vm/gen/primitives_glue.gen.cpp:2016
#12 0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x999d2d0, call_frame=0xbf8ca178, args=@0xbf8ca3f8) at vm/gen/instructions.cpp:759
#13 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x999d2d0, call_frame=0xbf8ca178, args=@0xbf8ca3f8) at vm/vmmethod.cpp:661
#14 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8ca534, msg=@0xa05c6f8, args=@0xbf8ca3f8) at vm/vmmethod.cpp:481
#15 0x0815b504 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05c360, call_frame=0xbf8ca534, args=@0xbf8ca7a8) at vm/gen/instructions.cpp:786
#16 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05c360, call_frame=0xbf8ca534, args=@0xbf8ca7a8) at vm/vmmethod.cpp:661
#17 0x080909bb in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8ca8c4, msg=@0xa05dbc0, args=@0xbf8ca7a8) at vm/vmmethod.cpp:481
#18 0x0815b504 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05dad0, call_frame=0xbf8ca8c4, args=@0xbf8cab68) at vm/gen/instructions.cpp:786
#19 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05dad0, call_frame=0xbf8ca8c4, args=@0xbf8cab68) at vm/vmmethod.cpp:661
#20 0x0811338e in rubinius::BlockEnvironment::execute_interpreter (state=0x98630e8, previous=0xbf8cac74, env=0xb7835c94, args=@0xbf8cab68, invocation=@0xbf8caa68) at vm/builtin/block_environment.cpp:87
#21 0x08112eb4 in rubinius::BlockEnvironment::call (this=0xb7835c94, state=0x98630e8, call_frame=0xbf8cac74, args=@0xbf8cab68, flags=0) at vm/builtin/block_environment.cpp:100
#22 0x08164d72 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05dbe0, call_frame=0xbf8cac74, args=@0xbf8caf18) at vm/gen/instructions.cpp:970
#23 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05dbe0, call_frame=0xbf8cac74, args=@0xbf8caf18) at vm/vmmethod.cpp:661
#24 0x0811338e in rubinius::BlockEnvironment::execute_interpreter (state=0x98630e8, previous=0xbf8cb024, env=0xb7835ce4, args=@0xbf8caf18, invocation=@0xbf8cae18) at vm/builtin/block_environment.cpp:87
#25 0x08112eb4 in rubinius::BlockEnvironment::call (this=0xb7835ce4, state=0x98630e8, call_frame=0xbf8cb024, args=@0xbf8caf18, flags=0) at vm/builtin/block_environment.cpp:100
... etc

connecting to the other (non defunkt) process gives the following backtrace:


(gdb) bt
#0  0xb80b5430 in __kernel_vsyscall () 
#1  0xb7dc9cf9 in __lll_lock_wait () from /lib/tls/i686/cmov/libpthread.so.0
#2  0xb7dc5138 in _L_lock_289 () from /lib/tls/i686/cmov/libpthread.so.0
#3  0xb7dc4b76 in pthread_mutex_lock () from /lib/tls/i686/cmov/libpthread.so.0
#4  0xb7eca4b6 in pthread_mutex_lock () from /lib/tls/i686/cmov/libc.so.6
#5  0x0808dab1 in thread::Mutex::lock (this=0x98626f0) at vm/util/thread.hpp:298
#6  0x0810f5fb in rubinius::NativeFunction::call (this=0xb74643b0, state=0x98630e8, args=@0xbf8c8838) at vm/builtin/nativefunction.cpp:512
#7  0x0810f7fb in rubinius::NativeFunction::execute (state=0x98630e8, call_frame=0xbf8c89b8, msg=@0x99a67f8, args=@0xbf8c8838) at vm/builtin/nativefunction.cpp:56
#8  0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x99a6258, call_frame=0xbf8c89b8, args=@0xbf8c8c38) at vm/gen/instructions.cpp:759
#9  0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x99a6258, call_frame=0xbf8c89b8, args=@0xbf8c8c38) at vm/vmmethod.cpp:661
#10 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c8d98, msg=@0x99a6c20, args=@0xbf8c8c38) at vm/vmmethod.cpp:481
#11 0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x99a6a98, call_frame=0xbf8c8d98, args=@0xbf8c9018) at vm/gen/instructions.cpp:759
#12 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x99a6a98, call_frame=0xbf8c8d98, args=@0xbf8c9018) at vm/vmmethod.cpp:661
#13 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c9198, msg=@0x99b3010, args=@0xbf8c9018) at vm/vmmethod.cpp:481
#14 0x0815bb74 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x99b2d48, call_frame=0xbf8c9198, args=@0xbf8c9418) at vm/gen/instructions.cpp:851
#15 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x99b2d48, call_frame=0xbf8c9198, args=@0xbf8c9418) at vm/vmmethod.cpp:661
#16 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c9554, msg=@0x9896008, args=@0xbf8c9418) at vm/vmmethod.cpp:481
#17 0x0815aeda in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x9895f38, call_frame=0xbf8c9554, args=@0xbf8c97c8) at vm/gen/instructions.cpp:823
#18 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x9895f38, call_frame=0xbf8c9554, args=@0xbf8c97c8) at vm/vmmethod.cpp:661
#19 0x08091431 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c9948, msg=@0x99b2c68, args=@0xbf8c97c8) at vm/vmmethod.cpp:481
#20 0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x99b2900, call_frame=0xbf8c9948, args=@0xbf8c9bc8) at vm/gen/instructions.cpp:759
#21 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x99b2900, call_frame=0xbf8c9948, args=@0xbf8c9bc8) at vm/vmmethod.cpp:661
#22 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8c9ce4, msg=@0xad74d30, args=@0xbf8c9bc8) at vm/vmmethod.cpp:481
#23 0x0815b504 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xad74b78, call_frame=0xbf8c9ce4, args=@0xbf8c9fc8) at vm/gen/instructions.cpp:786
#24 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xad74b78, call_frame=0xbf8c9ce4, args=@0xbf8c9fc8) at vm/vmmethod.cpp:661
#25 0x0811338e in rubinius::BlockEnvironment::execute_interpreter (state=0x98630e8, previous=0xbf8ca178, env=0xb7831738, args=@0xbf8c9fc8, invocation=@0xbf8c9e90) at vm/builtin/block_environment.cpp:87
#26 0x0811305c in rubinius::BlockEnvironment::call_under (this=0xb7831738, state=0x98630e8, exec=0xb765f330, call_frame=0xbf8ca178, msg=@0x999dac8, args=@0xbf8c9fc8) at vm/builtin/block_environment.cpp:141
#27 0x080d54dc in rubinius::Primitives::block_call_under (state=0x98630e8, call_frame=0xbf8ca178, msg=@0x80, args=@0xbf8c9fc8) at vm/gen/primitives_glue.gen.cpp:2016
#28 0x0815b414 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0x999d2d0, call_frame=0xbf8ca178, args=@0xbf8ca3f8) at vm/gen/instructions.cpp:759
#29 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0x999d2d0, call_frame=0xbf8ca178, args=@0xbf8ca3f8) at vm/vmmethod.cpp:661
#30 0x080910e1 in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8ca534, msg=@0xa05c6f8, args=@0xbf8ca3f8) at vm/vmmethod.cpp:481
#31 0x0815b504 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05c360, call_frame=0xbf8ca534, args=@0xbf8ca7a8) at vm/gen/instructions.cpp:786
#32 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05c360, call_frame=0xbf8ca534, args=@0xbf8ca7a8) at vm/vmmethod.cpp:661
#33 0x080909bb in rubinius::VMMethod::execute_specialized (state=0x98630e8, previous=0xbf8ca8c4, msg=@0xa05dbc0, args=@0xbf8ca7a8) at vm/vmmethod.cpp:481
#34 0x0815b504 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05dad0, call_frame=0xbf8ca8c4, args=@0xbf8cab68) at vm/gen/instructions.cpp:786
#35 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05dad0, call_frame=0xbf8ca8c4, args=@0xbf8cab68) at vm/vmmethod.cpp:661
#36 0x0811338e in rubinius::BlockEnvironment::execute_interpreter (state=0x98630e8, previous=0xbf8cac74, env=0xb7835c94, args=@0xbf8cab68, invocation=@0xbf8caa68) at vm/builtin/block_environment.cpp:87
#37 0x08112eb4 in rubinius::BlockEnvironment::call (this=0xb7835c94, state=0x98630e8, call_frame=0xbf8cac74, args=@0xbf8cab68, flags=0) at vm/builtin/block_environment.cpp:100
#38 0x08164d72 in rubinius::VMMethod::interpreter (state=0x98630e8, vmm=0xa05dbe0, call_frame=0xbf8cac74, args=@0xbf8caf18) at vm/gen/instructions.cpp:970
#39 0x0808ec78 in rubinius::VMMethod::run_interpreter (state=0x98630e8, vmm=0xa05dbe0, call_frame=0xbf8cac74, args=@0xbf8caf18) at vm/vmmethod.cpp:661
... etc

Currently this is always reproducable on my Ubuntu 32bit 9.04, gcc 4.3.3 box.

RDoc / RI failures during gem install

I'm seeing various failures during gem installation related to RI. They look like the following errors:

./bin/rbx -S gem install rdoc
Successfully installed rdoc-2.4.3
1 gem installed
Installing ri documentation for rdoc-2.4.3...
ERROR: While executing gem ... (NoMethodError)
No method 'keys' on an instance of RDoc::RI::MethodDescription.

Installing Rails also shows a similar error:

./bin/rbx -S gem install rails
Successfully installed rake-0.8.7
Successfully installed activesupport-2.3.2
Successfully installed activerecord-2.3.2
Successfully installed actionpack-2.3.2
Successfully installed actionmailer-2.3.2
Successfully installed activeresource-2.3.2
Successfully installed rails-2.3.2
7 gems installed
Installing ri documentation for rake-0.8.7...
Installing ri documentation for activesupport-2.3.2...
ERROR: While executing gem ... (NoMethodError)
No method 'keys' on an instance of RDoc::RI::MethodSummary.

Kernel and IncludedModule

Reported by Lin Jen-Shin LH 729

Greetings, I sent below to rubinius-dev mailing list but it didn't show up in google group, so I re-post them here.

Sorry if it's wrong place to post here.

I am not (yet) digging into source code,
and I guess IncludedModule was created
for separating each included module.
For example:
http://gist.github.com/30606 (first one or below)

module M
 def m
 end
end

module K
end

class C
 include K
end

module K
 include M
end

C.new.m # => undefined method

class D
 include K
end

D.new.m # => nil
C.new.m # => undefined method

Things are different in Kernel, because there's no
IncludedModule for Kernel in superclass_chain:
http://gist.github.com/30606 (last one or below)

module M
 def m
 end
end

module Kernel
 include M
end

class C
end

C.new.m # => undefined method

class D
 include Kernel
end

D.new.m # => nil
C.new.m # => nil in Rubinius
# undefined method in MRI 1.8/1.9 and JRuby

Should there be (an) IncludedModule(s) for Kernel?

Thanks and cheers,

$SAFE should be Proc local

Reported by kwatch LH 319

$SAFE is Proc local in Ruby but not in Rubinius.

hoge.rb:

puts   "*** before:  $SAFE=#{$SAFE.inspect}"
proc {
  $SAFE = 2
  puts "*** in proc: $SAFE=#{$SAFE}"
}.call
puts   "*** after:   $SAFE=#{$SAFE.inspect}"

result:

$ ruby hoge.rb
*** before:  $SAFE=0
*** in proc: $SAFE=2
*** after:   $SAFE=0     # not changed
$ shotgun/rubinius hoge.rb
*** before:  $SAFE=0
*** in proc: $SAFE=2
*** after:   $SAFE=2     # CHANGED!

environment:

$ ruby -v
ruby 1.8.6 (2007-09-24 patchlevel 111) [i686-darwin8.11.1]
$ shotgun/rubinius -v
rubinius 0.8.0 (ruby 1.8.6 compatible) (2ffa558ee) (02/08/2008) [i686-apple-darwin8.11.1]

can't run buildr

(Don't know if Rubinius is open for issues, but anyways)

Tried to use Rubinius (code from today) to run Buildr (a build tool based on Rake for Java). I get this:
An exception has occurred:
unknown marshal code: 1 (TypeError)

Backtrace:
Compiler::Utils.single_load {} at kernel/compiler/compile.rb:211
Compiler::Utils.compile_feature at kernel/compiler/compile.rb:142
Compiler::Utils.single_load at kernel/compiler/compile.rb:210
Compiler::Utils.unified_load {} at kernel/compiler/compile.rb:131
Array#each at kernel/bootstrap/array.rb:48
Compiler::Utils.unified_load at kernel/compiler/compile.rb:95
Kernel(Object)#gem_original_require (require) at kernel/common/kernel.rb:726
Kernel(Object)#require at lib/rubygems/custom_require.rb:31
main.script at /work/research/buildr/bin/buildr:18
Rubinius::CompiledMethod#activate_as_script at kernel/common/compiled_method.rb:150
Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:143
Compiler::Utils.single_load at kernel/compiler/compile.rb:239
Compiler::Utils.unified_load at kernel/compiler/compile.rb:89
Kernel(Object)#load at kernel/common/kernel.rb:677
main.script at /usr/bin/buildr:8
Rubinius::CompiledMethod#activate_as_script at kernel/common/compiled_method.rb:150
Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:143
Compiler::Utils.single_load at kernel/compiler/compile.rb:239
Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:323
Object#script at kernel/loader.rb:252

Use monotonic clock if possible (instead of gettimeofday)

Reported by zimbatm LH 279

Paraphrasing: "gettimeofday" is used in various places. This could possibly cause timing problems if the system date is changed between the uses.

(I don't know if this is an issue.)

Suggested fix:

I find that "get_clock" in libev's "ev.c" is a good implementation but it is not exported in "ev.h". It would be nice if libev would also export it's cross-platform timers independently.

Null dereference on 64-bit LLVM builds

As of now, on line 359 in vm/llvm/jit.cpp, ExecutionEngine::create() returns NULL. Then, on line 362, this null pointer is dereferenced, causing a segfault. As I know nothing about LLVM, I can't really say much more than this.

This is the segfault caused when compiling readline on my 64-bit Jaunty, GCC 4.3.3.

Class variables not created correctly in a def in a metaclass

Reported by agardiner LH 607

class Foo
  def self.map1  # Defs
    @@map1 ||= {}
  end

  class << self  # SClass
    def map2     # Defn
      @@map2 ||= {}
    end
  end

  # Initialise the cvars
  map1[:a] ||= {}   
  map2[:a] ||= {}
  
  # Now try and use them
  map1[:a][:b] = 1  # works fine
  map2[:a][:b] = 1  # raises NoMethodError []= on NilClass
end
gauss:rubinius brian$ bin/rbx ticket.rb
An exception occurred running ticket.rb
    No method '[]=' on an instance of NilClass. (NoMethodError)

Backtrace:
  Kernel(NilClass)#[]= (method_missing) at kernel/delta/kernel.rb:47
              Foo.__class_init__ (Foo) at ticket.rb:18
                       main.__script__ at ticket.rb:1
    Rubinius::CompiledMethod#as_script at kernel/common/compiled_method.rb:221
           Compiler::Utils.single_load at kernel/compiler/compile.rb:244
   Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:330
               Rubinius::Loader#script at kernel/loader.rb:327
                 Rubinius::Loader#main at kernel/loader.rb:406
                     Object#__script__ at kernel/loader.rb:454

TypeError in string interpolation (when #to_s does not return a String)

LH 765 by shugo.

Rubinius handles the following script differently from MRI. Is it intensional?

$ cat t.rb
x = Object.new
def x.to_s
  return 1
end
p "#{x}"
$ ruby-1_8_6 -v t.rb
ruby 1.8.6 (2008-08-08 patchlevel 286) [i686-linux]
"#<Object:0xb7dedbd8>"
$ rbx -v t.rb     
rubinius 0.11.0-dev (ruby 1.8.6) (eabf5ec7d 12/31/2009) [i686-pc-linux-gnu]
An exception has occurred:
      Tried to use non-reference value 0x3 as type String (48) (TypeError)

Backtrace:
            Compiler::Utils.single_load at kernel/compiler/compile.rb:245
    Compiler::Utils.load_from_extension at kernel/compiler/compile.rb:323
                      Object#__script__ at kernel/loader.rb:240

Seek error writing to sockets and pipes

Reported by agardiner LH 497

A seek error results on a socket when an attempt is made to write to a socket on which there is also data still to be read. On MatzRuby, no error occurs.

The exception on RBX is as follows:

    Unable to seek (ESPIPE)

Backtrace:
             IO(TCPSocket)#seek at kernel/core/io.rb:507
            IO(TCPSocket)#write at kernel/core/io.rb:490
          IO(TCPSocket)#puts {} at kernel/core/io.rb:371
                     Array#each at kernel/core/array.rb:573
             IO(TCPSocket)#puts at kernel/core/io.rb:355
              Object#__script__ at /home/ads/test_client.rb:10
       CompiledMethod#as_script at kernel/core/compiled_method.rb:326
            Compile.single_load at kernel/core/compile.rb:238
    Compile.load_from_extension at kernel/core/compile.rb:310
              Object#__script__ at kernel/loader.rb:201

The following server and client code can be used to reproduce the problem:

******* Server code *******

require 'socket'

REMOTE_DEBUG_PORT = 1098
TEST_DATA = "  Here
  is
  some
  multi-line
  data
"

port = ARGV.shift || REMOTE_DEBUG_PORT
server = TCPServer.open(port)

puts "*** waiting for client..."
socket = server.accept

puts "Sending data"
TEST_DATA.each_line {|l| socket.puts l}
socket.flush

resp = socket.gets
socket.close

******* Client code *******

require 'socket'

host = ARGV[0] || 'localhost'
port = ARGV[1] || 1098

socket = TCPSocket.new(host, port)
puts "Connected to server on #{host}:#{port}"
while line = socket.gets
  puts line
  socket.puts line
end
socket.close

rbx gem install mysql failed

When try to add mysql gem by issuing 'bin.rbx gem install mysql', the following error occurs:

checking for mysql_query() in -lmysqlclient... yes
checking for mysql_ssl_set()... yes
checking for mysql.h... no
checking for mysql/mysql.h... yes
creating Makefile

make
gcc -I. -I. -I/home/daddy/rubinius/rubinius/vm/capi -I. -DHAVE_MYSQL_SSL_SET -DHAVE_MYSQL_MYSQL_H -I/usr/local/include  -Wall -ggdb3 -O2  -c mysql.c
mysql.c:6:21: error: version.h: No such file or directory
mysql.c: In function 'mysql_raise':
mysql.c:165: warning: implicit declaration of function 'rb_exc_raise'
mysql.c: In function 'mysqlres2obj':
mysql.c:172: warning: passing argument 2 of 'memset' makes integer from pointer without a cast
mysql.c:177: warning: implicit declaration of function 'rb_gc'
mysql.c: In function 'make_field_obj':
mysql.c:189: warning: implicit declaration of function 'rb_str_freeze'
mysql.c:185: warning: unused variable 'hash'
mysql.c: In function 'init':
mysql.c:210: warning: passing argument 2 of 'memset' makes integer from pointer without a cast
mysql.c: In function 'real_connect':
mysql.c:243: warning: passing argument 2 of 'memset' makes integer from pointer without a cast
mysql.c: In function 'query':
mysql.c:719: warning: implicit declaration of function 'rb_ensure'
mysql.c: In function 'stmt_init':
mysql.c:854: warning: passing argument 2 of 'memset' makes integer from pointer without a cast
mysql.c: In function 'query_with_result_set':
mysql.c:882: warning: implicit declaration of function 'TypeError'
mysql.c: In function 'fetch_field_direct':
mysql.c:960: warning: implicit declaration of function 'Raise'
mysql.c: In function 'stmt_execute':
mysql.c:1337: warning: implicit declaration of function 'rb_big2ll'
mysql.c:1316: warning: unused variable 'false'
mysql.c: In function 'Init_mysql':
mysql.c:1814: warning: implicit declaration of function 'rb_define_global_const'
mysql.c:2571: error: 'E' undeclared (first use in this function)
mysql.c:2571: error: (Each undeclared identifier is reported only once
mysql.c:2571: error: for each function it appears in.)
mysql.c:2571: error: expected ')' at end of input
mysql.c:2571: error: expected declaration or statement at end of input
make: *** [mysql.o] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.