Skip to content

Instantly share code, notes, and snippets.

View patshaughnessy's full-sized avatar

Pat Shaughnessy patshaughnessy

View GitHub Profile
@patshaughnessy
patshaughnessy / gist:8239185
Last active January 2, 2016 02:48
x86_64 assembly language generated for MRI rb_obj_not (object.c line 186) with modified RTEST macro
-- Change RTEST:
//#define RTEST(v) !(((VALUE)(v) & ~Qnil) == 0)
#define RTEST(v) ((VALUE)(v) != Qnil && (VALUE)(v))
-- Recompile with -S flag:
clang -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith -Werror=write-strings -Werror=declaration-after-statement -Werror=shorten-64-to-32 -Werror=implicit-function-declaration -Werror=division-by-zero -Werror=extra-tokens -pipe -D_FORTIFY_SOURCE=2 -fstack-protector -fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT -fPIE -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -I. -I.ext/include/x86_64-darwin12.0 -I./include -I. -S -o object.o -c object.c
-- And here's the new assembly language - it's longer with a condition in the middle (See: je LBB7_2)
@patshaughnessy
patshaughnessy / gist:8239149
Created January 3, 2014 14:53
x86_64 assembly language generated for MRI rb_obj_not (object.c line 186)
_rb_obj_not: ## @rb_obj_not
.cfi_startproc
Lfunc_begin7:
.loc 1 185 0 ## object.c:185:0
## BB#0:
pushq %rbp
Ltmp90:
.cfi_def_cfa_offset 16
Ltmp91:
.cfi_offset %rbp, -16
@patshaughnessy
patshaughnessy / gist:7104128
Last active April 13, 2023 20:20
Resources for learning about MRI Ruby's internal C source code
Recently someone asked me for online resources about MRI's internal C source
code. Here are a few - if there are more to add please leave a comment! - pat
1. Ruby Hacking Guide - The definitive resource for people who want to learn
the C programming details of how Ruby works internally. Intended for C hackers.
It was just recently translated into English from the original Japanese.
http://ruby-hacking-guide.github.io
2. Various presentations by Koichi Sasada - he often does public presentations
on Ruby internals and they're always fascinating and full of technical details.
@patshaughnessy
patshaughnessy / gist:5672776
Last active December 17, 2015 21:09
Public Speaking Advice
Public speaking advice from a conversation between Ben Orenstein, Jeff Casimir and Katrina Owen.
Listen here: http://learn.thoughtbot.com/podcast/50
- Do remote talks via Skype with user groups or small conferences
- Don't apologize up front about how little you know or how unprepared you are
- Don't introduce yourself - people either know who are you or don't care
- Just start with the problem - why am I listening to this?
- Action right off the bat - like a James Bond movie hook people up front with something interesting
# Prime factorization.
perl -le '$_= 1 x pop; print $+[1] and s/$1/1/g while /^(11+?)\1*$/' 60
2
2
3
5
The "tostring" instruction below calls into this C code, from string.c. This checks if the expression/object is already a string, and does nothing if it is. If it's not a string, it calls "to_s" on the object.
VALUE
rb_obj_as_string(VALUE obj)
{
VALUE str;
if (RB_TYPE_P(obj, T_STRING)) {
return obj;
}
@patshaughnessy
patshaughnessy / gist:3105631
Created July 13, 2012 15:50
Why is for faster than each on Ruby 1.8.7?

Great question! It turns out that in Ruby 1.9 or 2.0 it's actually faster to use each, and not for (by a similar very small amount).

Looking into why for is faster than each in Ruby 1.8.7, it turns out Ruby 1.8.7 uses a slightly different code path for each vs. for, although for still is automatically evaluated as a call to each internally:

if (nd_type(node) == NODE_ITER) {
  result = rb_eval(self, node->nd_iter);
}
else {
  VALUE recv;
I go to the home page
And I follow "sign up"
And I fill in username with "Matt"
And I fill in password with…
@patshaughnessy
patshaughnessy / gist:1979298
Created March 5, 2012 17:01
Ruby parse string backtrace
(gdb) bt
#0 str_new (klass=4303856320, ptr=0x100680500 "The Ruby core team is playing a joke on us!", len=43) at string.c:389
#1 0x00000001001179f8 in rb_str_new [inlined] () at /Users/pat/.rvm/src/ruby-1.9.3-preview1/string.c:416
#2 0x00000001001179f8 in rb_enc_str_new (ptr=<value temporarily unavailable, due to optimizations>, len=<value temporarily unavailable, due to optimizations>, enc=0x1004027e0) at string.c:430
#3 0x000000010009f725 in parser_str_new (p=<value temporarily unavailable, due to optimizations>, n=<value temporarily unavailable, due to optimizations>, enc=0x1004027e0, func=2, enc0=0x1004027e0) at parse.y:5401
#4 0x00000001000aa677 in parser_parse_string (parser=0x10060e000, quote=0x1010793e0) at parse.y:6033
#5 0x00000001000ab285 in parser_yylex (parser=0x10060e000) at parse.y:6645
#6 0x00000001000b4999 in ruby_yyparse (parser=<value temporarily unavailable, due to optimizations>) at parse.y:7922
#7 0x00000001000c24bf in yycompile0 (arg=<value temporarily unavailable, due to optimi
def cripple_rubygems(specs)
reverse_rubygems_kernel_mixin
executables = specs.map { |s| s.executables }.flatten
Gem.source_index # ensure RubyGems is fully loaded
::Kernel.send(:define_method, :gem) do |dep, *reqs|
...etc...