Smalltalk and ruby - 2012-12-08

59
An Amateur Smalltalk User’s Observations on Ruby Object Model and Bytecode “freedom” Koan-Sin Tan freedom_at_computer.org RubyConf Taiwan, Dec 8th, 2012 1 Friday, March 22, 13

description

An Amateur Smalltalk User’s Observations on Ruby Object Model and Bytecode

Transcript of Smalltalk and ruby - 2012-12-08

Page 1: Smalltalk and ruby  - 2012-12-08

An Amateur Smalltalk User’s Observations on Ruby Object Model and Bytecode

“freedom” Koan-Sin Tanfreedom_at_computer.org

RubyConf Taiwan, Dec 8th, 2012

1

Friday, March 22, 13

Page 2: Smalltalk and ruby  - 2012-12-08

Or say, learning Ruby, a stupid way

2

Friday, March 22, 13

Page 3: Smalltalk and ruby  - 2012-12-08

Outline

• General introduction

• Smalltalk-80 and Ruby object models

• Smalltalk-80 and Ruby bytecode

3

Friday, March 22, 13

Page 4: Smalltalk and ruby  - 2012-12-08

Who am I• Learnt to write program on MPF-II

• Used to be a programming language junkie

• Learnt a bit Smalltalk during early '90s, use it on and off

• Recent interest in ST-80 because of Scratch and BYOB/SNAP

• Working on dealing with big.LITTLE system

• Knew little about Ruby

4

Friday, March 22, 13

Page 5: Smalltalk and ruby  - 2012-12-08

MPF-II• Multi-tech Micro-Professor

II, MPF-II

• A not so compatible Apple-][ clone

• 6502

• Basic similar to Apple SOFT

• Different monitor

• I got one of this in 1983

5

Friday, March 22, 13

Page 6: Smalltalk and ruby  - 2012-12-08

the first smalltalk-80 I used is on Sun’s SunView, image from Wikipedia

6

Friday, March 22, 13

Page 8: Smalltalk and ruby  - 2012-12-08

Scratch and BYOB/SNAP visual programming

8

Friday, March 22, 13

Page 9: Smalltalk and ruby  - 2012-12-08

ARM big.LITTLE9

Friday, March 22, 13

Page 10: Smalltalk and ruby  - 2012-12-08

10

Friday, March 22, 13

Page 11: Smalltalk and ruby  - 2012-12-08

What I knew about Ruby

• freebsd: portupgrade is written in ruby, http://wiki.freebsd.org/portupgrade

• RoR

• message passing

• temporary variable, block, block arguments

• However, a block in ruby is not an object!!

• And of course, ruby is more than smalltalk-80

11

Friday, March 22, 13

Page 12: Smalltalk and ruby  - 2012-12-08

• Object-Oriented Programming

• OO GUI environment, IDE

• VM, bytecode

• Lambda, functional language, block

• Message passing

• Design Pattern:

• if you read GoF book, you ran into lots Smalltalk patterns before

• Learning/educational

• Logo and the dream of Dynabook

Smalltalk-80

12

Friday, March 22, 13

Page 13: Smalltalk and ruby  - 2012-12-08

some smalltalk-80 systems

• Squeak:  originally  from  Alan  Kay  and  other  veteran  Smalltalk  guys

• Pharo:  a  Squeak  fork  focusing  on  providing  a  clean  and  ready-­‐to-­‐use  smalltalk  environment

• VisualWorks:  the  ParcPlace  system

• GNU  Smalltalk

13

Friday, March 22, 13

Page 14: Smalltalk and ruby  - 2012-12-08

Object Model

• Object Model can be used to refer to different things

• We just touch what a common language user is aware of, not something like the details of how objects are represented in VMs

• I believe you can get more about VM implementations from Sasada-San’s talk

14

Friday, March 22, 13

Page 15: Smalltalk and ruby  - 2012-12-08

Smalltalk Object Model• From "purple book", Chap 16

1. Every class is ultimately a subclass of class Object, except for Object itself, which has no superclass. In particular, Class is a subclass of ClassDescription, which is a subclass of Behavior which is a subclass of Object

2. Every object is an instance of a class

3. Every class is an instance of a metaclass

4. All metaclasses are subclasses of Class

5. Every metaclass is an instance of Metaclass

6. The method of Class and it superclasses support the behavior common to all objects that are classes

7. The methods of instances of Metaclass add the behavior specific to particular classes

15

Friday, March 22, 13

Page 16: Smalltalk and ruby  - 2012-12-08

Smalltalk Object Model

•10 factorial --> 3628800•10 factorial class --> SmallInteger•SmallInteger superclass --> Integer•Integer  superclass  --> Number•Number  superclass  --> Magnitude•Magnitude  superclass  --> Object•Object  superclass  -­‐-­‐>  ProtoObject•ProtoObject  superclass  -­‐-­‐>  nil

16Friday, March 22, 13

Page 17: Smalltalk and ruby  - 2012-12-08

• 10 factorial class allSuperClasses --> an OrderedCollection(Integer Number Magnitude Object ProtoObject)

17

Friday, March 22, 13

Page 18: Smalltalk and ruby  - 2012-12-08

• SmallInteger class --> SmallInteger class• Integer  class  --> Integer  class• Number  class -->  Number  class• Magnitude  class -->  Magnitude  class• Object  class -->  Object  class• ProtoObject  class -->  ProtoObject  class

18Friday, March 22, 13

Page 19: Smalltalk and ruby  - 2012-12-08

Object

Magnitude

Number

Object class

Magnitude class

Number class

Keyinstance-of

Integer class

SmallInteger SmallInteger class

10

Integer

ProtoObject ProtoObject class

figures modified from “Pharo by Example”

19Friday, March 22, 13

Page 20: Smalltalk and ruby  - 2012-12-08

4. All metaclasses are subclasses of Class

5. Every metaclass is an instance of Metaclass

20

Friday, March 22, 13

Page 21: Smalltalk and ruby  - 2012-12-08

SmallInteger class superclass --> Integer classInteger class superclass --> Number classumber class superclass --> Magnitude classMagnitude class superclass --> Object classObject class superclass --> ProtoObject classProtoObject class superclass --> Class

Class class class --> Metaclass

21Friday, March 22, 13

Page 22: Smalltalk and ruby  - 2012-12-08

Object

Magnitude

Number

Object class

Magnitude class

Number class

Keyinstance-of

Integer class

SmallInteger SmallInteger class

10

Integer

ProtoObject ProtoObject class

Class

Class class

Metaclass

Metaclass class

22Friday, March 22, 13

Page 23: Smalltalk and ruby  - 2012-12-08

6. The method of Class and it superclasses support the behavior common to all objects that are classes

7. The methods of instances of Metaclass add the behavior specific to particular classes

23

Friday, March 22, 13

Page 24: Smalltalk and ruby  - 2012-12-08

Class class class --> MetaclassMetaclass superclass --> ClassDescription.ClassDescription superclass --> BehaviorBehavior superclass --> Object

Class class superclass --> ClassDescription classClassDescription class --> superclass Behavior classBehavior class superclass --> Object class

24Friday, March 22, 13

Page 25: Smalltalk and ruby  - 2012-12-08

Object

Magnitude

Number

Object class

Magnitude class

Number class

Keyinstance-of

Integer classSmallInteger

SmallInteger class10

Integer

ProtoObject

ProtoObject class

Class

Class class

Metaclass

Metaclass class

ClassDescription

BehaviorClassDescription class

Behavior class

25Friday, March 22, 13

Page 26: Smalltalk and ruby  - 2012-12-08

from “PBE”26

Friday, March 22, 13

Page 27: Smalltalk and ruby  - 2012-12-08

• since I cannot find good Ruby tutorial/book similar to blue/purple book, let see check if we can use similar way to explore ruby

27

Friday, March 22, 13

Page 28: Smalltalk and ruby  - 2012-12-08

Ruby Metaclass

• Singleton class, eigenclass

28

Friday, March 22, 13

Page 29: Smalltalk and ruby  - 2012-12-08

from ‘ri Class’ of ruby 1.8 +------------------+

| |

Object---->(Object) |

^ ^ ^ ^ |

| | | | |

| | +-----+ +---------+ |

| | | | |

| +-----------+ | |

| | | | |

+------+ | Module--->(Module) |

| | ^ ^ |

OtherClass-->(OtherClass) | | |

| | |

Class---->(Class) |

^ |

| |

+----------------+29

Friday, March 22, 13

Page 30: Smalltalk and ruby  - 2012-12-08

from ‘ri Class’ of ruby 1.9• All  metaclasses  are  instances  of  the  class  `Class'.

          +---------+ +-... | | |

BasicObject-----|-->(BasicObject)-------|-...

^ | ^ |

| | | |

Object---------|----->(Object)---------|-...

^ | ^ |

| | | |

+-------+ | +--------+ |

| | | | | |

| Module-|---------|--->(Module)-|-...

| ^ | | ^ |

| | | | | |

| Class-|---------|---->(Class)-|-...

| ^ | | ^ |

| +---+ | +----+

| |

obj--->OtherClass---------->(OtherClass)-----------...30

Friday, March 22, 13

Page 31: Smalltalk and ruby  - 2012-12-08

Ruby Eigenclass hierarchynoway:work freedom$ ruby -v

ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]

noway:work freedom$ irb -v

irb 0.9.5(05/04/13)

noway:work freedom$ irb

>> 1.class

=> Fixnum

>> 1.class.class

=> Class

>> 1.class.class.superclass

=> Module

>> 1.class.class.superclass.superclass

=> Object

>> 1.class.class.superclass.superclass.superclass

=> nil

>>

freedom@freedom-desktop:~$ ruby -vruby 1.9.3p0 (2011-10-30 revision 33570) [arm-linux-eabi]

freedom@freedom-desktop:~$ irb -virb 0.9.6(09/06/30)freedom@freedom-desktop:~$ irbirb(main):001:0> 1.class=> Fixnumirb(main):002:0> 1.class.class=> Classirb(main):003:0> 1.class.class.superclass=> Moduleirb(main):004:0> 1.class.class.superclass.superclass=> Objectirb(main):005:0> 1.class.class.superclass.superclass.superclass

=> BasicObjectirb(main):006:0> 1.class.class.superclass.superclass.superclass.superclass

=> nilirb(main):007:0>

31

Friday, March 22, 13

Page 32: Smalltalk and ruby  - 2012-12-08

>> 1.class.ancestors

=> [Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]

32

Friday, March 22, 13

Page 33: Smalltalk and ruby  - 2012-12-08

$ rbenv exec irb meta.rb

rb(main):001:0> 1.class.class

=> Class

irb(main):002:0> 1.class.class.ancestors

=> [Class, Module, Object, Kernel, BasicObject]

$rbenv exec irb meta.rb

meta.rb(main):001:0> class Object

meta.rb(main):002:1> def metaclass

meta.rb(main):003:2> class << self; self; end

meta.rb(main):004:2> end

meta.rb(main):005:1> end

=> nil

meta.rb(main):006:0>

meta.rb(main):007:0* 1.class.metaclass

=> #<Class:Fixnum>

eta.rb(main):008:0> 1.class.metaclass.superclass

=> #<Class:Integer>

meta.rb(main):009:0> 1.class.metaclass.ancestors

=> [Class, Module, Object, Kernel, BasicObject]

33

Friday, March 22, 13

Page 34: Smalltalk and ruby  - 2012-12-08

meta.rb(main):009:0> 1.class.metaclass.ancestors

=> [Class, Module, Object, Kernel, BasicObject]

• hmm..., back to superclass

meta.rb(main):010:0> 1.class.metaclass.superclass.superclass

=> #<Class:Numeric>

meta.rb(main):011:0> 1.class.metaclass.superclass.superclass.superclass

=> #<Class:Object>

meta.rb(main):012:0> 1.class.metaclass.superclass.superclass.superclass.superclass

=> #<Class:BasicObject>

meta.rb(main):013:0> 1.class.metaclass.superclass.superclass.superclass.superclass.superclass

=> Class

34

Friday, March 22, 13

Page 35: Smalltalk and ruby  - 2012-12-08

Object

BasicObject

super class

eigenclass #<Class:Object>

eigenclass

#<Class:BasicObject>

super class

Class

super class

instancemethods

methods

super class

BasicObject

super class

super class

String

super class

eigenclass #<Class:String>

super class

! != == __id__ __send__ equal? instance_eval instance_exec

!~ <=> === =~ class clone define_singleton_method display dup eigen_class

eigen_methods enum_for eql? extend freeze frozen? hash initialize_clone initialize_dup inspect

instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? kind_of? method methods nil? object_id private_methods

protected_methods public_method public_methods public_send respond_to?

respond_to_missing? send singleton_class singleton_methods taint tainted? tap to_enum to_s

trust untaint untrust untrusted?

instancemethods

instancemethods

< <= > >= ancestors autoload autoload? class_eval class_exec class_variable_defined?

class_variable_get class_variable_set class_variables const_defined? const_get

const_missing const_set constants include? included_modules instance_method

instance_methods method_defined? module_eval module_exec name private_class_method

private_constant private_instance_methods private_method_defined?

protected_instance_methods protected_method_defined? public_class_method

public_constant public_instance_method public_instance_methods public_method_defined?

remove_class_variable

instancemethods

allocate new superclass

instancemethods

instancemethods

methods

instancemethods

methods

try_convert

Ruby's Object Hierarchy 2

Thomas Schank © 2011 (CC BY-ND)

Module

ObjectKernel includedmodules

•So Ruby’s object hierarchy should be similar to this•http://drtom.schank.ch/posts/2011/12/11/Rubys_Object_Model_and_Eigenclasses/

35

Friday, March 22, 13

Page 37: Smalltalk and ruby  - 2012-12-08

Smalltalk bytecode categories• pushes

• indicates  the  source  of  an  object  to  be  added  to  the  top  of  the  interpreter's  stack

• stores• indicates  the  variable  whose  value  should  be  changed

• sends• specifies  the  selector  of  a  message  to  be  sent  and  how  many  

arguments  it  should  have.• returns

•  a  value  is  returned  for  the  message  that  invoked  that  CompiledMethod

• and  jumps• you  know  what  these  are 37

Friday, March 22, 13

Page 38: Smalltalk and ruby  - 2012-12-08

Smalltalk  bytecodesRange Bits FuncQon0-­‐15 0000iiii Push  Receiver  Variable  #iiii16-­‐31 0001iiii Push  Temporary  LocaQon  #iiii32-­‐63 001iiiii Push  Literal  Constant  #iiiii64-­‐95 010iiiii Push  Literal  Variable  #iiiii96-­‐103 01100iii Pop  and  Store  Receiver  Variable  #iii104-­‐111 01101iii Pop  and  Store  Temporary  LocaQon  #iii112-­‐119 01110iii Push  (receiver,  true,  false,  nil,  -­‐1,  0,  1,  2)  [iii]120-­‐123 011110ii Return  (receiver,  true,  false,  nil)  [ii]  From  Message124-­‐125 0111110i Return  Stack  Top  From  (Message,  Block)  [i]126-­‐127 0111111i unused128 10000000  jjkkkkkk Push  (Receiver  Variable,  Temporary  LocaQon,  Literal  Constant,  Literal  Variable)  [jj]  #kkkkkk129 10000001  jjkkkkkk Store  (Receiver  Variable,  Temporary  LocaQon,  Illegal,  Literal  Variable)  [jj]  #kkkkkk130 10000010  jjkkkkkk Pop  and  Store  (Receiver  Variable,  Temporary  LocaQon,  Illegal,  Literal  Variable)  [jj]  #kkkkkk131 10000011  jjjkkkkk Send  Literal  Selector  #kkkkk  With  jjj  Arguments132 10000100  jjjjjjjj  kkkkkkkk Send  Literal  Selector  #kkkkkkkk  With  jjjjjjjj  Arguments133 10000101  jjjkkkkk Send  Literal  Selector  #kkkkk  To  Superclass  With  jjj  Arguments134 10000110  jjjjjjjj  kkkkkkkk Send  Literal  Selector  #kkkkkkkk  To  Superclass  With  jjjjjjjj  Arguments135 10000111 Pop  Stack  Top136 10001000 Duplicate  Stack  Top137 10001001 Push  AcQve  Context138-­‐143 unused144-­‐151 10010iii Jump  iii  +  1  (i.e.,  1  through  8)152-­‐159 10011iii Pop  and  Jump  0n  False  iii  +1  (i.e.,  1  through  8)160-­‐167 10100iii  jjjjjjjj Jump(iii  -­‐  4)  *256+jjjjjjjj168-­‐171 101010ii  jjjjjjjj Pop  and  Jump  On  True  ii  *256+jjjjjjjj172-­‐175 101011ii  jjjjjjjj Pop  and  Jump  On  False  ii  *256+jjjjjjjj176-­‐191 1011iiii Send  ArithmeQc  Message  #iiii192-­‐207 1100iiii Send  Special  Message  #iiii208-­‐223 1101iiii Send  Literal  Selector  #iiii  With  No  Arguments224-­‐239 1110iiii Send  Literal  Selector  #iiii  With  1  Argument240-­‐255 1111iiii Send  Literal  Selector  #iiii  With  2  Arguments  38

Friday, March 22, 13

Page 39: Smalltalk and ruby  - 2012-12-08

• An  example  method,forCompiledMethod "to show how CompiledMethod works" | foo | foo := 'test'. ^ 1 + 2

• Bytecode:  in  System  Browser  of  Squeak/Pharo,  we  can  see  byteCode  easily–17 <20> pushConstant: 'test'–18 <68> popIntoTemp: 0–19 <76> pushConstant: 1–20 <77> pushConstant: 2–21 <B0> send: +–22 <7C> returnTop

39Friday, March 22, 13

Page 40: Smalltalk and ruby  - 2012-12-08

displaying smalltalk bytecode

• CompiledMethod

• Class>>compiledMethodAt

• (Integer compiledMethodAt: #factorial) symbolic

• (RubyConfTW compiledMethodAt: #forCompiledMethd) symbolic

• code here

40

Friday, March 22, 13

Page 41: Smalltalk and ruby  - 2012-12-08

compiler

• Behavior>>compile

• compile:

compile: code

^self compile: code notifying: nil

• compile:notifying:

• compile:classified: notifying: requestor trailer: ifFail:

41

Friday, March 22, 13

Page 42: Smalltalk and ruby  - 2012-12-08

a Simple Behavior>>compile example• RubyConfTW compile: 'foo^42'

• RubyConfTW will have a new method called foo and the code is to return the ultimate answer

• (RubyConfTW compiledMethodAt: #foo) symbolic

'17 <20> pushConstant: 42

18 <7C> returnTop’

42

Friday, March 22, 13

Page 43: Smalltalk and ruby  - 2012-12-08

add a method

| myClass myInstance |  

myClass := Behavior new. "create anon behavior"  

myClass compile: 'theAnswer ^42'. "add a method for instances"  

myInstance := myClass new. "create an instance"  

Transcript show: myInstance theAnswer; cr. "shows 42" 

43

Friday, March 22, 13

Page 44: Smalltalk and ruby  - 2012-12-08

Ruby bytecode

• ruby  1.8o cannot  find  easy  way  to  do  this

• ruby  1.9  and  2.0o ruby.c:proc_opQons()

§ -­‐-­‐dump=insnso YARV  InstrucQon  tableo hmp://www.atdot.net/yarv/insnstbl.html,  o source  code,  oro you  can  ask  Sasada-­‐san  :-­‐)

44Friday, March 22, 13

Page 45: Smalltalk and ruby  - 2012-12-08

For a simple hello world> rbenv exec ruby --dump=insns ~/work/ruby/test.rb == disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/test.rb>0000 trace 1 ( 1)0002 putself 0003 putstring "hello, world\n"0005 send <callinfo!mid:print, argc:1, FCALL|ARGS_SKIP>0007 leave

45Friday, March 22, 13

Page 46: Smalltalk and ruby  - 2012-12-08

Ruby KERNEL Module

• it  took  me  some  Qme  to  figure  out  what  puts()  and  other  kernel  methods  are

• puts  ==  KERNEL.puts  ==  $stdout.puts()?,  == disasm: <RubyVM::InstructionSequence:<main>@test.rb>=================0000 trace 1 ( 1)0002 putself 0003 putstring "hello, world\n"0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>0007 pop 0008 trace 1 ( 2)0010 getinlinecache 17, <ic:0>0013 getconstant :Kernel0015 setinlinecache <ic:0>0017 putstring "hello, world\n"0019 opt_send_simple <callinfo!mid:puts, argc:1, ARGS_SKIP>0021 pop 0022 trace 1 ( 3)0024 getglobal $stdout0026 putstring "hello, world"0028 opt_send_simple <callinfo!mid:puts, argc:1, ARGS_SKIP>0030 leave

46Friday, March 22, 13

Page 47: Smalltalk and ruby  - 2012-12-08

CompiledMethod in Ruby

• RubyVM::InstructionSequence

• = Class methods:

• compile, compile_file, compile_option, compile_option=, disasm, disassemble, load, new

• = Instance methods:

• disasm, disassemble, eval, inspect, to_a

47

Friday, March 22, 13

Page 48: Smalltalk and ruby  - 2012-12-08

CompiledMethod in Ruby

filename = ARGV[0]

code = RubyVM::InstructionSequence.compile_file filename

File.open "bytecode.dump", "w" do |file|

file << Marshal.dump(code.to_a)

end

print code.disasm

48

Friday, March 22, 13

Page 49: Smalltalk and ruby  - 2012-12-08

Load saved instruction sequence

• there  is  no  RubyVM::InstrucQonSequence.load,  but  there  is  iseq_s_load()  in  iseq.c

#if 0 /* TBD */ rb_define_method(rb_cISeq, "marshal_dump", iseq_marshal_dump, 0); rb_define_method(rb_cISeq, "marshal_load", iseq_marshal_load, 1);#endif

/* disable this feature because there is no verifier. */ /* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */ (void)iseq_s_load;

• So,  my  first  reacQon  is /* disable this feature because there is no verifier. */ rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); // (void)iseq_s_load;

• And  I  googled  a  bit,  found  that,  it  seems  we  can  define  an  InstrucQonSequence.load  method  to  use    iseq_s_load()• hmp://bb10.com/ruby-­‐core/2012-­‐07/msg00303.html

49Friday, March 22, 13

Page 50: Smalltalk and ruby  - 2012-12-08

Store and load• test.rb

puts “hello, world\n”

puts 1+2

• store-and-load.rb

filename = ARGV[0]

code = RubyVM::InstructionSequence.compile_file filename

File.open "bytecode.dump", "w" do |file|

file << Marshal.dump(code.to_a)

end

code = nil

File.open "bytecode.dump", "r" do |file|

code = RubyVM::InstructionSequence.load Marshal.restore(file.read)

end

print code.disasm

50

Friday, March 22, 13

Page 51: Smalltalk and ruby  - 2012-12-08

test.rb./ruby --disable-gems ~/work/ruby/load.rb

== disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/test.rb>

local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)

0000 trace 1

0002 putself

0003 putstring "hello, world\n"

0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0007 pop

0008 trace 1

0010 putself

0011 putobject 1

0013 putobject 2

0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP>

0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0019 leave

51

Friday, March 22, 13

Page 52: Smalltalk and ruby  - 2012-12-08

With some tweaks and modification to bytecode.dump

./ruby --disable-gems ~/work/ruby/load.rb

== disasm: <RubyVM::InstructionSequence:<main>@/Users/freedom/work/ruby/test.rb>

local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)

0000 trace 1

0002 putself

0003 putstring "hello, world\n"

0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0007 pop

0008 trace 1

0010 putself

0011 putobject 1

0013 putobject 2

0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP>

0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0019 answe

52

Friday, March 22, 13

Page 53: Smalltalk and ruby  - 2012-12-08

in case you didn’t get it

• There is a YARV instruction called “answer”

• And, the answer instruction will return “The Answer to Life, the Universe, and Everything”, which you know is 42

• http://en.wikipedia.org/wiki/Answer_to_The_Ultimate_Question_of_Life,_the_Universe,_and_Everything#Answer_to_the_Ultimate_Question_of_Life.2C_the_Universe.2C_and_Everything_.2842.29

53

Friday, March 22, 13

Page 54: Smalltalk and ruby  - 2012-12-08

Comparing bytecodes17 <20> pushConstant: 'test’18 <68> popIntoTemp: 019 <76> pushConstant: 120 <77> pushConstant: 221 <B0> send: +22 <7C> returnTop

0000 trace 1

0002 putself

0003 putstring "hello, world\n"

0005 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0007 pop

0008 trace 1

0010 putself

0011 putobject 1

0013 putobject 2

0015 opt_plus <callinfo!mid:+, argc:1, ARGS_SKIP>

0017 send <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>

0019 leave

54Friday, March 22, 13

Page 55: Smalltalk and ruby  - 2012-12-08

• An  example  method,forCOmpiledMethod2: a and: b "to show how CompiledMethod works" | foo | foo := 'test'. ^ a + b

• Bytecode:  in  System  Browser  of  Squeak/Pharo,  we  can  see  byteCode  easily–17 <20> pushConstant: 'test'–18 <68> popIntoTemp: 2–19 <76> pushTemp: 0–20 <77> pushTemp: 1–21 <B0> send: +–22 <7C> returnTop

55Friday, March 22, 13

Page 56: Smalltalk and ruby  - 2012-12-08

Some obvious differences

• Smalltalk bytecodes are quite low-level, but more consistent?

• String is not special

• no special optimizations such as ‘op_plus’

• but Smalltalk-80 does have some primitive methods

• no joke bytecode :-)

56

Friday, March 22, 13

Page 57: Smalltalk and ruby  - 2012-12-08

Smalltalk primitive methodInteger>>+

+ aNumber    "Refer to the comment in Number + "    aNumber isInteger ifTrue:        [self negative == aNumber negative            ifTrue: [^ (self digitAdd: aNumber) normalize]            ifFalse: [^ self digitSubtract: aNumber]].    ^ aNumber adaptToInteger: self andSend: #+

SmallInteger>>+

+ aNumber     "Primitive. Add the receiver to the argument and answer with the result    if it is a SmallInteger. Fail if the argument or the result is not a    SmallInteger Essential No Lookup. See Object documentation whatIsAPrimitive."

    <primitive: 1>    ^ super + aNumber

57Friday, March 22, 13

Page 58: Smalltalk and ruby  - 2012-12-08

??

58

Friday, March 22, 13

Page 59: Smalltalk and ruby  - 2012-12-08

Thanks!!

59

Friday, March 22, 13