MagLev / maglev

GemStone Maglev Ruby Repository
http://maglev.github.io
518 stars 41 forks source link

Can't create top level method #393

Closed zenspider closed 9 years ago

zenspider commented 9 years ago
./bin/maglev-ruby -w -e 'class X; def x; end; end'

works fine, but:

./bin/maglev-ruby -w -e 'def x; end'

fails with:

ERROR 2010 , NoMethodError: undefined method `method_added' for NilClass (NoMethodError)

I don't have the chops to dig into this solo yet. Here's the relevant trace:

topaz 1> where
==> 1 MessageNotUnderstood >> defaultAction    (envId 0) @2 line 3
2 AbstractException >> _outer:with:        (envId 0) @8 line 19
3 AbstractException >> outer               (envId 0) @2 line 19
4 [] in  RubyContext >> evalDashEStrings:  (envId 0) @3 line 17
5 AbstractException >> _executeOuterHandler: (envId 0) @3 line 7
6 AbstractException >> _outer:with:        (envId 0) @4 line 14
7 AbstractException >> outer               (envId 0) @2 line 19
8 [] in  RubyCompiler class >> withRubyHandlers:main:do: (envId 0) @24 line 56
9 AbstractException >> _executeOuterHandler: (envId 0) @3 line 7
10 AbstractException >> _pass:with:         (envId 0) @4 line 13
11 AbstractException >> pass                (envId 0) @2 line 14
12 [] in  ExecBlock >> rubyEnsure:          (envId 0) @5 line 18
13 AbstractException >> _executeHandler:    (envId 0) @3 line 8
14 AbstractException >> _signalWith:        (envId 0) @1 line 1
15 AbstractException >> signal              (envId 0) @2 line 47
16 Kernel # method_missing#1*_              (envId 1) @16 line 15
17 Object >> _doesNotUnderstand:args:envId:reason: (envId 0) @30 line 29
18 Object >> with:perform:env:              (envId 0) @2 line 4
19 RubyCompiler >> compileIn:rubyMethod:    (envId 0) @8 line 10
20 block in  Object class # __compileEval   (envId 1) @4 line 3
21 ExecBlock >> onSynchronous:do:           (envId 0) @2 line 14
22 [] in  ExecBlock >> rubyEnsure:          (envId 0) @2 line 8
23 ExecBlock >> ensure:                     (envId 0) @2 line 12
24 ExecBlock >> rubyEnsure:                 (envId 0) @2 line 20
25 Object class # __compileEval             (envId 1) @2 line 4
26 block in  Object class # __evalCaller#2__ (envId 1) @2 line 6
27 ExecBlock >> ensure:                     (envId 0) @2 line 12
28 Object class # __evalCaller#2__          (envId 1) @9 line 7
29 [] in  RubyCompiler >> evaluateString:with:withSelf:binding:fileName:lineNumber:env: (envId 0) @2 line 42
AllenOtis commented 9 years ago

Is this a regression or something that never worked in maglev ? Assumming it never worked, The runtime implementation of "def" wants to send #method_added to the class, but in this case there is no class at the top level . So perhaps NilClass needs an implementation of method_added which does nothing ?

timfel commented 9 years ago

A generic method_added exists. The error message is confusing, I think. Here is the definition of compileIn:rubyMethod (from src/packages/Maglev.package/RubyCompiler.class/instance/compileIn.rubyMethod..st)

*maglev-runtime
compileIn: aClass rubyMethod: aNode
  "called from generated code"
   | cls selPrefix envId |
   cls := aClass ifNil:[ Object "for irb"  ].  
   envId := 1"__callerEnvId" . 
   selPrefix := self compileSelector: nil inClass: cls 
                rubyMethod: aNode env: envId  .
   selPrefix ifNotNil:[
     "ruby_selector_suffix dependent , use perform to bypass protection"
     aClass with: selPrefix perform: #'method_added#1__' env: 1 .
   ].
   ^ nil  "per ruby specs, a  'def'  returns nil"

I think the problem is that we compile in cls (in case aClass is nil, this is set to be Object), but then we send method_added to aClass

timfel commented 9 years ago

I've pushed a potential fix, let's see if Travis is happy with it (it's late, and I'm too tired to wait for the results locally)