Skip to content

Commit a596063

Browse files
committed
Merge remote-tracking branch 'origin' into mcjit
2 parents d1a452c + cdc89a9 commit a596063

File tree

18 files changed

+183
-17
lines changed

18 files changed

+183
-17
lines changed

core/basic_object.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ def __id__
3939
end
4040

4141
def method_missing(meth, *args)
42-
::Kernel.raise ::NoMethodError, "Unable to send '#{meth}' on instance of BasicObject"
42+
error = ::NoMethodError
43+
.new("Unable to send '#{meth}' on instance of BasicObject", receiver: self)
44+
45+
::Kernel.raise(error)
4346
end
4447
private :method_missing
4548

core/exception.rb

+13-3
Original file line numberDiff line numberDiff line change
@@ -237,18 +237,28 @@ class LocalJumpError < StandardError
237237
class NameError < StandardError
238238
attr_reader :name
239239

240-
def initialize(*args)
240+
def initialize(*args, receiver: nil)
241241
super(args.shift)
242+
242243
@name = args.shift
244+
@receiver = receiver
245+
end
246+
247+
def receiver
248+
if @receiver
249+
@receiver
250+
else
251+
raise ArgumentError, 'no receiver is available'
252+
end
243253
end
244254
end
245255

246256
class NoMethodError < NameError
247257
attr_reader :name
248258
attr_reader :args
249259

250-
def initialize(*arguments)
251-
super(arguments.shift)
260+
def initialize(*arguments, **options)
261+
super(arguments.shift, **options)
252262
@name = arguments.shift
253263
@args = arguments.shift
254264
end

core/object_space.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ def self.find_object(query, callable)
66

77
def self._id2ref(id)
88
ary = []
9+
910
if find_object([:object_id, Integer(id)], ary) > 0
1011
return ary.first
1112
end
1213

13-
return nil
14+
raise RangeError, "#{id} is not a valid ID value"
1415
end
1516

1617
def self.find_references(obj)

core/string.rb

+8
Original file line numberDiff line numberDiff line change
@@ -2680,4 +2680,12 @@ def dump
26802680
str += ".force_encoding(\"#{encoding}\")" unless encoding.ascii_compatible?
26812681
s.replace(str)
26822682
end
2683+
2684+
def -@
2685+
frozen? ? self : dup.freeze
2686+
end
2687+
2688+
def +@
2689+
frozen? ? dup : self
2690+
end
26832691
end

core/zed.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@ def method_missing(meth, *args)
13671367
msg << " on an instance of #{object_class}."
13681368
end
13691369

1370-
Kernel.raise cls.new(msg, meth, args)
1370+
Kernel.raise(cls.new(msg, meth, args, receiver: self))
13711371
end
13721372

13731373
private :method_missing

gems_list.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ psych-2.0.17.gem
77
racc-1.4.14.gem
88
rake-10.5.0.gem
99
rb-readline-0.5.3.gem
10-
rdoc-4.2.1.gem
10+
rdoc-4.2.2.gem
1111
redcard-1.1.0.gem
1212
rubinius-ast-3.0.gem
1313
rubinius-bridge-1.1.0.gem
@@ -71,9 +71,9 @@ rubysl-net-smtp-2.0.1.gem
7171
rubysl-net-telnet-2.0.0.gem
7272
rubysl-nkf-2.0.1.gem
7373
rubysl-observer-2.0.0.gem
74-
rubysl-open-uri-2.0.0.gem
7574
rubysl-open3-2.0.0.gem
7675
rubysl-openssl-2.8.0.gem
76+
rubysl-open-uri-2.0.0.gem
7777
rubysl-optparse-2.0.1.gem
7878
rubysl-ostruct-2.1.0.gem
7979
rubysl-pathname-2.1.0.gem
@@ -95,7 +95,7 @@ rubysl-set-2.0.1.gem
9595
rubysl-shellwords-2.0.0.gem
9696
rubysl-singleton-2.0.0.gem
9797
rubysl-socket-2.1.1.gem
98-
rubysl-stringio-2.0.0.gem
98+
rubysl-stringio-2.1.0.gem
9999
rubysl-strscan-2.0.0.gem
100100
rubysl-sync-2.0.0.gem
101101
rubysl-syslog-2.1.0.gem

spec/ruby/core/exception/name_error_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,21 @@
1111
NameError.new("msg","name").name.should == "name"
1212
end
1313
end
14+
15+
describe 'NameError#receiver' do
16+
it 'returns the receiver if available' do
17+
x = 'foo'
18+
19+
begin
20+
x.foo
21+
rescue NameError => error
22+
error.receiver.should == x
23+
end
24+
end
25+
26+
it 'raises ArgumentError when no receiver is available' do
27+
error = NameError.new('msg', 'name')
28+
29+
proc { error.receiver }.should raise_error(ArgumentError)
30+
end
31+
end

spec/ruby/core/objectspace/_id2ref_spec.rb

+4
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818
r = ObjectSpace._id2ref(s.object_id)
1919
r.should == s
2020
end
21+
22+
it 'raises RangeError when an object could not be found' do
23+
proc { ObjectSpace._id2ref(1 << 60) }.should raise_error(RangeError)
24+
end
2125
end
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
require File.expand_path('../../../spec_helper', __FILE__)
2+
3+
describe 'String#-@' do
4+
it 'returns self if the String is frozen' do
5+
input = 'foo'.freeze
6+
output = -input
7+
8+
output.equal?(input).should == true
9+
output.frozen?.should == true
10+
end
11+
12+
it 'returns a frozen copy if the String is not frozen' do
13+
input = 'foo'
14+
output = -input
15+
16+
output.frozen?.should == true
17+
output.should == 'foo'
18+
end
19+
end
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
require File.expand_path('../../../spec_helper', __FILE__)
2+
3+
describe 'String#+@' do
4+
it 'returns an unfrozen copy of a frozen String' do
5+
input = 'foo'.freeze
6+
output = +input
7+
8+
output.frozen?.should == false
9+
output.should == 'foo'
10+
end
11+
12+
it 'returns self if the String is not frozen' do
13+
input = 'foo'
14+
output = +input
15+
16+
output.equal?(input).should == true
17+
end
18+
end

spec/ruby/language/send_spec.rb

+10-2
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,19 @@ def foobar; 200; end
193193
o.message.should == :not_there
194194
o.args.should == [1,2]
195195
end
196-
196+
197197
it "raises NameError if invoked as a vcall" do
198198
lambda { no_such_method }.should raise_error NameError
199199
end
200-
200+
201+
it 'adds the receiver to the raised exception' do
202+
begin
203+
no_such_method
204+
rescue NameError => error
205+
error.receiver.should == self
206+
end
207+
end
208+
201209
it "raises NoMethodError if invoked as an unambiguous method call" do
202210
lambda { no_such_method() }.should raise_error NoMethodError
203211
lambda { no_such_method(1,2,3) }.should raise_error NoMethodError

spec/ruby/optional/capi/ext/rubyspec.h

+1
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,7 @@
639639
#define HAVE_RB_TIME_INTERVAL 1
640640
#define HAVE_RB_TIME_TIMEVAL 1
641641
#define HAVE_RB_TIME_TIMESPEC 1
642+
#define HAVE_RB_TIME_TIMESPEC_NEW 1
642643
#endif
643644

644645
/* Util */

spec/ruby/optional/capi/ext/time_spec.c

+14
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ static VALUE time_spec_rb_time_timespec(VALUE self, VALUE time) {
6363
}
6464
#endif
6565

66+
#ifdef HAVE_RB_TIME_TIMESPEC_NEW
67+
static VALUE time_spec_rb_time_timespec_new(VALUE self, VALUE sec, VALUE nsec, VALUE offset) {
68+
struct timespec ts;
69+
ts.tv_sec = NUM2TIMET(sec);
70+
ts.tv_nsec = NUM2LONG(nsec);
71+
72+
return rb_time_timespec_new(&ts, NUM2INT(offset));
73+
}
74+
#endif
75+
6676
#ifdef HAVE_TIMET2NUM
6777
static VALUE time_spec_TIMET2NUM(VALUE self) {
6878
time_t t = 10;
@@ -101,6 +111,10 @@ void Init_time_spec() {
101111
#ifdef HAVE_RB_TIME_TIMESPEC
102112
rb_define_method(cls, "rb_time_timespec", time_spec_rb_time_timespec, 1);
103113
#endif
114+
115+
#ifdef HAVE_RB_TIME_TIMESPEC_NEW
116+
rb_define_method(cls, "rb_time_timespec_new", time_spec_rb_time_timespec_new, 3);
117+
#endif
104118
}
105119

106120
#ifdef __cplusplus

spec/ruby/optional/capi/time_spec.rb

+30
Original file line numberDiff line numberDiff line change
@@ -252,4 +252,34 @@
252252
nsec.should == t.nsec
253253
end
254254
end
255+
256+
describe "rb_time_timespec_new" do
257+
it "returns a time object with the given timespec and UTC offset" do
258+
@s.rb_time_timespec_new(1447087832, 476451125, 32400).should == Time.at(1447087832, 476451.125).localtime(32400)
259+
end
260+
261+
describe "when offset given is within range of -86400 and 86400 (exclusive)" do
262+
it "sets time's is_gmt to false" do
263+
@s.rb_time_timespec_new(1447087832, 476451125, 0).gmt?.should be_false
264+
end
265+
266+
it "sets time's offset to the offset given" do
267+
@s.rb_time_timespec_new(1447087832, 476451125, 86399).gmtoff.should == 86399
268+
end
269+
end
270+
271+
it "returns time object in UTC if offset given equals INT_MAX - 1" do
272+
@s.rb_time_timespec_new(1447087832, 476451125, 0x7ffffffe).utc?.should be_true
273+
end
274+
275+
it "returns time object in localtime if offset given equals INT_MAX" do
276+
@s.rb_time_timespec_new(1447087832, 476451125, 0x7fffffff).should == Time.at(1447087832, 476451.125).localtime
277+
@s.rb_time_timespec_new(1447087832, 476451125, 0x7fffffff).gmtoff.should == Time.now.gmtoff
278+
end
279+
280+
it "raises an ArgumentError if offset passed is not within range of -86400 and 86400 (exclusive)" do
281+
lambda { @s.rb_time_timespec_new(1447087832, 476451125, 86400) }.should raise_error(ArgumentError)
282+
lambda { @s.rb_time_timespec_new(1447087832, 476451125, -86400) }.should raise_error(ArgumentError)
283+
end
284+
end
255285
end

spec/ruby/shared/kernel/method_missing.rb

+10
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,15 @@
110110
it "raises a NoMethodError when a private method is called" do
111111
lambda { @object.new.method_private }.should raise_error(NoMethodError)
112112
end
113+
114+
it 'sets the receiver of the raised NoMethodError' do
115+
obj = @object.new
116+
117+
begin
118+
obj.method_private
119+
rescue NoMethodError => error
120+
(error.receiver == obj).should == true
121+
end
122+
end
113123
end
114124
end

vm/builtin/string.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ namespace rubinius {
602602
native_int String::char_size(STATE) {
603603
if(num_chars_->nil_p()) {
604604
OnigEncodingType* enc = encoding(state)->get_encoding();
605-
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_)) {
605+
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_p(state))) {
606606
num_chars(state, num_bytes_);
607607
} else if(fixed_width_p(encoding_)) {
608608
num_chars(state, Fixnum::from((byte_size() + ONIGENC_MBC_MINLEN(enc) - 1) / ONIGENC_MBC_MINLEN(enc)));
@@ -1337,7 +1337,7 @@ namespace rubinius {
13371337
if(i >= byte_size() || i < 0) return cNil;
13381338

13391339
native_int len = char_size(state);
1340-
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_)) {
1340+
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_p(state))) {
13411341
return byte_substring(state, i, 1);
13421342
} else {
13431343
// Assumptions above about size are possibly invalid, recalculate.
@@ -1355,7 +1355,7 @@ namespace rubinius {
13551355
native_int String::find_character_byte_index(STATE, native_int index,
13561356
native_int start) {
13571357
OnigEncodingType* enc = encoding(state)->get_encoding();
1358-
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_)) {
1358+
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_p(state))) {
13591359
return start + index;
13601360
} else if(fixed_width_p(encoding_)) {
13611361
return start + index * ONIGENC_MBC_MINLEN(enc);
@@ -1391,7 +1391,7 @@ namespace rubinius {
13911391
native_int String::find_byte_character_index(STATE, native_int index,
13921392
native_int start) {
13931393
OnigEncodingType* enc = encoding(state)->get_encoding();
1394-
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_)) {
1394+
if(byte_compatible_p(encoding_) || CBOOL(ascii_only_p(state))) {
13951395
return index;
13961396
} else if(fixed_width_p(encoding_)) {
13971397
return index / ONIGENC_MBC_MINLEN(enc);
@@ -1500,7 +1500,7 @@ namespace rubinius {
15001500
n = size - i;
15011501
}
15021502

1503-
if(n == 0 || byte_compatible_p(encoding_) || CBOOL(ascii_only_)) {
1503+
if(n == 0 || byte_compatible_p(encoding_) || CBOOL(ascii_only_p(state))) {
15041504
return byte_substring(state, i, n);
15051505
} else {
15061506
return char_substring(state, i, n);
@@ -1564,7 +1564,7 @@ namespace rubinius {
15641564
uint8_t* s;
15651565
uint8_t* ss;
15661566

1567-
if(byte_compatible_p(encoding()) || CBOOL(ascii_only_)) {
1567+
if(byte_compatible_p(encoding()) || CBOOL(ascii_only_p(state))) {
15681568
for(s = p += offset, ss = pp; p < e; s = ++p) {
15691569
if(*p != *pp) continue;
15701570

vm/capi/time.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,23 @@ extern "C" {
106106
struct timespec ts = capi_time_num_timespec(env, time);
107107
return ts;
108108
}
109+
110+
VALUE rb_time_timespec_new(const struct timespec *ts, int offset) {
111+
NativeMethodEnvironment* env = NativeMethodEnvironment::get();
112+
113+
Time* time = Time::at(env->state(), ts->tv_sec, ts->tv_nsec);
114+
115+
if(-86400 < offset && offset < 86400) { /* fixed offset */
116+
time->offset(env->state(), Fixnum::from(offset));
117+
time->is_gmt(env->state(), cFalse);
118+
time->zone(env->state(), cNil);
119+
} else if(offset == INT_MAX) { /* localtime */
120+
} else if(offset == INT_MAX - 1) { /* UTC */
121+
time->is_gmt(env->state(), cTrue);
122+
} else {
123+
rb_raise(rb_eArgError, "utc_offset out of range");
124+
}
125+
126+
return env->get_handle(time);
127+
}
109128
}

vm/include/capi/ruby/ruby.h

+3
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,9 @@ struct RTypedData {
21482148
struct timeval rb_time_timeval(VALUE time);
21492149
struct timespec rb_time_timespec(VALUE time);
21502150

2151+
/** Returns a time object with UTC/localtime/fixed offset */
2152+
VALUE rb_time_timespec_new(const struct timespec *ts, int offset);
2153+
21512154
#define HAVE_RB_TIME_NEW 1
21522155
#define HAVE_RB_TIME_NANO_NEW 1
21532156
#define HAVE_RB_TIME_NUM_NEW 1

0 commit comments

Comments
 (0)