Mercurial > hg > truffle
view truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/MaxMinObject.java @ 22046:e7c2d36daf72
TruffleLanguage.parse method to convert a source to CallTarget. Basic caching to make sure the code is shared among tenants in one JVM.
author | Jaroslav Tulach <jaroslav.tulach@oracle.com> |
---|---|
date | Thu, 30 Jul 2015 17:36:34 +0200 |
parents | 5bc7f7b867ab |
children | 78c3d3d8d86e |
line wrap: on
line source
/* * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.oracle.truffle.tck; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeChildren; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; final class MaxMinObject implements TruffleObject { private final boolean max; public MaxMinObject(boolean max) { this.max = max; } @Override public ForeignAccess getForeignAccess() { return ForeignAccess.create(MaxMinObject.class, new AF()); } static final class AF implements ForeignAccess.Factory10 { @Override public CallTarget accessIsNull() { return null; } @Override public CallTarget accessIsExecutable() { return null; } @Override public CallTarget accessIsBoxed() { return null; } @Override public CallTarget accessHasSize() { return null; } @Override public CallTarget accessGetSize() { return null; } @Override public CallTarget accessUnbox() { return null; } @Override public CallTarget accessRead() { return null; } @Override public CallTarget accessWrite() { return null; } @Override public CallTarget accessExecute(int argumentsLength) { if (argumentsLength == 2) { MaxMinNode maxNode = MaxMinObjectFactory.MaxMinNodeGen.create(new ReadReceiverNode(), MaxMinObjectFactory.UnboxNodeGen.create(new ReadArgNode(0)), MaxMinObjectFactory.UnboxNodeGen.create(new ReadArgNode(1))); return Truffle.getRuntime().createCallTarget(maxNode); } return null; } @Override public CallTarget accessInvoke(int argumentsLength) { return null; } @Override public CallTarget accessMessage(Message unknown) { return null; } } static class ReadArgNode extends Node { private final int argIndex; public ReadArgNode(int argIndex) { this.argIndex = argIndex; } public Object execute(VirtualFrame frame) { return ForeignAccess.getArguments(frame).get(argIndex); } } static class ReadReceiverNode extends Node { public Object execute(VirtualFrame frame) { return ForeignAccess.getReceiver(frame); } } @NodeChildren({@NodeChild(value = "valueNode", type = ReadArgNode.class)}) abstract static class UnboxNode extends Node { @Child private Node unbox; @Child private Node isBoxed; public abstract Object executeUnbox(VirtualFrame frame); @Specialization public int executeUnbox(int value) { return value; } @Specialization public long executeUnbox(long value) { return value; } @Specialization public String executeUnbox(String value) { return value; } @Specialization(guards = "isBoxedPrimitive(frame, foreignValue)") public Object executeUnbox(VirtualFrame frame, TruffleObject foreignValue) { if (unbox == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); unbox = insert(Message.UNBOX.createNode()); } return ForeignAccess.execute(unbox, frame, foreignValue); } protected final boolean isBoxedPrimitive(VirtualFrame frame, TruffleObject object) { if (isBoxed == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); isBoxed = insert(Message.IS_BOXED.createNode()); } return (boolean) ForeignAccess.execute(isBoxed, frame, object); } } @NodeChildren({@NodeChild(value = "receiver", type = ReadReceiverNode.class), @NodeChild(value = "firstNode", type = UnboxNode.class), @NodeChild(value = "secondNode", type = UnboxNode.class)}) abstract static class MaxMinNode extends RootNode { MaxMinNode() { super(MMLanguage.class, null, null); } @Specialization public int execute(MaxMinObject receiver, int first, int second) { return receiver.max ? Math.max(first, second) : Math.min(first, second); } @Specialization public long execute(MaxMinObject receiver, long first, long second) { return receiver.max ? Math.max(first, second) : Math.min(first, second); } @Specialization public double execute(MaxMinObject receiver, double first, double second) { return receiver.max ? Math.max(first, second) : Math.min(first, second); } } private abstract class MMLanguage extends TruffleLanguage { public MMLanguage(Env env) { super(env); } } }