comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchNode.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children
comparison
equal deleted inserted replaced
13513:64a23ce736a0 13514:0fbee3eb71f0
1 /*
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
4 * redistribute it and/or modify it under the terms of the:
5 *
6 * Eclipse Public License version 1.0
7 * GNU General Public License version 2
8 * GNU Lesser General Public License version 2.1
9 */
10 package com.oracle.truffle.ruby.nodes.call;
11
12 import com.oracle.truffle.api.*;
13 import com.oracle.truffle.api.frame.*;
14 import com.oracle.truffle.api.nodes.*;
15 import com.oracle.truffle.ruby.runtime.*;
16 import com.oracle.truffle.ruby.runtime.control.*;
17 import com.oracle.truffle.ruby.runtime.core.*;
18 import com.oracle.truffle.ruby.runtime.methods.*;
19 import com.oracle.truffle.ruby.runtime.objects.*;
20
21 /**
22 * Any node in the dispatch chain.
23 */
24 public class DispatchNode extends Node {
25
26 private final RubyContext context;
27
28 public DispatchNode(RubyContext context, SourceSection sourceSection) {
29 super(sourceSection);
30
31 assert context != null;
32 assert sourceSection != null;
33
34 this.context = context;
35 }
36
37 /**
38 * Get the depth of this node in the dispatch chain. The first node below
39 * {@link DispatchHeadNode} is at depth 1.
40 */
41 public int getDepth() {
42 int depth = 1;
43 Node parent = this.getParent();
44
45 while (!(parent instanceof DispatchHeadNode)) {
46 parent = parent.getParent();
47 depth++;
48 }
49
50 return depth;
51 }
52
53 public Object respecialize(String reason, VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) {
54 CompilerAsserts.neverPartOfCompilation();
55
56 final int depth = getDepth();
57 final DispatchHeadNode head = (DispatchHeadNode) NodeUtil.getNthParent(this, depth);
58
59 return head.respecialize(frame, reason, receiverObject, blockObject, argumentsObjects);
60 }
61
62 /**
63 * The central point for method lookup.
64 */
65 protected RubyMethod lookup(VirtualFrame frame, RubyBasicObject receiverBasicObject, String name) {
66 final RubyMethod method = receiverBasicObject.getLookupNode().lookupMethod(name);
67
68 final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf());
69
70 if (method == null || method.isUndefined()) {
71 CompilerDirectives.transferToInterpreter();
72 throw new RaiseException(context.getCoreLibrary().nameErrorNoMethod(name, receiverBasicObject.toString()));
73 }
74
75 if (!method.isVisibleTo(self)) {
76 CompilerDirectives.transferToInterpreter();
77 throw new RaiseException(context.getCoreLibrary().noMethodError(name, receiverBasicObject.toString()));
78 }
79
80 return method;
81 }
82
83 public RubyContext getContext() {
84 return context;
85 }
86
87 }