MessageNodes() { keyInfo = Message.KEY_INFO.createNode(); keys = Message.KEYS.createNode(); hasSize = Message.HAS_SIZE.createNode(); getSize = Message.GET_SIZE.createNode(); read = Message.READ.createNode(); write = Message.WRITE.createNode(); isBoxed = Message.IS_BOXED.createNode(); unbox = Message.UNBOX.createNode(); } }
return Message.TO_NATIVE; case "EXECUTE": return Message.createExecute(0); case "NEW": return Message.createNew(0); case "INVOKE": return Message.createInvoke(0); initializeMessageClass(messageId);
/** * One can define their own extended message by subclassing. The expectation is that the * subclass will have public constructor and its {@link #equals(java.lang.Object)} and * {@link #hashCode()} methods will operate on the class equivalence. Only then the subclass * will work properly with {@link #valueOf(java.lang.String)} and * {@link #toString(com.oracle.truffle.api.interop.Message)} methods. * * @since 0.8 or earlier */ protected Message() { registerClass(this); }
ExecuteGenerator(ProcessingEnvironment processingEnv, Resolve resolveAnnotation, MessageResolution messageResolutionAnnotation, TypeElement element, ForeignAccessFactoryGenerator containingForeignAccessFactory) { super(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); this.targetableExecuteNode = (new StringBuilder(messageName)).replace(0, 1, messageName.substring(0, 1).toUpperCase()).append("Node").insert(0, "Targetable").toString(); if (Message.createExecute(0).toString().equalsIgnoreCase(messageName)) { numberOfArguments = 2; } else if (Message.createInvoke(0).toString().equalsIgnoreCase(messageName)) { numberOfArguments = 3; } else if (Message.createNew(0).toString().equalsIgnoreCase(messageName)) { numberOfArguments = 2; } else { throw new AssertionError(); } }
private static Object handleMessage(Message message, Node messageNode, TruffleObject obj, String name, Object[] args) throws InteropException { if (message == Message.WRITE) { ForeignAccess.sendWrite(messageNode, obj, name, args[0]); return null; } if (message == Message.HAS_SIZE || message == Message.IS_BOXED || message == Message.IS_EXECUTABLE || message == Message.IS_NULL || message == Message.GET_SIZE) { return ForeignAccess.send(messageNode, obj); } if (message == Message.KEY_INFO) { return ForeignAccess.sendKeyInfo(messageNode, obj, name); } if (message == Message.READ) { return ForeignAccess.sendRead(messageNode, obj, name); } if (message == Message.UNBOX) { return ForeignAccess.sendUnbox(messageNode, obj); } if (Message.createExecute(0).equals(message)) { return ForeignAccess.sendExecute(messageNode, obj, args); } if (Message.createInvoke(0).equals(message)) { return ForeignAccess.sendInvoke(messageNode, obj, name, args); } if (Message.createNew(0).equals(message)) { return ForeignAccess.sendNew(messageNode, obj, args); } CompilerDirectives.transferToInterpreter(); throw UnsupportedMessageException.raise(message); }
@Override protected Object executeImpl(VirtualFrame frame) { Object[] callArgs = frame.getArguments(); final TruffleObject function = receiverType.cast(callArgs[0]); final Object[] args = (Object[]) callArgs[1]; unwrapArgs(engine, args); try { if (executeNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); executeNode = insert(Message.createExecute(0).createNode()); } Object tmp = ForeignAccess.sendExecute(executeNode, function, args); if (tmp == null) { tmp = JavaInterop.asTruffleValue(null); } Object result = returnConvertNode.convert(tmp); // TODO we must check here that the language returns a valid value. return result; } catch (InteropException e) { CompilerDirectives.transferToInterpreter(); throw e.raise(); } } }
@Override public CallTarget accessMessage(Message tree) { if (tree == Message.IS_EXECUTABLE) { return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(Boolean.TRUE)); } else if (Message.createExecute(2).equals(tree)) { return Truffle.getRuntime().createCallTarget(this); } else { throw UnsupportedMessageException.raise(tree); } }
@Override public String checkSignature(ExecutableElement method) { final List<? extends VariableElement> params = method.getParameters(); boolean hasFrameArgument = false; if (params.size() >= 1) { hasFrameArgument = ElementUtils.typeEquals(params.get(0).asType(), Utils.getTypeMirror(processingEnv, VirtualFrame.class)); } int expectedNumberOfArguments = hasFrameArgument ? getParameterCount() + 1 : getParameterCount(); if (params.size() != expectedNumberOfArguments) { if (Message.createInvoke(0).toString().equalsIgnoreCase(messageName)) { return "Wrong number of arguments. Expected signature: ([frame: VirtualFrame], receiverObject: TruffleObject, identifier: String, arguments: Object[])"; } else if (Message.createExecute(0).toString().equalsIgnoreCase(messageName)) { return "Wrong number of arguments. Expected signature: ([frame: VirtualFrame], receiverObject: TruffleObject, arguments: Object[])"; } else { throw new IllegalStateException(); } } if (Message.createInvoke(0).toString().equalsIgnoreCase(messageName)) { if (!ElementUtils.typeEquals(params.get(hasFrameArgument ? 2 : 1).asType(), Utils.getTypeMirror(processingEnv, String.class))) { int i = hasFrameArgument ? 3 : 2; return "The " + i + " argument must be a " + String.class.getName() + "- but is " + ElementUtils.getQualifiedName(params.get(hasFrameArgument ? 2 : 1).asType()); } } VariableElement variableElement = params.get(params.size() - 1); if (!Utils.isObjectArray(variableElement.asType())) { return "The last argument must be the arguments array. Required type: java.lang.Object[]"; } return super.checkSignature(method); }
private void appendFactoryAccessIsExecutable(Writer w) throws IOException { w.append(" @Override").append("\n"); w.append(" public CallTarget accessIsExecutable() {").append("\n"); appendOptionalDefaultHandlerBody(w, Message.IS_EXECUTABLE, Message.createExecute(0)); w.append(" }").append("\n"); }
private static CallTarget accessMessage(Factory26 factory, Message msg) { if (msg instanceof KnownMessage) { switch (msg.hashCode()) { case Execute.HASH: return factory.accessExecute(0);
private void appendFactoryAccessInvoke(Writer w) throws IOException { w.append(" @Override").append("\n"); w.append(" public CallTarget accessInvoke(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createInvoke(0)); w.append(" }").append("\n"); }
private void appendFactoryAccessNew(Writer w) throws IOException { w.append(" @Override").append("\n"); w.append(" public CallTarget accessNew(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createNew(0)); w.append(" }").append("\n"); }
@Override public CallTarget accessMessage(Message tree) { if (tree == Message.IS_EXECUTABLE) { return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(Boolean.TRUE)); } else if (Message.EXECUTE.equals(tree)) { return Truffle.getRuntime().createCallTarget(this); } else { throw UnsupportedMessageException.raise(tree); } }
static Object getMessage(ProcessingEnvironment processingEnv, String messageName) { Object currentMessage = null; try { currentMessage = Message.valueOf(messageName); } catch (IllegalArgumentException ex) { TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(messageName); TypeElement messageElement = processingEnv.getElementUtils().getTypeElement(Message.class.getName()); if (typeElement != null && processingEnv.getTypeUtils().isAssignable(typeElement.asType(), messageElement.asType())) { currentMessage = messageName; } } return currentMessage; }
if (sendIsExecutableNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); sendIsExecutableNode = insert(Message.IS_EXECUTABLE.createNode()); if (sendExecuteNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); sendExecuteNode = insert(Message.createExecute(args.length).createNode());
public static MessageGenerator getGenerator(ProcessingEnvironment processingEnv, Resolve resolveAnnotation, MessageResolution messageResolutionAnnotation, TypeElement element, ForeignAccessFactoryGenerator containingForeignAccessFactory) { String messageName = resolveAnnotation.message(); Object currentMessage = Utils.getMessage(processingEnv, messageName); if (currentMessage != null) { if (Message.READ.toString().equalsIgnoreCase(messageName) || Message.KEY_INFO.toString().equalsIgnoreCase(messageName) || Message.REMOVE.toString().equalsIgnoreCase(messageName)) { return new ReadGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } else if (Message.WRITE.toString().equalsIgnoreCase(messageName)) { return new WriteGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } else if (Message.IS_NULL.toString().equalsIgnoreCase(messageName) || Message.IS_EXECUTABLE.toString().equalsIgnoreCase(messageName) || Message.IS_BOXED.toString().equalsIgnoreCase(messageName) || Message.HAS_SIZE.toString().equalsIgnoreCase(messageName) || Message.GET_SIZE.toString().equalsIgnoreCase(messageName) || Message.UNBOX.toString().equalsIgnoreCase(messageName) || Message.IS_INSTANTIABLE.toString().equalsIgnoreCase(messageName) || Message.HAS_KEYS.toString().equalsIgnoreCase(messageName) || Message.IS_POINTER.toString().equalsIgnoreCase(messageName) || Message.AS_POINTER.toString().equalsIgnoreCase(messageName) || Message.TO_NATIVE.toString().equalsIgnoreCase(messageName)) { return new UnaryGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } else if (Message.KEYS.toString().equalsIgnoreCase(messageName)) { return new KeysGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } else if (Message.createExecute(0).toString().equalsIgnoreCase(messageName) || Message.createInvoke(0).toString().equalsIgnoreCase(messageName) || Message.createNew(0).toString().equalsIgnoreCase(messageName)) { return new ExecuteGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } else { assert !InteropDSLProcessor.KNOWN_MESSAGES.contains(currentMessage); return new GenericGenerator(processingEnv, resolveAnnotation, messageResolutionAnnotation, element, containingForeignAccessFactory); } } return null; }
private void appendFactoryAccessExecute(Writer w) throws IOException { w.append(" @Override").append("\n"); w.append(" public CallTarget accessExecute(int argumentsLength) {").append("\n"); appendOptionalHandlerBody(w, Message.createExecute(0)); w.append(" }").append("\n"); }
private static CallTarget accessMessage(Factory26 factory, Message msg) { if (msg instanceof KnownMessage) { switch (msg.hashCode()) { case Execute.EXECUTE: return factory.accessExecute(((Execute) msg).getArity());
w.append(indent).append(" try {\n"); w.append(indent).append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); if (Message.createInvoke(0).toString().equalsIgnoreCase(messageName)) { w.append(indent).append(" List<Object> arguments = ForeignAccess.getArguments(frame);\n"); w.append(indent).append(" Object identifier = arguments.get(0);\n");