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"); }
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(); } }
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");
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; }
@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); }
@Override Object executeProxy(PolyglotLanguageContext context, Proxy proxy, Object[] arguments) { if (arguments.length >= 2) { Object key = arguments[1]; if (proxy instanceof ProxyObject && key instanceof String) { return invoke(context, (ProxyObject) proxy, (String) key, arguments); } } CompilerDirectives.transferToInterpreter(); throw UnsupportedMessageException.raise(Message.createInvoke(0)); }
return Message.createNew(0); case "INVOKE": return Message.createInvoke(0);
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); }