comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchHeadNode.java @ 13529:856c2c294f84

Merge.
author Christian Humer <christian.humer@gmail.com>
date Tue, 07 Jan 2014 18:53:04 +0100
parents 0fbee3eb71f0
children
comparison
equal deleted inserted replaced
13528:5a0c694ef735 13529:856c2c294f84
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.ruby.runtime.*;
15 import com.oracle.truffle.ruby.runtime.core.*;
16 import com.oracle.truffle.ruby.runtime.methods.*;
17 import com.oracle.truffle.ruby.runtime.objects.*;
18
19 /**
20 * The head of a chain of dispatch nodes. Can be used with {@link CallNode} or on its own.
21 */
22 public class DispatchHeadNode extends DispatchNode {
23
24 private final RubyContext context;
25 private final String name;
26 private final boolean isSplatted;
27
28 @Child protected UnboxedDispatchNode dispatch;
29
30 public DispatchHeadNode(RubyContext context, SourceSection sourceSection, String name, boolean isSplatted) {
31 super(context, sourceSection);
32
33 assert context != null;
34 assert name != null;
35
36 this.context = context;
37 this.name = name;
38 this.isSplatted = isSplatted;
39
40 final UninitializedDispatchNode uninitializedDispatch = new UninitializedDispatchNode(context, sourceSection, name);
41 dispatch = adoptChild(new UninitializedBoxingDispatchNode(context, sourceSection, uninitializedDispatch));
42 }
43
44 public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) {
45 return dispatch.dispatch(frame, receiverObject, blockObject, argumentsObjects);
46 }
47
48 /**
49 * Replace the entire dispatch chain with a fresh chain. Used when the situation has changed in
50 * such a significant way that it's best to start again rather than add new specializations to
51 * the chain. Used for example when methods appear to have been monkey-patched.
52 */
53 public Object respecialize(VirtualFrame frame, String reason, Object receiverObject, RubyProc blockObject, Object... argumentObjects) {
54 CompilerAsserts.neverPartOfCompilation();
55
56 replace(new DispatchHeadNode(context, getSourceSection(), name, isSplatted), reason);
57
58 final RubyBasicObject receiverBasicObject = context.getCoreLibrary().box(receiverObject);
59
60 final RubyMethod method = lookup(frame, receiverBasicObject, name);
61 return method.call(frame.pack(), receiverBasicObject, blockObject, argumentObjects);
62 }
63
64 public UnboxedDispatchNode getDispatch() {
65 return dispatch;
66 }
67
68 }