jruby-safe 0.2.2-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7d4c4406a2d5008327fa781205106f933f84d15d
4
+ data.tar.gz: d09fc7ecc14e297a1c676cd0b61d15c87bef0bf5
5
+ SHA512:
6
+ metadata.gz: 620de9cf546f5cd64d3e55a5c392be8598536ab9f2352da7d684344bd6bc1ccded760bba49f625e97fd0afec5dcd94acb02c9474763f65abe54e0e06982880df
7
+ data.tar.gz: c2c28c23359031787148a6d7dbf563f00843e94bc99640ba36baaa990ef2c93eb89f197b02ee622d02e9b5dc9c4e1eac53cc42733e50b33aca1e64e55aceed03
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ .ruby-gemset
4
+ lib/sandbox/sandbox.jar
5
+ pkg/*
6
+ tags
7
+ tmp
8
+ vendor
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby-1.7.9
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby-19mode
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in jruby_sandbox.gemspec
4
+ gemspec
5
+
6
+ # this fork has some recent work done for 1.9, like File.foreach
7
+ gem 'fakefs', :git => 'git://github.com/codeschool/fakefs.git', :require => 'fakefs/safe', :ref => "6ae3212e3dab013b4b5e290d1aceba6466b30dec"
data/Gemfile.lock ADDED
@@ -0,0 +1,40 @@
1
+ GIT
2
+ remote: git://github.com/codeschool/fakefs.git
3
+ revision: 6ae3212e3dab013b4b5e290d1aceba6466b30dec
4
+ ref: 6ae3212e3dab013b4b5e290d1aceba6466b30dec
5
+ specs:
6
+ fakefs (0.4.0)
7
+
8
+ PATH
9
+ remote: .
10
+ specs:
11
+ jruby-safe (0.2.2-java)
12
+ fakefs
13
+
14
+ GEM
15
+ remote: http://rubygems.org/
16
+ specs:
17
+ diff-lcs (1.1.2)
18
+ rake (0.9.2)
19
+ rake-compiler (0.7.9)
20
+ rake
21
+ rspec (2.6.0)
22
+ rspec-core (~> 2.6.0)
23
+ rspec-expectations (~> 2.6.0)
24
+ rspec-mocks (~> 2.6.0)
25
+ rspec-core (2.6.4)
26
+ rspec-expectations (2.6.0)
27
+ diff-lcs (~> 1.1.2)
28
+ rspec-mocks (2.6.0)
29
+ yard (0.7.2)
30
+
31
+ PLATFORMS
32
+ java
33
+
34
+ DEPENDENCIES
35
+ fakefs!
36
+ jruby-safe!
37
+ rake
38
+ rake-compiler
39
+ rspec
40
+ yard
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2006 Ola Bini <ola@ologix.com>
2
+ Copyright (c) 2011 Dray Lacy and Eric Allam
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,71 @@
1
+ JRuby Safe
2
+ =============
3
+
4
+ The JRuby safe is a clone of [jruby-sandbox](https://github.com/omghax/jruby-sandbox)
5
+
6
+ ## Building
7
+
8
+ To build the JRuby extension, run `rake compile`. This will build the
9
+ `lib/sandbox/sandbox.jar` file, which `lib/sandbox.rb` loads.
10
+
11
+ ## Testing
12
+
13
+ $ bundle install --path vendor/bundle
14
+ $ bundle exec rake spec
15
+
16
+ ## Basic Usage
17
+
18
+ Sandbox gives you a self-contained JRuby interpreter in which to eval
19
+ code without polluting the host environment.
20
+
21
+ >> require "sandbox"
22
+ => true
23
+ >> sand = Sandbox::Full.new
24
+ => #<Sandbox::Full:0x46377e2a>
25
+ >> sand.eval("x = 1 + 2") # we've defined x in the sandbox
26
+ => 3
27
+ >> sand.eval("x")
28
+ => 3
29
+ >> x # but it hasn't leaked out into the host interpreter
30
+ NameError: undefined local variable or method `x' for #<Object:0x11cdc190>
31
+
32
+ There's also `Sandbox::Full#require`, which lets you invoke `Kernel#require`
33
+ directly for the sandbox, so you can load any trusted core libraries. Note that
34
+ this is a direct binding to `Kernel#require`, so it will only load ruby stdlib
35
+ libraries (i.e. no rubygems support yet).
36
+
37
+ ## Sandbox::Safe usage
38
+
39
+ Sandbox::Safe exposes an `#activate!` method which will lock down the sandbox,
40
+ removing unsafe methods. Before calling `#activate!`, Sandbox::Safe is the same
41
+ as Sandbox::Full.
42
+
43
+ >> require 'sandbox'
44
+ => true
45
+ >> sand = Sandbox.safe
46
+ => #<Sandbox::Safe:0x17072b90>
47
+ >> sand.eval %{`echo HELLO`}
48
+ => "HELLO\n"
49
+ >> sand.activate!
50
+ >> sand.eval %{`echo HELLO`}
51
+ Sandbox::SandboxException: NoMethodError: undefined method ``' for main:Object
52
+
53
+ Sandbox::Safe works by whitelisting methods to keep, and removing the rest.
54
+ Checkout sandbox.rb for which methods are kept.
55
+
56
+ Sandbox::Safe.activate! will also isolate the sandbox environment from the
57
+ filesystem using FakeFS.
58
+
59
+ >> require 'sandbox'
60
+ => true
61
+ >> s = Sandbox.safe
62
+ => #<Sandbox::Safe:0x3fdb8a73>
63
+ >> s.eval('Dir["/"]')
64
+ => ["/"]
65
+ >> s.eval('Dir["/*"]')
66
+ => ["/Applications", "/bin", "/cores", "/dev", etc.]
67
+ > s.activate!
68
+ >> s.eval('Dir["/*"]')
69
+ => []
70
+ > Dir['/*']
71
+ => ["/Applications", "/bin", "/cores", "/dev", etc.]
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/javaextensiontask'
5
+
6
+ Rake::JavaExtensionTask.new('sandbox') do |ext|
7
+ jruby_home = RbConfig::CONFIG['prefix']
8
+ ext.ext_dir = 'ext/java'
9
+ ext.lib_dir = 'lib/sandbox'
10
+ jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/*.jar']
11
+ ext.classpath = jars.map { |x| File.expand_path(x) }.join(':')
12
+ end
13
+
14
+ require 'rspec/core/rake_task'
15
+
16
+ RSpec::Core::RakeTask.new(:spec) do |t|
17
+ t.pattern = 'spec/**/*_spec.rb'
18
+ t.rspec_opts = ['--backtrace']
19
+ end
20
+
21
+ # Make sure the jar is up to date before running specs
22
+ task :spec => :compile
23
+
24
+ task :default => :spec
@@ -0,0 +1,35 @@
1
+ package sandbox;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyClass;
5
+ import org.jruby.anno.JRubyClass;
6
+ import org.jruby.anno.JRubyMethod;
7
+ import org.jruby.runtime.builtin.IRubyObject;
8
+ import org.jruby.runtime.Block;
9
+
10
+ @JRubyClass(name="BoxedClass")
11
+ public class BoxedClass {
12
+ protected static RubyClass createBoxedClassClass(final Ruby runtime) {
13
+ RubyClass cObject = runtime.getObject();
14
+ RubyClass cBoxedClass = runtime.defineClass("BoxedClass", cObject, cObject.getAllocator());
15
+ cBoxedClass.defineAnnotatedMethods(BoxedClass.class);
16
+
17
+ return cBoxedClass;
18
+ }
19
+
20
+ @JRubyMethod(module=true, rest=true)
21
+ public static IRubyObject method_missing(IRubyObject recv, IRubyObject[] args, Block block) {
22
+ IRubyObject[] args2 = new IRubyObject[args.length - 1];
23
+ System.arraycopy(args, 1, args2, 0, args2.length);
24
+ String name = args[0].toString();
25
+
26
+ SandboxFull box = (SandboxFull) SandboxFull.getLinkedBox(recv);
27
+ return box.runMethod(recv, name, args2, block);
28
+ }
29
+
30
+ @JRubyMethod(name="new", meta=true, rest=true)
31
+ public static IRubyObject _new(IRubyObject recv, IRubyObject[] args, Block block) {
32
+ SandboxFull box = (SandboxFull) SandboxFull.getLinkedBox(recv);
33
+ return box.runMethod(recv, "new", args, block);
34
+ }
35
+ }
@@ -0,0 +1,356 @@
1
+ package sandbox;
2
+
3
+ import java.util.Collection;
4
+ import java.util.Map;
5
+
6
+ import org.jruby.Ruby;
7
+ import org.jruby.RubyClass;
8
+ import org.jruby.RubyBinding;
9
+ import org.jruby.RubyInstanceConfig;
10
+ import org.jruby.RubyKernel;
11
+ import org.jruby.RubyModule;
12
+ import org.jruby.RubyObject;
13
+ import org.jruby.CompatVersion;
14
+ import org.jruby.anno.JRubyClass;
15
+ import org.jruby.anno.JRubyMethod;
16
+ import org.jruby.internal.runtime.methods.DynamicMethod;
17
+ import org.jruby.runtime.Block;
18
+ import org.jruby.runtime.Binding;
19
+ import org.jruby.runtime.ObjectAllocator;
20
+ import org.jruby.runtime.builtin.IRubyObject;
21
+ import org.jruby.common.IRubyWarnings;
22
+ import org.jruby.exceptions.RaiseException;
23
+ import org.jruby.runtime.DynamicScope;
24
+
25
+
26
+ @JRubyClass(name="Sandbox::Full")
27
+ public class SandboxFull extends RubyObject {
28
+ protected static ObjectAllocator FULL_ALLOCATOR = new ObjectAllocator() {
29
+ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
30
+ return new SandboxFull(runtime, klass);
31
+ }
32
+ };
33
+
34
+ private Ruby wrapped;
35
+ private DynamicScope currentScope;
36
+
37
+ protected SandboxFull(Ruby runtime, RubyClass type) {
38
+ super(runtime, type);
39
+ reload();
40
+ }
41
+
42
+ @JRubyMethod
43
+ public IRubyObject reload() {
44
+ RubyInstanceConfig cfg = new RubyInstanceConfig();
45
+ cfg.setObjectSpaceEnabled(getRuntime().getInstanceConfig().isObjectSpaceEnabled());
46
+ cfg.setInput(getRuntime().getInstanceConfig().getInput());
47
+ cfg.setOutput(getRuntime().getInstanceConfig().getOutput());
48
+ cfg.setError(getRuntime().getInstanceConfig().getError());
49
+ cfg.setCompatVersion(CompatVersion.RUBY1_9);
50
+ cfg.setScriptFileName("(sandbox)");
51
+
52
+ SandboxProfile profile = new SandboxProfile(this);
53
+ cfg.setProfile(profile);
54
+
55
+ wrapped = Ruby.newInstance(cfg);
56
+ currentScope = wrapped.getCurrentContext().getCurrentScope();
57
+
58
+ BoxedClass.createBoxedClassClass(wrapped);
59
+
60
+ return this;
61
+ }
62
+
63
+ private static abstract class EvalBinding {
64
+ public abstract Binding convertToBinding(IRubyObject scope);
65
+ }
66
+
67
+ private static EvalBinding evalBinding19 = new EvalBinding() {
68
+ @Override
69
+ public Binding convertToBinding(IRubyObject scope) {
70
+ if (scope instanceof RubyBinding) {
71
+ return ((RubyBinding)scope).getBinding().cloneForEval();
72
+ } else {
73
+ throw scope.getRuntime().newTypeError("wrong argument type " + scope.getMetaClass() + " (expected Binding)");
74
+ }
75
+ }
76
+ };
77
+
78
+ @JRubyMethod(required=1)
79
+ public IRubyObject eval(IRubyObject str) {
80
+ try {
81
+ IRubyObject result = wrapped.evalScriptlet(str.asJavaString(), currentScope);
82
+ return unbox(result);
83
+ } catch (RaiseException e) {
84
+ String msg = e.getException().callMethod(wrapped.getCurrentContext(), "message").asJavaString();
85
+ String path = e.getException().type().getName();
86
+ RubyClass eSandboxException = (RubyClass) getRuntime().getClassFromPath("Sandbox::SandboxException");
87
+ throw new RaiseException(getRuntime(), eSandboxException, path + ": " + msg, false);
88
+ } catch (Exception e) {
89
+ e.printStackTrace();
90
+ getRuntime().getWarnings().warn(IRubyWarnings.ID.MISCELLANEOUS, "NativeException: " + e);
91
+ return getRuntime().getNil();
92
+ }
93
+ }
94
+
95
+ @JRubyMethod(required=2)
96
+ public IRubyObject eval_with_binding(IRubyObject str, IRubyObject argBinding) {
97
+ try {
98
+ //IRubyObject result = wrapped.evalScriptlet(str.asJavaString());
99
+ //boolean bindingGiven = args.length > 1 && !args[1].isNil();
100
+ //Binding binding = bindingGiven ? evalBinding.convertToBinding(args[1]) : context.currentBinding();
101
+ Binding binding = evalBinding19.convertToBinding(argBinding);
102
+ DynamicScope scope = binding.getEvalScope(getRuntime());
103
+ IRubyObject result = wrapped.evalScriptlet(str.asJavaString(), scope);
104
+ return unbox(result);
105
+ } catch (RaiseException e) {
106
+ String msg = e.getException().callMethod(wrapped.getCurrentContext(), "message").asJavaString();
107
+ String path = e.getException().type().getName();
108
+ RubyClass eSandboxException = (RubyClass) getRuntime().getClassFromPath("Sandbox::SandboxException");
109
+ throw new RaiseException(getRuntime(), eSandboxException, path + ": " + msg, false);
110
+ } catch (Exception e) {
111
+ e.printStackTrace();
112
+ getRuntime().getWarnings().warn(IRubyWarnings.ID.MISCELLANEOUS, "NativeException: " + e);
113
+ return getRuntime().getNil();
114
+ }
115
+ }
116
+
117
+ @JRubyMethod(name="import", required=1)
118
+ public IRubyObject _import(IRubyObject klass) {
119
+ if (!(klass instanceof RubyModule)) {
120
+ throw getRuntime().newTypeError(klass, getRuntime().getClass("Module"));
121
+ }
122
+ String name = ((RubyModule) klass).getName();
123
+ importClassPath(name, false);
124
+ return getRuntime().getNil();
125
+ }
126
+
127
+ @JRubyMethod(required=1)
128
+ public IRubyObject ref(IRubyObject klass) {
129
+ if (!(klass instanceof RubyModule)) {
130
+ throw getRuntime().newTypeError(klass, getRuntime().getClass("Module"));
131
+ }
132
+ String name = ((RubyModule) klass).getName();
133
+ importClassPath(name, true);
134
+ return getRuntime().getNil();
135
+ }
136
+
137
+ private RubyModule importClassPath(String path, final boolean link) {
138
+ RubyModule runtimeModule = getRuntime().getObject();
139
+ RubyModule wrappedModule = wrapped.getObject();
140
+
141
+ if (path.startsWith("#")) {
142
+ throw getRuntime().newArgumentError("can't import anonymous class " + path);
143
+ }
144
+
145
+ for (String name : path.split("::")) {
146
+ runtimeModule = (RubyModule) runtimeModule.getConstantAt(name);
147
+ // Create the module when it did not exist yet...
148
+ if (wrappedModule.const_defined_p(wrapped.getCurrentContext(), wrapped.newString(name)).isFalse()) {
149
+ // The BoxedClass takes the place of Object as top of the inheritance
150
+ // hierarchy. As a result, we can intercept all new instances that are
151
+ // created and all method_missing calls.
152
+ RubyModule sup = wrapped.getClass("BoxedClass");
153
+ if (!link && runtimeModule instanceof RubyClass) {
154
+ // If we're importing a class, recursively import all of its
155
+ // superclasses as well.
156
+ sup = importClassPath(runtimeModule.getSuperClass().getName(), true);
157
+ }
158
+
159
+ RubyClass klass = (RubyClass) sup;
160
+ if (wrappedModule == wrapped.getObject()) {
161
+
162
+ if (link || runtimeModule instanceof RubyClass) { // if this is a ref and not an import
163
+ wrappedModule = wrapped.defineClass(name, klass, klass.getAllocator());
164
+ } else {
165
+ wrappedModule = wrapped.defineModule(name);
166
+ }
167
+
168
+ } else {
169
+ if (runtimeModule instanceof RubyClass) {
170
+ wrappedModule = wrappedModule.defineClassUnder(name, klass, klass.getAllocator());
171
+ } else {
172
+ wrappedModule = wrappedModule.defineModuleUnder(name);
173
+ }
174
+
175
+ }
176
+ } else {
177
+ // ...or just resolve it, if it was already known
178
+ wrappedModule = (RubyModule) wrappedModule.getConstantAt(name);
179
+ }
180
+
181
+ // Check the consistency of the hierarchy
182
+ if (runtimeModule instanceof RubyClass) {
183
+ if (!link && !runtimeModule.getSuperClass().getName().equals(wrappedModule.getSuperClass().getName())) {
184
+ throw getRuntime().newTypeError("superclass mismatch for class " + runtimeModule.getSuperClass().getName());
185
+ }
186
+ }
187
+
188
+ if (link || runtimeModule instanceof RubyClass) {
189
+ linkObject(runtimeModule, wrappedModule);
190
+ } else {
191
+ copyMethods(runtimeModule, wrappedModule);
192
+ }
193
+ }
194
+
195
+ return runtimeModule;
196
+ }
197
+
198
+ private void copyMethods(RubyModule from, RubyModule to) {
199
+ to.getMethodsForWrite().putAll(from.getMethods());
200
+ to.getSingletonClass().getMethodsForWrite().putAll(from.getSingletonClass().getMethods());
201
+ }
202
+
203
+ @JRubyMethod(required=2)
204
+ public IRubyObject keep_methods(IRubyObject className, IRubyObject methods) {
205
+ RubyModule module = wrapped.getModule(className.asJavaString());
206
+ if (module != null) {
207
+ keepMethods(module, methods.convertToArray());
208
+ }
209
+ return methods;
210
+ }
211
+
212
+ @JRubyMethod(required=2)
213
+ public IRubyObject keep_singleton_methods(IRubyObject className, IRubyObject methods) {
214
+ RubyModule module = wrapped.getModule(className.asJavaString()).getSingletonClass();
215
+ if (module != null) {
216
+ keepMethods(module, methods.convertToArray());
217
+ }
218
+ return methods;
219
+ }
220
+
221
+ private void keepMethods(RubyModule module, Collection retain) {
222
+ for (Map.Entry<String, DynamicMethod> methodEntry : module.getMethods().entrySet()) {
223
+ String methodName = methodEntry.getKey();
224
+ if (!retain.contains(methodName)) {
225
+ removeMethod(module, methodName);
226
+ }
227
+ }
228
+ }
229
+
230
+ @JRubyMethod(required=2)
231
+ public IRubyObject remove_method(IRubyObject className, IRubyObject methodName) {
232
+ RubyModule module = wrapped.getModule(className.asJavaString());
233
+ if (module != null) {
234
+ removeMethod(module, methodName.asJavaString());
235
+ }
236
+ return getRuntime().getNil();
237
+ }
238
+
239
+ @JRubyMethod(required=2)
240
+ public IRubyObject remove_singleton_method(IRubyObject className, IRubyObject methodName) {
241
+ RubyModule module = wrapped.getModule(className.asJavaString()).getSingletonClass();
242
+ if (module != null) {
243
+ removeMethod(module, methodName.asJavaString());
244
+ }
245
+ return getRuntime().getNil();
246
+ }
247
+
248
+ private void removeMethod(RubyModule module, String methodName) {
249
+ // System.err.println("removing method " + methodName + " from " + module.inspect().asJavaString());
250
+ module.removeMethod(wrapped.getCurrentContext(), methodName);
251
+ }
252
+
253
+ @JRubyMethod(required=1)
254
+ public IRubyObject load(IRubyObject str) {
255
+ try {
256
+ wrapped.getLoadService().load(str.asJavaString(), true);
257
+ return getRuntime().getTrue();
258
+ } catch (RaiseException e) {
259
+ e.printStackTrace();
260
+ return getRuntime().getFalse();
261
+ }
262
+ }
263
+
264
+ @JRubyMethod(required=1)
265
+ public IRubyObject require(IRubyObject str) {
266
+ try {
267
+ IRubyObject result = RubyKernel.require(wrapped.getKernel(), wrapped.newString(str.asJavaString()), Block.NULL_BLOCK);
268
+ return unbox(result);
269
+ } catch (RaiseException e) {
270
+ e.printStackTrace();
271
+ return getRuntime().getFalse();
272
+ }
273
+ }
274
+
275
+ private IRubyObject unbox(IRubyObject obj) {
276
+ return box(obj);
277
+ }
278
+
279
+ private IRubyObject rebox(IRubyObject obj) {
280
+ return box(obj);
281
+ }
282
+
283
+ private IRubyObject box(IRubyObject obj) {
284
+ if (obj.isImmediate()) {
285
+ return cross(obj);
286
+ } else {
287
+ // If this object already existed and was returned from the wrapped
288
+ // runtime on an earlier occasion, it will already contain a link to its
289
+ // brother in the regular runtime and we can safely return that link.
290
+ IRubyObject link = getLinkedObject(obj);
291
+ if (!link.isNil()) {
292
+ IRubyObject box = getLinkedBox(obj);
293
+ if (box == this) return link;
294
+ }
295
+
296
+ // Is the class already known on both sides of the fence?
297
+ IRubyObject klass = constFind(obj.getMetaClass().getRealClass().getName());
298
+ link = getRuntime().getNil();
299
+ if (!klass.isNil()) {
300
+ link = getLinkedObject(klass);
301
+ }
302
+
303
+ if (link.isNil()) {
304
+ return cross(obj);
305
+ } else {
306
+ IRubyObject v = ((RubyClass)klass).allocate();
307
+ linkObject(obj, v);
308
+ return v;
309
+ }
310
+ }
311
+ }
312
+
313
+ private IRubyObject cross(IRubyObject obj) {
314
+ IRubyObject dumped = wrapped.getModule("Marshal").callMethod(wrapped.getCurrentContext(), "dump", obj);
315
+ return getRuntime().getModule("Marshal").callMethod(getRuntime().getCurrentContext(), "load", dumped);
316
+ }
317
+
318
+ protected static IRubyObject getLinkedObject(IRubyObject arg) {
319
+ IRubyObject object = arg.getRuntime().getNil();
320
+ if (arg.getInstanceVariables().hasInstanceVariable("__link__")) {
321
+ object = (IRubyObject) arg.getInstanceVariables().getInstanceVariable("__link__");
322
+ }
323
+ return object;
324
+ }
325
+
326
+ protected static IRubyObject getLinkedBox(IRubyObject arg) {
327
+ IRubyObject object = arg.getRuntime().getNil();
328
+ if (arg.getInstanceVariables().hasInstanceVariable("__box__")) {
329
+ object = (IRubyObject) arg.getInstanceVariables().getInstanceVariable("__box__");
330
+ }
331
+ return object;
332
+ }
333
+
334
+ private void linkObject(IRubyObject runtimeObject, IRubyObject wrappedObject) {
335
+ wrappedObject.getInstanceVariables().setInstanceVariable("__link__", runtimeObject);
336
+ wrappedObject.getInstanceVariables().setInstanceVariable("__box__", this);
337
+ }
338
+
339
+ private IRubyObject constFind(String path) {
340
+ try {
341
+ return wrapped.getClassFromPath(path);
342
+ } catch (Exception e) {
343
+ return wrapped.getNil();
344
+ }
345
+ }
346
+
347
+ protected IRubyObject runMethod(IRubyObject recv, String name, IRubyObject[] args, Block block) {
348
+ IRubyObject[] args2 = new IRubyObject[args.length];
349
+ for (int i = 0; i < args.length; i++) {
350
+ args2[i] = unbox(args[i]);
351
+ }
352
+ IRubyObject recv2 = unbox(recv);
353
+ IRubyObject result = recv2.callMethod(getRuntime().getCurrentContext(), name, args2, block);
354
+ return rebox(result);
355
+ }
356
+ }