diff --git a/mx.truffle/suite.py b/mx.truffle/suite.py index 150c022b5c08..88f281dfb1b1 100644 --- a/mx.truffle/suite.py +++ b/mx.truffle/suite.py @@ -99,7 +99,10 @@ "com.oracle.truffle.dsl.processor" : { "subDir" : "truffle", "sourceDirs" : ["src"], - "dependencies" : ["com.oracle.truffle.api.dsl"], + "dependencies" : [ + "com.oracle.truffle.api.dsl", + "com.oracle.truffle.api.interop" + ], "checkstyle" : "com.oracle.truffle.dsl.processor", "javaCompliance" : "1.7", "workingSets" : "Truffle,Codegen", diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleReadNode.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleReadNode.java new file mode 100644 index 000000000000..71df989ba1bc --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleReadNode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; + +//@formatter:off +// BEGIN: AcceptMessageExample +@AcceptMessage(value = "READ", +receiverType = ExampleTruffleObject.class, +language = TestTruffleLanguage.class) +public final class ExampleReadNode extends ExampleReadBaseNode { + + @Override + protected Object access(VirtualFrame vf, + ExampleTruffleObject receiver, + String name) { + if (ExampleTruffleObject.MEMBER_NAME.equals(name)) { + return receiver.getValue(); + } + throw UnknownIdentifierException.raise(name); + } +} +// END: AcceptMessageExample +//@formatter:on diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleTruffleObject.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleTruffleObject.java new file mode 100644 index 000000000000..5061c3b1e42e --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleTruffleObject.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +public class ExampleTruffleObject implements TruffleObject { + static final String MEMBER_NAME = "value"; + + private int value = 0; + + void setValue(int value) { + this.value = value; + } + + int getValue() { + return value; + } + + // BEGIN: getForeignAccessMethod + public ForeignAccess getForeignAccess() { + return ExampleTruffleObjectForeign.ACCESS; + } + + // END: getForeignAccessMethod + + // BEGIN: isInstanceCheck + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ExampleTruffleObject; + } + // END: isInstanceCheck +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleWriteNode.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleWriteNode.java new file mode 100644 index 000000000000..15150952a90a --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ExampleWriteNode.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; + +@AcceptMessage(value = "WRITE", receiverType = ExampleTruffleObject.class, language = TestTruffleLanguage.class) +public final class ExampleWriteNode extends ExampleWriteBaseNode { + + @Override + protected int access(VirtualFrame vf, ExampleTruffleObject receiver, String name, int value) { + if (ExampleTruffleObject.MEMBER_NAME.equals(name)) { + receiver.setValue(value); + return value; + } + throw UnknownIdentifierException.raise(name); + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute.java new file mode 100644 index 000000000000..8091e3db0151 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "EXECUTE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Execute extends BaseExecute { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"access method has to have 3 arguments"}) + public Object access(VirtualFrame frame, ValidTruffleObject object) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute2.java new file mode 100644 index 000000000000..d4c690d8007f --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute2.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "EXECUTE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Execute2 extends BaseExecute2 { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The first argument must be a com.oracle.truffle.api.frame.VirtualFrame- but is java.lang.String"}) + public Object access(String frame, ValidTruffleObject object, Object[] args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute3.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute3.java new file mode 100644 index 000000000000..1a4b1974422b --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute3.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "EXECUTE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Execute3 extends BaseExecute3 { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The last argument must be the arguments array. Required type: java.lang.Object[]- but is java.lang.String"}) + public Object access(VirtualFrame frame, ValidTruffleObject object, String args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute4.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute4.java new file mode 100644 index 000000000000..0f59f1a30376 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute4.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "EXECUTE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Execute4 extends BaseExecute4 { + @Override + public Object access(VirtualFrame frame, ValidTruffleObject object, Object[] args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute5.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute5.java new file mode 100644 index 000000000000..bd1823e09b90 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Execute5.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "EXECUTE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Execute5 extends BaseExecute5 { + @Override + public Object access(VirtualFrame frame, ValidTruffleObjectB object, Object[] args) { + return true; + } + + @Override + public Object access(VirtualFrame frame, ValidTruffleObject object, Object[] args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/InvalidTruffleObject.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/InvalidTruffleObject.java new file mode 100644 index 000000000000..3b56d79c3a5a --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/InvalidTruffleObject.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +public class InvalidTruffleObject implements TruffleObject { + + public ForeignAccess getForeignAccess() { + return null; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke.java new file mode 100644 index 000000000000..53609b2f9fce --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke extends BaseInvoke { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"access method has to have 4 arguments"}) + public Object access(VirtualFrame frame, ValidTruffleObject object, String name, Object[] args, int i) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke2.java new file mode 100644 index 000000000000..13ee00b72775 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke2.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke2 extends BaseInvoke2 { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The third argument must be a java.lang.String- but is int"}) + public Object access(VirtualFrame frame, ValidTruffleObject object, int name, Object[] args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke3.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke3.java new file mode 100644 index 000000000000..819df56362ef --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke3.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke3 extends BaseInvoke3 { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The last argument must be the arguments array. Required type: java.lang.Object[]- but is java.lang.String"}) + public Object access(VirtualFrame frame, ValidTruffleObject object, String name, String args) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke4.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke4.java new file mode 100644 index 000000000000..3ec229eebf65 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke4.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke4 extends BaseInvoke4 { + + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The first argument must be a com.oracle.truffle.api.frame.VirtualFrame- but is java.lang.String"}) + protected int access(String vf, ValidTruffleObject receiver, Object name, Object[] args) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke5.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke5.java new file mode 100644 index 000000000000..8107648cbf03 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke5.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke5 extends BaseInvoke5 { + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, String name, Object[] args) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke6.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke6.java new file mode 100644 index 000000000000..ef552dcf3d96 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Invoke6.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "INVOKE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Invoke6 extends BaseInvoke6 { + @Override + protected int access(VirtualFrame vf, ValidTruffleObjectB receiver, String name, Object[] args) { + return 0; + } + + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, String name, Object[] args) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed.java new file mode 100644 index 000000000000..51cc69bd9072 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "IS_BOXED", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class IsBoxed extends BaseIsBoxed { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"access method has to have 2 arguments"}) + public Object access(VirtualFrame frame, ValidTruffleObject object, int i) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed2.java new file mode 100644 index 000000000000..f76ad0829272 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/IsBoxed2.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "IS_BOXED", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class IsBoxed2 extends BaseIsBoxed2 { + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The first argument of access must be of type com.oracle.truffle.api.frame.VirtualFrame- but is java.lang.String"}) + public Object access(String frame, ValidTruffleObject object) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New.java new file mode 100644 index 000000000000..3d455fe6b3f9 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "NEW", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class New extends BaseNew { + @Override + protected int access(VirtualFrame vf, ValidTruffleObjectB receiver, Object[] args) { + return 0; + } + + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, Object[] args) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New1.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New1.java new file mode 100644 index 000000000000..37f89c8e2875 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/New1.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "NEW", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class New1 extends BaseNew1 { + + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, Object[] args) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode.java new file mode 100644 index 000000000000..5f8776731566 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@ExpectError("There needs to be at least one access method.") +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode extends BaseReadNode { +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode2.java new file mode 100644 index 000000000000..640f2bd5fa1d --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode2.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@ExpectError("Missing isInstance method in class com.oracle.truffle.api.dsl.test.interop.InvalidTruffleObject") +@AcceptMessage(value = "READ", receiverType = InvalidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode2 extends BaseReadNode2 { + + @SuppressWarnings({"static-method", "unused"}) + protected int access(VirtualFrame vf, Object receiver, Object name) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode3.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode3.java new file mode 100644 index 000000000000..914fb29ddd73 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode3.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@ExpectError({"Class must be final"}) +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public class ReadNode3 extends BaseReadNode3 { +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode4.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode4.java new file mode 100644 index 000000000000..58f2187c5e2f --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode4.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode4 extends BaseReadNode4 { + + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"access method has to have 3 arguments"}) + protected int access(VirtualFrame vf, Object receiver, Object name, int i) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode5.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode5.java new file mode 100644 index 000000000000..4ce15931cd30 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode5.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode5 extends BaseReadNode5 { + + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The first argument must be a com.oracle.truffle.api.frame.VirtualFrame- but is java.lang.String"}) + protected int access(String vf, Object receiver, Object name) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode6.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode6.java new file mode 100644 index 000000000000..e5cedcb67251 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode6.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode6 extends BaseReadNode6 { + + @Override + protected Object access(VirtualFrame vf, Object receiver, Object name) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode7.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode7.java new file mode 100644 index 000000000000..4a55eebae594 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ReadNode7.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "READ", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class ReadNode7 extends BaseReadNode7 { + + @Override + protected Object access(VirtualFrame vf, ValidTruffleObjectB receiver, Object name) { + return 0; + } + + @Override + protected Object access(VirtualFrame vf, ValidTruffleObject receiver, Object name) { + return 0; + } + + @Override + protected Object access(VirtualFrame vf, Object receiver, Object name) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/TestTruffleLanguage.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/TestTruffleLanguage.java new file mode 100644 index 000000000000..30310981c76b --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/TestTruffleLanguage.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import java.io.IOException; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.instrument.Visualizer; +import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.source.Source; + +@TruffleLanguage.Registration(mimeType = "application/x-test", name = "InteropProcessorTest", version = "1.0") +public final class TestTruffleLanguage extends TruffleLanguage { + + public static final TestTruffleLanguage INSTANCE = new TestTruffleLanguage(); + + @Override + protected Object createContext(com.oracle.truffle.api.TruffleLanguage.Env env) { + return null; + } + + @Override + protected CallTarget parse(Source code, Node context, String... argumentNames) throws IOException { + return null; + } + + @Override + protected Object findExportedSymbol(Object context, String globalName, boolean onlyExplicit) { + return null; + } + + @Override + protected Object getLanguageGlobal(Object context) { + return null; + } + + @Override + protected boolean isObjectOfLanguage(Object object) { + return false; + } + + @Override + protected Visualizer getVisualizer() { + return null; + } + + @Override + protected boolean isInstrumentable(Node node) { + return false; + } + + @Override + protected WrapperNode createWrapperNode(Node node) { + return null; + } + + @Override + protected Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws IOException { + return null; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox.java new file mode 100644 index 000000000000..4cdc2d9f5620 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "UNBOX", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Unbox extends BaseUnbox { + @Override + public Object access(VirtualFrame frame, ValidTruffleObject object) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox2.java new file mode 100644 index 000000000000..195897408ef2 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/Unbox2.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "UNBOX", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class Unbox2 extends BaseUnbox2 { + @Override + public Object access(VirtualFrame frame, ValidTruffleObjectB object) { + return 0; + } + + @Override + public Object access(VirtualFrame frame, ValidTruffleObject object) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/UnknownMessage.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/UnknownMessage.java new file mode 100644 index 000000000000..42d3b094b6c2 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/UnknownMessage.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@ExpectError({"Unknown message type: unknownMsg"}) +@AcceptMessage(value = "unknownMsg", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class UnknownMessage extends BaseUnknownMessage { +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject.java new file mode 100644 index 000000000000..be52aedf8d4e --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObject.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +public class ValidTruffleObject implements TruffleObject { + + public ForeignAccess getForeignAccess() { + return null; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ValidTruffleObject; + } + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObjectB.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObjectB.java new file mode 100644 index 000000000000..f0e566ebc7d8 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/ValidTruffleObjectB.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +public class ValidTruffleObjectB extends ValidTruffleObject { + +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode.java new file mode 100644 index 000000000000..a48a929571b7 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "WRITE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class WriteNode extends BaseWriteNode { + + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"The first argument must be a com.oracle.truffle.api.frame.VirtualFrame- but is java.lang.String"}) + protected int access(String vf, Object receiver, Object name, Object value) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode2.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode2.java new file mode 100644 index 000000000000..2babadf36693 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode2.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.dsl.test.ExpectError; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "WRITE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class WriteNode2 extends BaseWriteNode2 { + + @SuppressWarnings({"static-method", "unused"}) + @ExpectError({"access method has to have 4 arguments"}) + protected int access(VirtualFrame vf, Object receiver, Object name) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode3.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode3.java new file mode 100644 index 000000000000..e0d262892c0c --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode3.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "WRITE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class WriteNode3 extends BaseWriteNode3 { + + @Override + protected int access(VirtualFrame vf, Object receiver, Object name, Object value) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode4.java b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode4.java new file mode 100644 index 000000000000..44bcab09a527 --- /dev/null +++ b/truffle/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/interop/WriteNode4.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.api.dsl.test.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; + +@AcceptMessage(value = "WRITE", receiverType = ValidTruffleObject.class, language = TestTruffleLanguage.class) +public final class WriteNode4 extends BaseWriteNode4 { + + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, Object name, String value) { + return 0; + } + + @Override + protected int access(VirtualFrame vf, ValidTruffleObject receiver, Object name, Object value) { + return 0; + } + + @Override + protected int access(VirtualFrame vf, Object receiver, Object name, Object value) { + return 0; + } +} diff --git a/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/JavaInteropTest.java b/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/JavaInteropTest.java index 8541021dc4fa..45fb4b81f7ef 100644 --- a/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/JavaInteropTest.java +++ b/truffle/com.oracle.truffle.api.interop.java.test/src/com/oracle/truffle/api/interop/java/test/JavaInteropTest.java @@ -40,6 +40,7 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.java.JavaInterop; @@ -187,7 +188,11 @@ public TemporaryRoot(Class lang, Node foreignAccess, @Override public Object execute(VirtualFrame frame) { - return ForeignAccess.execute(foreignAccess, frame, function, args); + try { + return ForeignAccess.send(foreignAccess, frame, function, args); + } catch (InteropException e) { + throw new AssertionError(e); + } } } // end of TemporaryRoot diff --git a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java index 213799bd7612..fe3a6fc438f0 100644 --- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/InvokeMemberNode.java @@ -26,6 +26,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.nodes.RootNode; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -43,7 +44,7 @@ public Object execute(VirtualFrame frame) { final Object nameOrIndex = args.get(0); final int argsLength = args.size() - 1; if (nameOrIndex instanceof Integer) { - throw new IllegalStateException(); + throw UnknownIdentifierException.raise(String.valueOf(nameOrIndex)); } else { String name = (String) nameOrIndex; for (Method m : receiver.clazz.getMethods()) { @@ -56,7 +57,7 @@ public Object execute(VirtualFrame frame) { return JavaFunctionNode.execute(m, receiver.obj, arr); } } - throw new IllegalArgumentException(name); + throw UnknownIdentifierException.raise(name); } } diff --git a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java index dec632c3e851..ccd4d24fed5b 100644 --- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/JavaInterop.java @@ -29,8 +29,10 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import java.lang.reflect.InvocationHandler; @@ -70,28 +72,25 @@ * interface method, followed by the * {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) actual arguments} of the * interface method. Your language can either handle the message or throw - * {@link IllegalArgumentException} to signal additional processing is needed. - *
  • - * If the {@link Message#createInvoke(int) previous message} isn't handled, a {@link Message#READ} - * is sent to your {@link TruffleObject object} (e.g. + * {@link UnsupportedMessageException} to signal additional processing is needed.
  • + *
  • If the {@link Message#createInvoke(int) previous message} isn't handled, a + * {@link Message#READ} is sent to your {@link TruffleObject object} (e.g. * {@link ForeignAccess#getReceiver(com.oracle.truffle.api.frame.Frame) receiver}) with a field name * equal to the name of the interface method. If the read returns a primitive type, it is returned.
  • - *
  • - * If the read value is another {@link TruffleObject}, it is inspected whether it handles + *
  • If the read value is another {@link TruffleObject}, it is inspected whether it handles * {@link Message#IS_EXECUTABLE}. If it does, a message {@link Message#createExecute(int)} with name * of the interface method and its parameters is sent to the object. The result is returned to the * interface method caller.
  • - *
  • - * In case the read value is neither primitive, neither {@link Message#IS_EXECUTABLE executable}, - * and the interface method has no parameters, it is returned back.
  • - *
  • - * All other cases yield an {@link IllegalArgumentException}.
  • + *
  • In case the read value is neither primitive, neither {@link Message#IS_EXECUTABLE executable} + * , and the interface method has no parameters, it is returned back.
  • + *
  • All other cases yield an {@link InteropException}.
  • * *

    * Object oriented languages are expected to handle the initial {@link Message#createInvoke(int)} - * message. Non-OOP languages are expected to ignore it, yield {@link IllegalArgumentException} and - * handle the subsequent {@link Message#READ read} and {@link Message#createExecute(int) execute} - * ones. The real semantic however depends on the actual language one is communicating with. + * message. Non-OOP languages are expected to ignore it, yield {@link UnsupportedMessageException} + * and handle the subsequent {@link Message#READ read} and {@link Message#createExecute(int) + * execute} ones. The real semantic however depends on the actual language one is communicating + * with. *

    */ public final class JavaInterop { @@ -157,7 +156,7 @@ private static T asJavaObject(Class clazz, Type type, TruffleObject forei if (foreignObject == null) { return null; } - if (clazz == List.class && Boolean.TRUE.equals(message(Message.HAS_SIZE, foreignObject))) { + if (clazz == List.class && Boolean.TRUE.equals(binaryMessage(Message.HAS_SIZE, foreignObject))) { Class elementType = Object.class; if (type instanceof ParameterizedType) { ParameterizedType parametrizedType = (ParameterizedType) type; @@ -279,7 +278,7 @@ static Object toJava(Object ret, Method method) { return primitiveRet; } if (ret instanceof TruffleObject) { - if (Boolean.TRUE.equals(message(Message.IS_NULL, ret))) { + if (Boolean.TRUE.equals(binaryMessage(Message.IS_NULL, ret))) { return null; } } @@ -396,7 +395,7 @@ public Object invoke(Object proxy, Method method, Object[] arguments) throws Thr callArgs.add(name); callArgs.addAll(Arrays.asList(args)); ret = message(Message.createInvoke(args.length), obj, callArgs.toArray()); - } catch (IllegalArgumentException ex) { + } catch (InteropException ex) { val = message(Message.READ, obj, name); Object primitiveVal = toPrimitive(val, method.getReturnType()); if (primitiveVal != null) { @@ -427,10 +426,14 @@ static boolean isPrimitive(Object attr) { static Object toPrimitive(Object value, Class requestedType) { Object attr; if (value instanceof TruffleObject) { - if (!Boolean.TRUE.equals(message(Message.IS_BOXED, value))) { + if (!Boolean.TRUE.equals(binaryMessage(Message.IS_BOXED, value))) { return null; } - attr = message(Message.UNBOX, value); + try { + attr = message(Message.UNBOX, value); + } catch (InteropException e) { + throw new IllegalStateException(); + } } else { attr = value; } @@ -479,12 +482,21 @@ static Object toPrimitive(Object value, Class requestedType) { return null; } - static Object message(final Message m, Object receiver, Object... arr) { + @SuppressWarnings("unused") + static Object message(final Message m, Object receiver, Object... arr) throws InteropException { Node n = m.createNode(); CallTarget callTarget = Truffle.getRuntime().createCallTarget(new TemporaryRoot(TruffleLanguage.class, n, (TruffleObject) receiver)); return callTarget.call(arr); } + static Object binaryMessage(final Message m, Object receiver, Object... arr) { + try { + return message(m, receiver, arr); + } catch (InteropException e) { + throw new AssertionError(e); + } + } + private static class TemporaryRoot extends RootNode { @Node.Child private Node foreignAccess; private final TruffleObject function; @@ -496,6 +508,7 @@ public TemporaryRoot(Class lang, Node foreignAccess, this.function = function; } + @SuppressWarnings("deprecation") @Override public Object execute(VirtualFrame frame) { return ForeignAccess.execute(foreignAccess, frame, function, frame.getArguments()); diff --git a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/TruffleList.java b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/TruffleList.java index f51a296fe2dd..b0fa21422719 100644 --- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/TruffleList.java +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/TruffleList.java @@ -24,6 +24,7 @@ */ package com.oracle.truffle.api.interop.java; +import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import java.util.AbstractList; @@ -44,19 +45,31 @@ public static List create(Class elementType, TruffleObject array) { @Override public T get(int index) { - return type.cast(JavaInterop.message(Message.READ, array, index)); + try { + return type.cast(JavaInterop.message(Message.READ, array, index)); + } catch (InteropException e) { + throw new IllegalStateException(e); + } } @Override public T set(int index, T element) { T prev = get(index); - JavaInterop.message(Message.WRITE, array, index, element); + try { + JavaInterop.message(Message.WRITE, array, index, element); + } catch (InteropException e) { + throw new IllegalStateException(e); + } return prev; } @Override public int size() { - return (Integer) JavaInterop.message(Message.GET_SIZE, array); + try { + return (Integer) JavaInterop.message(Message.GET_SIZE, array); + } catch (InteropException e) { + throw new IllegalStateException(e); + } } } diff --git a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/UnboxNode.java b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/UnboxNode.java index c5b0ac51a25c..5e9da445f25e 100644 --- a/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/UnboxNode.java +++ b/truffle/com.oracle.truffle.api.interop.java/src/com/oracle/truffle/api/interop/java/UnboxNode.java @@ -32,6 +32,7 @@ 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.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; @NodeChildren(value = {@NodeChild(value = "valueNode", type = ReadArgNode.class)}) @@ -62,7 +63,11 @@ public Object executeUnbox(VirtualFrame frame, TruffleObject foreignValue) { CompilerDirectives.transferToInterpreterAndInvalidate(); unbox = insert(Message.UNBOX.createNode()); } - return ForeignAccess.execute(unbox, frame, foreignValue); + try { + return ForeignAccess.sendUnbox(unbox, frame, foreignValue); + } catch (UnsupportedMessageException e) { + return null; + } } protected final boolean isBoxedPrimitive(VirtualFrame frame, TruffleObject object) { @@ -70,7 +75,7 @@ protected final boolean isBoxedPrimitive(VirtualFrame frame, TruffleObject objec CompilerDirectives.transferToInterpreterAndInvalidate(); isBoxed = insert(Message.IS_BOXED.createNode()); } - return (boolean) ForeignAccess.execute(isBoxed, frame, object); + return ForeignAccess.sendIsBoxed(isBoxed, frame, object); } } diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/AcceptMessage.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/AcceptMessage.java new file mode 100644 index 000000000000..154f9494cf29 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/AcceptMessage.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, 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.api.interop; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.frame.VirtualFrame; + +/** + * Annotation to put on your node to simplify handling of incoming inter-operability {@link Message + * messages}. + * + * This node needs to be a final class. It extends a base class which will be automatically + * generated. The generated class defines an abstract accept method that needs to be + * overwritten. The first argument of accept needs to be a {@link VirtualFrame}. The + * second argument of accept needs to be a the receiver, i.e., a {@link TruffleObject}. + * Afterwards, the arguments of the message follow. For example: + * + * {@codesnippet AcceptMessageExample} + * + * The receiver object needs to implement a static method isInstance, which checks if a + * given foreign object is an instance of the given receiver type and can therefore be accessed by + * this node. For example: + * + * {@codesnippet isInstanceCheck} + * + * Besides the abstract base class, a {@link ForeignAccess} will be generated. The receiver object + * can then return a singleton instance of this access. For example:
    + * + * {@codesnippet getForeignAccessMethod} + * + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface AcceptMessage { + /** + * Identification of the {@link Message message} to accept. Well known messages include fields + * of the {@link Message} class (e.g. "READ", "WRITE", "UNBOX", + * IS_NULL) or slightly mangled names of {@link Message} class factory methods ( + * EXECUTE, INVOKE). For more details on the string encoding of message names + * see {@link Message#valueOf(java.lang.String)} method. + * + * @return string identification of an inter-operability message + * @see Message#valueOf(java.lang.String) + */ + String value(); + + /** + * The receiver object class that this message implementation belongs to. + * + * An annotation processor generates a {@link ForeignAccess} class, which the + * {@link TruffleObject} can use to implement {@link TruffleObject#getForeignAccess()}. + * + * @return class of the receiver object + */ + Class receiverType(); + + /** + * The language the message implementation belongs to. + * + * @return class of the language object + */ + Class> language(); +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ArityException.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ArityException.java new file mode 100644 index 000000000000..01f6e9ce72b4 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ArityException.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 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.api.interop; + +/** + * An exception thrown if a foreign function or method invocation provides the wrong number of + * arguments. + */ +public final class ArityException extends InteropException { + + private static final long serialVersionUID = 1857745390734085182L; + + private final int expectedArity; + private final int actualArity; + + private ArityException(int expectedArity, int actualArity) { + super("Arity error - expected: " + expectedArity + " actual: " + actualArity); + this.expectedArity = expectedArity; + this.actualArity = actualArity; + } + + /** + * Returns the number of arguments that the foreign object expects. + * + * @return the number of expected arguments + */ + public int getExpectedArity() { + return expectedArity; + } + + /** + * Returns the actual number of arguments provided by the foreign access. + * + * @return the number of provided arguments + */ + public int getActualArity() { + return actualArity; + } + + /** + * Raises an {@link ArityException}, hidden as a {@link RuntimeException}, which allows throwing + * it without an explicit throws declaration. The {@link ForeignAccess} methods (e.g. + * ForeignAccess.sendRead ) catch the exceptions and re-throw them as checked + * exceptions. + * + * @param expectedArity the number of arguments expected by the foreign object + * @param actualArity the number of provided by the foreign access + * + * @return the exception + */ + public static RuntimeException raise(int expectedArity, int actualArity) { + return silenceException(RuntimeException.class, new ArityException(expectedArity, actualArity)); + } + +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java index deb3cb3517e2..81c6be61e2c3 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignAccess.java @@ -24,13 +24,14 @@ */ package com.oracle.truffle.api.interop; +import java.util.List; + import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.impl.ReadOnlyArrayList; import com.oracle.truffle.api.nodes.Node; -import java.util.List; /** * Encapsulates types of access to {@link TruffleObject}. If you want to expose your own objects to @@ -87,14 +88,327 @@ public static ForeignAccess create(Factory factory) { * @return return value, if any * @throws ClassCastException if the createNode has not been created by * {@link Message#createNode()} method. - * @throws IllegalAccessError if the receiver does not support the - * {@link Message#createNode() message represented} by foreignNode + * @throws IllegalStateException if any error occurred while accessing the receiver + * object */ + @SuppressWarnings("deprecation") + @Deprecated public static Object execute(Node foreignNode, VirtualFrame frame, TruffleObject receiver, Object... arguments) { ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) foreignNode; return fn.executeForeign(frame, receiver, arguments); } + /** + * Sends a {@link Message} to the foreign receiver object by executing the + * {@link Message#createNode() foreign node}. + * + * @param foreignNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @param arguments parameters for the receiver + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws InteropException if any error occurred while accessing the receiver + * object + */ + public static Object send(Node foreignNode, VirtualFrame frame, TruffleObject receiver, Object... arguments) throws InteropException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) foreignNode; + try { + return fn.executeForeignImpl(frame, receiver, arguments); + } catch (InteropException e) { + throw e; + } + } + + /** + * Sends a {@link Message#READ READ message} to the foreign receiver object by executing the + * readNode . + * + * @param readNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @param identifier name of the property to be read + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by readNode + * @throws UnknownIdentifierException if the receiver does not allow reading a + * property for the given identifier + */ + public static Object sendRead(Node readNode, VirtualFrame frame, TruffleObject receiver, Object identifier) throws UnknownIdentifierException, UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) readNode; + try { + return fn.executeForeignImpl(frame, receiver, new Object[]{identifier}); + } catch (UnsupportedMessageException e) { + throw e; + } catch (UnknownIdentifierException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends a {@link Message#WRITE WRITE message} to the foreign receiver object by executing the + * writeNode . + * + * @param writeNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @param identifier name of the property to be written + * @param value value to be written + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by writeNode + * @throws UnknownIdentifierException if the receiver does not allow writing a + * property for the given identifier + * @throws UnsupportedTypeException if value has an unsupported type + */ + public static Object sendWrite(Node writeNode, VirtualFrame frame, TruffleObject receiver, Object identifier, Object value) + throws UnknownIdentifierException, UnsupportedTypeException, UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) writeNode; + try { + return fn.executeForeignImpl(frame, receiver, new Object[]{identifier, value}); + } catch (UnknownIdentifierException | UnsupportedTypeException | UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an {@link Message#UNBOX UNBOX message} to the foreign receiver object by executing the + * unboxNode . + * + * @param unboxNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by unboxNode + */ + public static Object sendUnbox(Node unboxNode, VirtualFrame frame, TruffleObject receiver) throws UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) unboxNode; + try { + return fn.executeForeignImpl(frame, receiver); + } catch (UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an EXECUTE {@link Message} to the foreign receiver object by executing the + * executeNode . + * + * @param executeNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign function object to receive the message passed to + * {@link Message#createNode()} method + * @param arguments arguments passed to the foreign function + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedTypeException if one of element of the arguments has an + * unsupported type + * @throws ArityException if the arguments array does not contain the right number + * of arguments for the foreign function + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by executeNode + */ + public static Object sendExecute(Node executeNode, VirtualFrame frame, TruffleObject receiver, Object... arguments) throws UnsupportedTypeException, ArityException, UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) executeNode; + try { + return fn.executeForeignImpl(frame, receiver, arguments); + } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an {@link Message#IS_EXECUTABLE IS_EXECUTABLE message} to the foreign receiver object + * by executing the isExecutableNode . + * + * @param isExecutableNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + */ + public static boolean sendIsExecutable(Node isExecutableNode, VirtualFrame frame, TruffleObject receiver) { + try { + return (boolean) send(isExecutableNode, frame, receiver); + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an INVOKE {@link Message} to the foreign receiver object by executing the + * invokeNode . + * + * @param invokeNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign function object to receive the message passed to + * {@link Message#createNode()} method + * @param arguments arguments passed to the foreign function + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedTypeException if one of element of the arguments has an + * unsupported type + * @throws UnknownIdentifierException if the receiver does not have a property for + * the given identifier that can be invoked + * @throws ArityException if the arguments array does not contain the right number + * of arguments for the foreign function + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by invokeNode + */ + public static Object sendInvoke(Node invokeNode, VirtualFrame frame, TruffleObject receiver, String identifier, Object... arguments) + throws UnsupportedTypeException, ArityException, UnknownIdentifierException, UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) invokeNode; + try { + Object[] args = new Object[arguments.length + 1]; + System.arraycopy(arguments, 0, args, 1, arguments.length); + args[0] = identifier; + return fn.executeForeignImpl(frame, receiver, args); + } catch (UnsupportedTypeException | ArityException | UnknownIdentifierException | UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an NEW {@link Message} to the foreign receiver object by executing the + * newNode . + * + * @param newNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign function object to receive the message passed to + * {@link Message#createNode()} method + * @param arguments arguments passed to the foreign function + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedTypeException if one of element of the arguments has an + * unsupported type + * @throws ArityException if the arguments array does not contain the right number + * of arguments for the foreign function + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by newNode + */ + public static Object sendNew(Node newNode, VirtualFrame frame, TruffleObject receiver, Object... arguments) throws UnsupportedTypeException, ArityException, UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) newNode; + try { + return fn.executeForeignImpl(frame, receiver, arguments); + } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an {@link Message#IS_NULL IS_NULL message} to the foreign receiver object by executing + * the isNullNode . + * + * @param isNullNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + */ + public static boolean sendIsNull(Node isNullNode, VirtualFrame frame, TruffleObject receiver) { + try { + return (boolean) send(isNullNode, frame, receiver); + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an {@link Message#HAS_SIZE HAS_SIZE message} to the foreign receiver object by + * executing the hasSizeNode . + * + * @param hasSizeNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + */ + public static boolean sendHasSize(Node hasSizeNode, VirtualFrame frame, TruffleObject receiver) { + try { + return (boolean) send(hasSizeNode, frame, receiver); + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends a {@link Message#GET_SIZE GET_SIZE message} to the foreign receiver object by executing + * the getSizeNode . + * + * @param getSizeNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + * @throws UnsupportedMessageException if the receiver does not support the + * {@link Message#createNode() message represented} by getSizeNode + */ + public static Object sendGetSize(Node getSizeNode, VirtualFrame frame, TruffleObject receiver) throws UnsupportedMessageException { + ForeignObjectAccessHeadNode fn = (ForeignObjectAccessHeadNode) getSizeNode; + try { + return fn.executeForeignImpl(frame, receiver); + } catch (UnsupportedMessageException e) { + throw e; + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + + /** + * Sends an {@link Message#IS_BOXED IS_BOXED message} to the foreign receiver object by + * executing the isNullNode . + * + * @param isBoxedNode the createNode created by {@link Message#createNode()} + * @param frame the call frame + * @param receiver foreign object to receive the message passed to {@link Message#createNode()} + * method + * @return return value, if any + * @throws ClassCastException if the createNode has not been created by + * {@link Message#createNode()} method. + */ + public static boolean sendIsBoxed(Node isBoxedNode, VirtualFrame frame, TruffleObject receiver) { + try { + return (boolean) send(isBoxedNode, frame, receiver); + } catch (InteropException e) { + throw new AssertionError("Unexpected exception catched.", e); + } + } + /** * Read only access to foreign call arguments inside of a frame. * diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java index 40b39ce116fb..5a7a1403177c 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/ForeignObjectAccessHeadNode.java @@ -47,7 +47,15 @@ protected ObjectAccessNode getFirst() { return first; } - public Object executeForeign(VirtualFrame frame, TruffleObject receiver, Object... arguments) { + @Deprecated + Object executeForeign(VirtualFrame frame, TruffleObject receiver, Object... arguments) { + Object ret = first.executeWith(frame, receiver, arguments); + assert assertReturnValue(ret) : "Only primitive values or TruffleObject expected: " + ret; + return ret; + } + + @SuppressWarnings("unused") + Object executeForeignImpl(VirtualFrame frame, TruffleObject receiver, Object... arguments) throws InteropException { Object ret = first.executeWith(frame, receiver, arguments); assert assertReturnValue(ret) : "Only primitive values or TruffleObject expected: " + ret; return ret; diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/InteropException.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/InteropException.java new file mode 100644 index 000000000000..1dce9254e8a4 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/InteropException.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 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.api.interop; + +/** + * Common super class for exceptions that can occur when sending {@link Message interop messages}. + * This super class is used to catch any kind of these exceptions. + */ +public abstract class InteropException extends Exception { + + InteropException(String string) { + super(string); + } + + InteropException(Exception cause) { + super(cause); + } + + @SuppressWarnings({"unchecked", "unused"}) + static RuntimeException silenceException(Class type, Exception ex) throws E { + throw (E) ex; + } + + private static final long serialVersionUID = -5173354806966156285L; +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java index d30aec56a4a5..a012108772a5 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/Message.java @@ -53,13 +53,13 @@ protected Message() { * {@link ForeignAccess#getArguments(com.oracle.truffle.api.frame.Frame) argument} identifying a * field to read - e.g. either {@link String} or an {@link Integer} - if access to an array at * particular index is requested. The code that wants to send this message should use: - * + * *

          * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
          *   {@link Message#READ}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver, nameOfTheField
          * );
          * 
    - * + * * Where receiver is the {@link TruffleObject foreign object} to access and * nameOfTheField is the name (or index) of its field. *

    @@ -73,13 +73,13 @@ protected Message() { * subclasses of {@link Number}, {@link Boolean}, {@link Character} and {@link String}. Before * sending the {@link #UNBOX} message, it is desirable to send the {@link #IS_BOXED} one and * verify that the object can really be unboxed. To unbox an object, use: - * + * *

          * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
          *   {@link Message#UNBOX}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToUnbox
          * );
          * 
    - * + * * The returned value should be subclass of {@link Number}, {@link Boolean}, {@link Character} * or {@link String}. *

    @@ -96,13 +96,13 @@ protected Message() { * one identifies a field to read - e.g. either {@link String} or an {@link Integer} - if access * to an array at particular index is requested. The second one is the value to assign to such * field. Use following style to construct field modification message: - * + * *

          * {@link ForeignAccess}.{@link ForeignAccess#execute(com.oracle.truffle.api.nodes.Node, com.oracle.truffle.api.frame.VirtualFrame, com.oracle.truffle.api.interop.TruffleObject, java.lang.Object...) execute}(
          *   {@link Message#WRITE}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver, nameOfTheField, newValue
          * );
          * 
    - * + * * Where receiver is the {@link TruffleObject foreign object} to access, * nameOfTheField is the name (or index) of its field and newValue is * the value to assign to the receiver's field. @@ -120,13 +120,13 @@ protected Message() { *

    * To inter-operate with a non-OOP language like C - for example to execute its * function: - * + * *

          * double add(double a, double b) {
          *   return a + b;
          * }
          * 
    - * + * * One can obtain reference to the add function (for example by * {@link Env#importSymbol(java.lang.String) importing it as a global symbol}) and store it into * variable addFunction. Then it's time to check the object is executable by @@ -172,7 +172,7 @@ public static Message createExecute(int argumentsLength) { * should yield value of {@link Boolean}. Either {@link Boolean#TRUE} if the receiver can be * executed (e.g. accepts {@link #createExecute(int)} message, or {@link Boolean#FALSE} * otherwise. This is the way to send the IS_EXECUTABLE message: - * + * *
          * {@link Boolean} canBeExecuted = ({@link Boolean}) {@link ForeignAccess}.execute(
          *   {@link Message#IS_EXECUTABLE}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, receiver
    @@ -214,7 +214,7 @@ public static Message createExecute(int argumentsLength) {
          * the {@link #createInvoke(int)} message first. Only when that fails, fallback to non-object
          * oriented workflow with {@link #createExecute(int)}. Imagine there is a Java class
          * with add method and its instance:
    -     * 
    +     *
          * 
          * public class Arith {
          *    public double add(double a, double b) {
    @@ -223,7 +223,7 @@ public static Message createExecute(int argumentsLength) {
          * }
          * Arith obj = new Arith();
          * 
    - * + * * To access obj's add method one should use: * *
    @@ -235,7 +235,7 @@ public static Message createExecute(int argumentsLength) {
          *   // access the language via {@link #createExecute(int)}
          * }
          * 
    - * + * * The valueOfA and valueOfB should be double or * {@link Double} or at least be {@link #UNBOX unboxable} to such type. *

    @@ -271,7 +271,7 @@ public static Message createNew(int argumentsLength) { * object representing null like values in their languages. For purposes of * inter-operability it is essential to canonicalize such values from time to time - sending * this message is a way to recognize such null representing values: - * + * *

          * {@link Boolean} isNull = ({@link Boolean}) {@link ForeignAccess}.execute(
          *   {@link Message#IS_NULL}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToCheckForNull
    @@ -310,13 +310,13 @@ public static Message createNew(int argumentsLength) {
          * string, etc. To ensure inter-operability, these types should support unboxing - if they do,
          * they should handle this message and return {@link Boolean#TRUE}. The way to check whether an
          * object is boxed is:
    -     * 
    +     *
          * 
          * {@link Boolean} isBoxed = ({@link Boolean}) {@link ForeignAccess}.execute(
          *   {@link Message#IS_BOXED}.{@link Message#createNode()}, {@link VirtualFrame currentFrame}, objectToCheck
          * );
          * 
    - * + * * Calling {@link Factory#accessMessage(com.oracle.truffle.api.interop.Message) the target} * created for this message should yield value of {@link Boolean}. If the object responds with * {@link Boolean#TRUE}, it is safe to continue by sending it {@link #UNBOX} message. @@ -338,7 +338,7 @@ public static Message createNew(int argumentsLength) { /** * When re-implementing {@link #equals(java.lang.Object)}, it is generally recommended to also * implement hashCode(). - * + * * @return hash code */ @Override @@ -360,7 +360,7 @@ public final Node createNode() { * Converts the message into canonical string representation. The converted string can be * stored, persisted, transfered and later passed to {@link #valueOf(java.lang.String)} to * construct the message again. - * + * * @param message the message to convert * @return canonical string representation */ @@ -399,17 +399,17 @@ public static String toString(Message message) { * Converts string representation into real message. If the string was obtained by * {@link #toString(com.oracle.truffle.api.interop.Message)} method, it is guaranteed to be * successfully recognized (if the classpath of the system remains the same). - * + * * @param message canonical string representation of a message * @return the message * @throws IllegalArgumentException if the string does not represent known message */ public static Message valueOf(String message) { try { - return (Message) Message.class.getField(message).get(null); + return (Message) Message.class.getField(message.toUpperCase()).get(null); } catch (Exception ex) { try { - String factory = "create" + message.charAt(0) + message.substring(1).toLowerCase(); + String factory = "create" + Character.toUpperCase(message.charAt(0)) + message.substring(1).toLowerCase(); return (Message) Message.class.getMethod(factory, int.class).invoke(null, 0); } catch (Exception ex2) { try { diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnknownIdentifierException.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnknownIdentifierException.java new file mode 100644 index 000000000000..76a90a40f35f --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnknownIdentifierException.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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.api.interop; + +/** + * An exception thrown if a foreign access tries to access a property of a {@link TruffleObject} + * that is not accessible. + */ +public final class UnknownIdentifierException extends InteropException { + + private static final long serialVersionUID = 1857745390734085182L; + + private final String unknownIdentifier; + + private UnknownIdentifierException(String unknownIdentifier) { + super("Unknown identifier: " + unknownIdentifier); + this.unknownIdentifier = unknownIdentifier; + } + + /** + * Returns the identifier that could not be accessed. + * + * @return the unaccessible identifier + */ + public String getUnknownIdentifier() { + return unknownIdentifier; + } + + /** + * Raises an {@link UnknownIdentifierException}, hidden as a {@link RuntimeException}, which + * allows throwing it without an explicit throws declaration. The {@link ForeignAccess} methods + * (e.g. ForeignAccess.sendRead ) catch the exceptions and re-throw them as + * checked exceptions. + * + * @param unknownIdentifier the identifier that could not be accessed + * + * @return the exception + */ + public static RuntimeException raise(String unknownIdentifier) { + return silenceException(RuntimeException.class, new UnknownIdentifierException(unknownIdentifier)); + } + +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java index fce4f7afdd93..181669897961 100644 --- a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnresolvedObjectAccessNode.java @@ -52,7 +52,7 @@ private static CachedObjectAccessNode createCachedAccess(TruffleObject receiver, ForeignAccess fa = receiver.getForeignAccess(); final CallTarget ct = fa.access(accessTree); if (ct == null) { - throw new IllegalArgumentException("Message " + accessTree + " not recognized by " + fa); + throw UnsupportedMessageException.raise(accessTree); } return new CachedObjectAccessNode(Truffle.getRuntime().createDirectCallNode(ct), next, fa); } diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedMessageException.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedMessageException.java new file mode 100644 index 000000000000..8db907b21721 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedMessageException.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, 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.api.interop; + +/** + * An exception thrown if a {@link TruffleObject} does not support a {@link Message}. + */ +public final class UnsupportedMessageException extends InteropException { + + private static final long serialVersionUID = 1857745390734085182L; + + private final Message message; + + private UnsupportedMessageException(Message message) { + super("Message not supported: " + message.toString()); + this.message = message; + } + + /** + * Returns the {@link Message} that was not supported by the {@link TruffleObject}. + * + * @return the unsupported message + */ + public Message getUnsupportedMessage() { + return message; + } + + /** + * Raises an {@link UnsupportedMessageException}, hidden as a {@link RuntimeException}, which + * allows throwing it without an explicit throws declaration. The {@link ForeignAccess} methods + * (e.g. ForeignAccess.sendRead ) catch the exceptions and re-throw them as + * checked exceptions. + * + * @param message message that is not supported + * + * @return the exception + */ + public static RuntimeException raise(Message message) { + return silenceException(RuntimeException.class, new UnsupportedMessageException(message)); + } + +} diff --git a/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedTypeException.java b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedTypeException.java new file mode 100644 index 000000000000..b52be3035ab4 --- /dev/null +++ b/truffle/com.oracle.truffle.api.interop/src/com/oracle/truffle/api/interop/UnsupportedTypeException.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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.api.interop; + +import java.util.Arrays; + +/** + * An exception thrown if a {@link TruffleObject} does not support the type of one ore more + * arguments provided by a foreign access. + */ +public final class UnsupportedTypeException extends InteropException { + + private static final long serialVersionUID = 1857745390734085182L; + + private final Object[] suppliedValues; + + private UnsupportedTypeException(Object[] suppliedValues) { + super("Unsupported types: " + Arrays.toString(suppliedValues)); + this.suppliedValues = suppliedValues; + } + + /** + * Returns the arguments of the foreign object access that were not supported by the + * {@link TruffleObject}. + * + * @return the unsupported arguments + */ + public Object[] getSuppliedValues() { + return suppliedValues; + } + + /** + * Raises an {@link UnsupportedTypeException}, hidden as a {@link RuntimeException}, which + * allows throwing it without an explicit throws declaration. The {@link ForeignAccess} methods + * (e.g. ForeignAccess.sendRead ) catch the exceptions and re-throw them as + * checked exceptions. + * + * @param suppliedValues values that were not supported + * + * @return the exception + */ + public static RuntimeException raise(Object[] suppliedValues) { + return silenceException(RuntimeException.class, new UnsupportedTypeException(suppliedValues)); + } +} diff --git a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java index b2893b14d92c..4bc51a3f60ee 100644 --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/interop/ForeignAccessSingleThreadedTest.java @@ -51,7 +51,7 @@ public void run() { @Test(expected = AssertionError.class) public void accessNodeFromWrongThread() { Node n = Message.IS_EXECUTABLE.createNode(); - Object ret = ForeignAccess.execute(n, null, this); + Object ret = ForeignAccess.sendIsExecutable(n, null, this); fail("Should throw an exception: " + ret); } diff --git a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java index 0228a9da0d5d..60ea47cb90c5 100644 --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java @@ -37,7 +37,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.Executor; +import java.util.logging.Level; import java.util.logging.Logger; import com.oracle.truffle.api.CallTarget; @@ -61,8 +63,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; -import java.util.WeakHashMap; -import java.util.logging.Level; /** * Gate way into the world of {@link TruffleLanguage Truffle languages}. {@link #buildNew() @@ -427,7 +427,7 @@ private Object evalImpl(TruffleLanguage[] fillLang, Source s, Language l) thr } } - @SuppressWarnings("try") + @SuppressWarnings({"try", "deprecation"}) final Object invokeForeign(final Node foreignNode, VirtualFrame frame, final TruffleObject receiver) throws IOException { Object res; if (executor == null) { @@ -684,7 +684,7 @@ public Value invoke(final Object thiz, final Object... args) throws IOException * {@link java.lang.Double}, {@link java.lang.Character}, * {@link java.lang.Boolean}, and {@link java.lang.String}) or a * {@link TruffleObject object created} by one of the languages) - * + * * @return symbol wrapper around the value returned by invoking the symbol, never * null * @throws IOException signals problem during execution @@ -790,7 +790,8 @@ public Value eval(Source source) throws IOException { * Returns value representing global object of the language. *

    * The object is expected to be TruffleObject (e.g. a native object from the - * other language) but technically it can be one of Java primitive wrappers ({@link Integer}, {@link Double}, {@link Short}, etc.). + * other language) but technically it can be one of Java primitive wrappers ({@link Integer} + * , {@link Double}, {@link Short}, etc.). * * @return the global object or null if the language does not support such * concept diff --git a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/SymbolInvokerImpl.java b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/SymbolInvokerImpl.java index f4f18e0e206d..2c46c797b111 100644 --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/SymbolInvokerImpl.java +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/SymbolInvokerImpl.java @@ -30,8 +30,10 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; @@ -81,8 +83,12 @@ public Object execute(VirtualFrame frame) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new ArgumentsMishmashException(); } - Object tmp = ForeignAccess.execute(foreignAccess, frame, function, args); - return convert.convert(frame, tmp); + try { + Object tmp = ForeignAccess.send(foreignAccess, frame, function, args); + return convert.convert(frame, tmp); + } catch (InteropException e) { + throw new AssertionError(e); + } } } @@ -107,21 +113,17 @@ Object convert(VirtualFrame frame, Object obj) { private Object convert(VirtualFrame frame, TruffleObject obj) { Object isBoxedResult; - try { - isBoxedResult = ForeignAccess.execute(isBoxed, frame, obj); - } catch (IllegalArgumentException ex) { - isBoxedResult = false; - } + isBoxedResult = ForeignAccess.sendIsBoxed(isBoxed, frame, obj); if (Boolean.TRUE.equals(isBoxedResult)) { - return ForeignAccess.execute(unbox, frame, obj); - } else { try { - Object isNullResult = ForeignAccess.execute(isNull, frame, obj); - if (Boolean.TRUE.equals(isNullResult)) { - return null; - } - } catch (IllegalArgumentException ex) { - // fallthrough + return ForeignAccess.sendUnbox(unbox, frame, obj); + } catch (UnsupportedMessageException e) { + return null; + } + } else { + Object isNullResult = ForeignAccess.sendIsNull(isNull, frame, obj); + if (Boolean.TRUE.equals(isNullResult)) { + return null; } } return obj; diff --git a/truffle/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor b/truffle/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor index 48f3df563100..cb08102f1e27 100644 --- a/truffle/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor +++ b/truffle/com.oracle.truffle.dsl.processor/src/META-INF/services/javax.annotation.processing.Processor @@ -1,3 +1,4 @@ com.oracle.truffle.dsl.processor.TruffleProcessor com.oracle.truffle.dsl.processor.verify.VerifyTruffleProcessor com.oracle.truffle.dsl.processor.LanguageRegistrationProcessor +com.oracle.truffle.dsl.processor.InteropProcessor diff --git a/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/InteropProcessor.java b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/InteropProcessor.java new file mode 100644 index 000000000000..5f7dbf5a6c5c --- /dev/null +++ b/truffle/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/InteropProcessor.java @@ -0,0 +1,891 @@ +/* + * Copyright (c) 2016, 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. + * + * 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.dsl.processor; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.MirroredTypeException; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic.Kind; +import javax.tools.JavaFileObject; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; + +/** + * THIS IS NOT PUBLIC API. + */ +public final class InteropProcessor extends AbstractProcessor { + + @Override + public Set getSupportedAnnotationTypes() { + Set annotations = new HashSet<>(); + annotations.add("com.oracle.truffle.api.interop.AcceptMessage"); + return annotations; + } + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return false; + } + + Map factoryGenerators = new HashMap<>(); + List generatedClasses = new LinkedList<>(); + + top: for (Element e : roundEnv.getElementsAnnotatedWith(AcceptMessage.class)) { + if (e.getKind() != ElementKind.CLASS) { + continue; + } + AcceptMessage message = e.getAnnotation(AcceptMessage.class); + if (message == null) { + continue; + } + TypeMirror extending = ((TypeElement) e).getSuperclass(); + if (extending.getKind() != TypeKind.ERROR) { + continue; + } + + final String pkg = findPkg(e); + String receiverTypeFullClassName = getReceiverTypeFullClassName(message); + final String receiverTypeSimpleClass = receiverTypeFullClassName.substring(receiverTypeFullClassName.lastIndexOf(".") + 1); + final String receiverTypePackage = receiverTypeFullClassName.substring(0, receiverTypeFullClassName.lastIndexOf(".")); + final String factoryShortClassName = receiverTypeSimpleClass + "Foreign"; + final String factoryFullClassName = receiverTypeFullClassName + "Foreign"; + + String truffleLanguageFullClazzName = getTruffleLanguageFullClassName(message); + + final String clazzName = extending.toString(); + String fqn = pkg + "." + clazzName; + String messageName = message.value().toLowerCase(Locale.ENGLISH); + + MessageGenerator currentGenerator = null; + Message currentMessage = null; + try { + currentMessage = Message.valueOf(messageName); + if (Message.READ.toString().equalsIgnoreCase(messageName)) { + currentGenerator = new ReadGenerator(processingEnv, e, pkg, clazzName, fqn, messageName, ((TypeElement) e).getSimpleName().toString(), truffleLanguageFullClazzName); + } else if (Message.WRITE.toString().equalsIgnoreCase(messageName)) { + currentGenerator = new WriteGenerator(processingEnv, e, pkg, clazzName, fqn, messageName, ((TypeElement) e).getSimpleName().toString(), truffleLanguageFullClazzName); + } 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)) { + currentGenerator = new UnaryGenerator(processingEnv, e, pkg, clazzName, fqn, messageName, ((TypeElement) e).getSimpleName().toString(), truffleLanguageFullClazzName); + } else if (Message.createExecute(0).toString().equalsIgnoreCase(messageName) || Message.createInvoke(0).toString().equalsIgnoreCase(messageName) || + Message.createNew(0).toString().equalsIgnoreCase(messageName)) { + currentGenerator = new ExecuteGenerator(processingEnv, e, pkg, clazzName, fqn, messageName, ((TypeElement) e).getSimpleName().toString(), truffleLanguageFullClazzName); + } + } catch (IllegalArgumentException ex) { + // fall through + } + + if (currentGenerator == null) { + generateErrorClass(e, pkg, fqn, clazzName); + emitError("Unknown message type: " + message.value(), e); + continue; + } + + if (isInstanceMissing(receiverTypeFullClassName)) { + generateErrorClass(e, pkg, fqn, clazzName); + emitError("Missing isInstance method in class " + receiverTypeFullClassName, e); + continue; + } + + if (!e.getModifiers().contains(javax.lang.model.element.Modifier.FINAL)) { + generateErrorClass(e, pkg, fqn, clazzName); + emitError("Class must be final", e); + continue; + } + + List methods = currentGenerator.getAccessMethods(); + if (methods.size() == 0) { + generateErrorClass(e, pkg, fqn, clazzName); + emitError("There needs to be at least one access method.", e); + continue; + } + + for (ExecutableElement m : methods) { + String errorMessage = currentGenerator.checkSignature(m); + if (errorMessage != null) { + generateErrorClass(e, pkg, fqn, clazzName); + emitError(errorMessage, m); + continue top; + } + } + + if (generatedClasses.contains(fqn)) { + emitError("Base class name already in use.", e); + continue; + } + + currentGenerator.generate(generatedClasses); + + if (!factoryGenerators.containsKey(receiverTypeFullClassName)) { + try { + factoryGenerators.put(receiverTypeFullClassName, new FactoryGenerator(receiverTypePackage, factoryShortClassName, receiverTypeFullClassName, + processingEnv.getFiler().createSourceFile(factoryFullClassName, e))); + } catch (IOException e1) { + throw new IllegalStateException(e1); + } + } + FactoryGenerator factoryGenerator = factoryGenerators.get(receiverTypeFullClassName); + factoryGenerator.addMessageHandler(currentMessage, currentGenerator.getRootNodeFactoryInvokation()); + } + + for (FactoryGenerator fg : factoryGenerators.values()) { + fg.generate(); + } + + return true; + } + + private void generateErrorClass(Element e, final String pkg, final String fqn, final String clazzName) { + try { + JavaFileObject file = processingEnv.getFiler().createSourceFile(fqn, e); + Writer w = file.openWriter(); + w.append("package ").append(pkg).append(";\n"); + + w.append("abstract class ").append(clazzName).append(" {\n"); + w.append(" // An error occured, fix ").append(e.getSimpleName()).append(" first.\n"); + w.append("}\n"); + w.close(); + } catch (IOException ex1) { + emitError(ex1.getMessage(), e); + } + } + + private boolean isInstanceMissing(String receiverTypeFullClassName) { + for (Element elem : this.processingEnv.getElementUtils().getTypeElement(receiverTypeFullClassName).getEnclosedElements()) { + if (elem.getKind().equals(ElementKind.METHOD)) { + ExecutableElement method = (ExecutableElement) elem; + if (method.getSimpleName().toString().equals("isInstance") && method.getParameters().size() == 1 && + method.getParameters().get(0).asType().toString().equals(TruffleObject.class.getName())) { + return false; + } + } + } + return true; + } + + private static String getReceiverTypeFullClassName(AcceptMessage message) { + String receiverTypeFullClassName; + try { + receiverTypeFullClassName = message.receiverType().getName(); + } catch (MirroredTypeException mte) { + // wow, annotations processors are strange + receiverTypeFullClassName = mte.getTypeMirror().toString(); + } + return receiverTypeFullClassName; + } + + private static String getTruffleLanguageFullClassName(AcceptMessage message) { + String truffleLanguageFullClazzName; + try { + truffleLanguageFullClazzName = message.language().getName(); + } catch (MirroredTypeException mte) { + // wow, annotations processors are strange + truffleLanguageFullClazzName = mte.getTypeMirror().toString(); + } + return truffleLanguageFullClazzName; + } + + private static String findPkg(Element e) { + Element curr = e; + for (;;) { + if (curr.getKind() == ElementKind.PACKAGE) { + return ((PackageElement) curr).getQualifiedName().toString(); + } + curr = curr.getEnclosingElement(); + } + } + + private void emitError(String msg, Element e) { + if (ExpectError.isExpectedError(processingEnv, e, msg)) { + return; + } + processingEnv.getMessager().printMessage(Kind.ERROR, msg, e); + } + + private abstract static class MessageGenerator { + protected static final String ACCESS_METHOD_NAME = "access"; + + protected final Element e; + protected final String pkg; + protected final String clazzName; + protected final String methodName; + protected final String fullClazzName; + protected final String userClassName; + protected final String truffleLanguageFullClazzName; + protected final ProcessingEnvironment processingEnv; + + MessageGenerator(ProcessingEnvironment processingEnv, Element e, final String pkg, final String clazzName, String fullClazzName, String methodName, String userClassName, + String truffleLanguageFullClazzName) { + this.processingEnv = processingEnv; + this.e = e; + this.pkg = pkg; + this.clazzName = clazzName; + this.fullClazzName = fullClazzName; + this.methodName = methodName; + this.userClassName = userClassName; + this.truffleLanguageFullClazzName = truffleLanguageFullClazzName; + } + + final void generate(List generatedClasses) { + try { + generatedClasses.add(fullClazzName); + JavaFileObject file = processingEnv.getFiler().createSourceFile(fullClazzName, e); + Writer w = file.openWriter(); + w.append("package ").append(pkg).append(";\n"); + appendImports(w); + + w.append("abstract class ").append(clazzName).append(" extends Node {\n"); + appendAbstractMethods(w); + appendTargetableNode(w); + appendRootNode(w); + appendRootNodeFactory(w); + + w.append("}\n"); + w.close(); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + + final List getAccessMethods() { + List methods = new ArrayList<>(); + for (Element m : e.getEnclosedElements()) { + if (m.getKind() != ElementKind.METHOD) { + continue; + } + if (!m.getSimpleName().contentEquals(ACCESS_METHOD_NAME)) { + continue; + } + ExecutableElement method = (ExecutableElement) m; + methods.add(method); + } + return methods; + } + + void appendImports(Writer w) throws IOException { + w.append("import com.oracle.truffle.api.nodes.Node;").append("\n"); + w.append("import com.oracle.truffle.api.frame.VirtualFrame;").append("\n"); + w.append("import com.oracle.truffle.api.dsl.Specialization;").append("\n"); + w.append("import com.oracle.truffle.api.nodes.RootNode;").append("\n"); + w.append("import com.oracle.truffle.api.TruffleLanguage;").append("\n"); + w.append("import com.oracle.truffle.api.interop.ForeignAccess;").append("\n"); + w.append("import com.oracle.truffle.api.dsl.UnsupportedSpecializationException;").append("\n"); + w.append("import com.oracle.truffle.api.interop.UnsupportedTypeException;").append("\n"); + } + + abstract int getParameterCount(); + + void appendAbstractMethods(Writer w) throws IOException { + for (ExecutableElement method : getAccessMethods()) { + w.append(" protected abstract ").append(method.getReturnType().toString()).append(" ").append(ACCESS_METHOD_NAME); + w.append("("); + final List params = method.getParameters(); + String sep = ""; + for (VariableElement p : params) { + w.append(sep).append(p.asType().toString()).append(" ").append(p.getSimpleName()); + sep = ", "; + } + w.append(");\n"); + } + } + + abstract String checkSignature(ExecutableElement method); + + abstract String getTargetableNodeName(); + + void appendTargetableNode(Writer w) throws IOException { + String sep = ""; + w.append(" protected abstract static class ").append(getTargetableNodeName()).append(" extends Node {\n"); + w.append("\n"); + w.append(" @Child ").append(clazzName).append(" child = new ").append(userClassName).append("();\n"); + w.append("\n"); + w.append(" public abstract Object executeWithTarget(VirtualFrame frame, "); + sep = ""; + for (int i = 0; i < getParameterCount() - 1; i++) { + w.append(sep).append("Object ").append("o").append(String.valueOf(i)); + sep = ", "; + } + w.append(");\n"); + + for (ExecutableElement method : getAccessMethods()) { + final List params = method.getParameters(); + + w.append(" @Specialization\n"); + w.append(" protected Object ").append(ACCESS_METHOD_NAME).append("WithTarget"); + w.append("("); + + sep = ""; + for (VariableElement p : params) { + w.append(sep).append(p.asType().toString()).append(" ").append(p.getSimpleName()); + sep = ", "; + } + w.append(") {\n"); + w.append(" return child.").append(ACCESS_METHOD_NAME).append("("); + sep = ""; + for (VariableElement p : params) { + w.append(sep).append(p.getSimpleName()); + sep = ", "; + } + w.append(");\n"); + w.append(" }\n"); + } + w.append(" }\n"); + } + + abstract void appendRootNode(Writer w) throws IOException; + + abstract String getRootNodeName(); + + void appendRootNodeFactory(Writer w) throws IOException { + w.append(" public static RootNode createRoot(Class> language) {\n"); + w.append(" return new ").append(getRootNodeName()).append("(language);\n"); + w.append(" }\n"); + + } + + String getRootNodeFactoryInvokation() { + return ((TypeElement) e).asType().toString() + ".createRoot(" + truffleLanguageFullClazzName + ".class)"; + } + + @Override + public String toString() { + return clazzName; + } + + } + + // IsNull IsExecutable IsBoxed HasSize + // GetSize Unbox + private static class UnaryGenerator extends MessageGenerator { + + private static final int NUMBER_OF_UNARY = 2; // VirtualFrame frame, TruffleObject receiver + private final String targetableUnaryNode; + private final String unaryRootNode; + + UnaryGenerator(ProcessingEnvironment processingEnv, Element e, String pkg, String clazzName, String fullClazzName, String methodName, String userClassName, String truffleLanguageFullClazzName) { + super(processingEnv, e, pkg, clazzName, fullClazzName, methodName, userClassName, truffleLanguageFullClazzName); + this.targetableUnaryNode = (new StringBuilder(methodName)).replace(0, 1, methodName.substring(0, 1).toUpperCase()).append("Node").insert(0, "Targetable").toString(); + this.unaryRootNode = (new StringBuilder(methodName)).replace(0, 1, methodName.substring(0, 1).toUpperCase()).append("RootNode").toString(); + } + + @Override + int getParameterCount() { + return NUMBER_OF_UNARY; + } + + @Override + String getTargetableNodeName() { + return targetableUnaryNode; + } + + @Override + void appendRootNode(Writer w) throws IOException { + w.append(" private final static class ").append(unaryRootNode).append(" extends RootNode {\n"); + w.append(" protected ").append(unaryRootNode).append("(Class> language) {\n"); + w.append(" super(language, null, null);\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" @Child private ").append(targetableUnaryNode).append(" node = ").append(pkg).append(".").append(clazzName).append("Factory.").append(targetableUnaryNode).append( + "Gen.create();\n"); + w.append("\n"); + w.append(" @Override\n"); + w.append(" public Object execute(VirtualFrame frame) {\n"); + w.append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); + w.append(" try {\n"); + w.append(" return node.executeWithTarget(frame, receiver);\n"); + w.append(" } catch (UnsupportedSpecializationException e) {\n"); + w.append(" throw UnsupportedTypeException.raise(e.getSuppliedValues());\n"); + w.append(" }\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" }\n"); + } + + @Override + String getRootNodeName() { + return unaryRootNode; + } + + @Override + String checkSignature(ExecutableElement method) { + final List params = method.getParameters(); + if (params.size() != NUMBER_OF_UNARY) { + return ACCESS_METHOD_NAME + " method has to have " + getParameterCount() + " arguments"; + } + if (!params.get(0).asType().toString().equals(VirtualFrame.class.getName())) { + return "The first argument of " + ACCESS_METHOD_NAME + " must be of type " + VirtualFrame.class.getName() + "- but is " + params.get(0).asType().toString(); + } + return null; + } + } + + private static class ExecuteGenerator extends MessageGenerator { + + private final int numberOfArguments; + // Execute: VirtualFrame frame, TruffleObject receiver, Object[] args + // Invoke: VirtualFrame frame, TruffleObject receiver, String identifier, Object[] args + // New: VirtualFrame frame, TruffleObject receiver, Object[] args + private final String targetableExecuteNode; + private final String executeRootNode; + + ExecuteGenerator(ProcessingEnvironment processingEnv, Element e, String pkg, String clazzName, String fullClazzName, String methodName, String userClassName, + String truffleLanguageFullClazzName) { + super(processingEnv, e, pkg, clazzName, fullClazzName, methodName, userClassName, truffleLanguageFullClazzName); + this.targetableExecuteNode = (new StringBuilder(methodName)).replace(0, 1, methodName.substring(0, 1).toUpperCase()).append("Node").insert(0, "Targetable").toString(); + this.executeRootNode = (new StringBuilder(methodName)).replace(0, 1, methodName.substring(0, 1).toUpperCase()).append("RootNode").toString(); + if (Message.createExecute(0).toString().equalsIgnoreCase(methodName)) { + numberOfArguments = 3; + } else if (Message.createInvoke(0).toString().equalsIgnoreCase(methodName)) { + numberOfArguments = 4; + } else if (Message.createNew(0).toString().equalsIgnoreCase(methodName)) { + numberOfArguments = 3; + } else { + throw new AssertionError(); + } + } + + @Override + void appendImports(Writer w) throws IOException { + super.appendImports(w); + w.append("import java.util.List;").append("\n"); + w.append("import com.oracle.truffle.api.nodes.ExplodeLoop;").append("\n"); + } + + @Override + int getParameterCount() { + return numberOfArguments; + } + + @Override + String getTargetableNodeName() { + return targetableExecuteNode; + } + + @Override + void appendRootNode(Writer w) throws IOException { + w.append(" private final static class ").append(executeRootNode).append(" extends RootNode {\n"); + w.append(" protected ").append(executeRootNode).append("(Class> language) {\n"); + w.append(" super(language, null, null);\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" @Child private ").append(targetableExecuteNode).append(" node = ").append(pkg).append(".").append(clazzName).append("Factory.").append(targetableExecuteNode).append( + "Gen.create();\n"); + w.append("\n"); + w.append(" @Override\n"); + w.append(" @ExplodeLoop\n"); + w.append(" public Object execute(VirtualFrame frame) {\n"); + w.append(" try {\n"); + w.append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); + if (Message.createInvoke(0).toString().equalsIgnoreCase(methodName)) { + w.append(" List arguments = ForeignAccess.getArguments(frame);\n"); + w.append(" Object identifier = arguments.get(0);\n"); + w.append(" Object[] args = new Object[arguments.size() - 1];\n"); + w.append(" for (int i = 0; i < arguments.size() - 1; i++) {\n"); + w.append(" args[i] = arguments.get(i + 1);\n"); + w.append(" }\n"); + w.append(" return node.executeWithTarget(frame, receiver, identifier, args);\n"); + } else { + w.append(" List arguments = ForeignAccess.getArguments(frame);\n"); + w.append(" Object[] args = new Object[arguments.size()];\n"); + w.append(" for (int i = 0; i < arguments.size(); i++) {\n"); + w.append(" args[i] = arguments.get(i);\n"); + w.append(" }\n"); + w.append(" return node.executeWithTarget(frame, receiver, args);\n"); + + } + w.append(" } catch (UnsupportedSpecializationException e) {\n"); + w.append(" throw UnsupportedTypeException.raise(e.getSuppliedValues());\n"); + w.append(" }\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" }\n"); + } + + @Override + String getRootNodeName() { + return executeRootNode; + } + + @Override + String checkSignature(ExecutableElement method) { + final List params = method.getParameters(); + if (params.size() != numberOfArguments) { + return ACCESS_METHOD_NAME + " method has to have " + getParameterCount() + " arguments"; + } + if (!params.get(0).asType().toString().equals(VirtualFrame.class.getName())) { + return "The first argument must be a " + VirtualFrame.class.getName() + "- but is " + params.get(0).asType().toString(); + } + if (Message.createInvoke(0).toString().equalsIgnoreCase(methodName)) { + if (!params.get(2).asType().toString().equals(String.class.getName())) { + return "The third argument must be a " + String.class.getName() + "- but is " + params.get(2).asType().toString(); + } + } + VariableElement variableElement = params.get(params.size() - 1); + if (!variableElement.asType().toString().equals("java.lang.Object[]")) { + return "The last argument must be the arguments array. Required type: java.lang.Object[]" + "- but is " + params.get(params.size() - 1).asType().toString(); + } + return null; + } + + } + + private static class ReadGenerator extends MessageGenerator { + + private static final int NUMBER_OF_READ = 3; // VirtualFrame frame, TruffleObject receiver, + // Object identifier + private static final String TARGETABLE_READ_NODE = "TargetableReadNode"; + private static final String READ_ROOT_NODE = "ReadRootNode"; + + ReadGenerator(ProcessingEnvironment processingEnv, Element e, String pkg, String clazzName, String fullClazzName, String methodName, String userClassName, String truffleLanguageFullClazzName) { + super(processingEnv, e, pkg, clazzName, fullClazzName, methodName, userClassName, truffleLanguageFullClazzName); + } + + @Override + void appendRootNode(Writer w) throws IOException { + w.append(" private final static class ").append(READ_ROOT_NODE).append(" extends RootNode {\n"); + w.append(" protected ").append(READ_ROOT_NODE).append("(Class> language) {\n"); + w.append(" super(language, null, null);\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" @Child private ").append(TARGETABLE_READ_NODE).append(" node = ").append(pkg).append(".").append(clazzName).append("Factory.").append(TARGETABLE_READ_NODE).append( + "Gen.create();\n"); + w.append("\n"); + w.append(" @Override\n"); + w.append(" public Object execute(VirtualFrame frame) {\n"); + w.append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); + w.append(" Object identifier = ForeignAccess.getArguments(frame).get(0);\n"); + w.append(" try {\n"); + w.append(" return node.executeWithTarget(frame, receiver, identifier);\n"); + w.append(" } catch (UnsupportedSpecializationException e) {\n"); + w.append(" throw UnsupportedTypeException.raise(e.getSuppliedValues());\n"); + w.append(" }\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" }\n"); + } + + @Override + int getParameterCount() { + return NUMBER_OF_READ; + } + + @Override + String getTargetableNodeName() { + return TARGETABLE_READ_NODE; + } + + @Override + String getRootNodeName() { + return READ_ROOT_NODE; + } + + @Override + String checkSignature(ExecutableElement method) { + final List params = method.getParameters(); + if (params.size() != NUMBER_OF_READ) { + return ACCESS_METHOD_NAME + " method has to have " + getParameterCount() + " arguments"; + } + if (!params.get(0).asType().toString().equals(VirtualFrame.class.getName())) { + return "The first argument must be a " + VirtualFrame.class.getName() + "- but is " + params.get(0).asType().toString(); + } + return null; + } + + } + + private static class WriteGenerator extends MessageGenerator { + + private static final int NUMBER_OF_WRITE = 4; // VirtualFrame frame, TruffleObject receiver, + // Object identifier, Object value + private static final String TARGETABLE_WRITE_NODE = "TargetableWriteNode"; + private static final String WRITE_ROOT_NODE = "WriteRootNode"; + + WriteGenerator(ProcessingEnvironment processingEnv, Element e, String pkg, String clazzName, String fullClazzName, String methodName, String userClassName, String truffleLanguageFullClazzName) { + super(processingEnv, e, pkg, clazzName, fullClazzName, methodName, userClassName, truffleLanguageFullClazzName); + } + + @Override + void appendRootNode(Writer w) throws IOException { + w.append(" private final static class ").append(WRITE_ROOT_NODE).append(" extends RootNode {\n"); + w.append(" protected ").append(WRITE_ROOT_NODE).append("(Class> language) {\n"); + w.append(" super(language, null, null);\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" @Child private ").append(TARGETABLE_WRITE_NODE).append(" node = ").append(pkg).append(".").append(clazzName).append("Factory.").append(TARGETABLE_WRITE_NODE).append( + "Gen.create();\n"); + w.append("\n"); + w.append(" @Override\n"); + w.append(" public Object execute(VirtualFrame frame) {\n"); + w.append(" Object receiver = ForeignAccess.getReceiver(frame);\n"); + w.append(" Object identifier = ForeignAccess.getArguments(frame).get(0);\n"); + w.append(" Object value = ForeignAccess.getArguments(frame).get(1);\n"); + w.append(" try {\n"); + w.append(" return node.executeWithTarget(frame, receiver, identifier, value);\n"); + w.append(" } catch (UnsupportedSpecializationException e) {\n"); + w.append(" throw UnsupportedTypeException.raise(e.getSuppliedValues());\n"); + w.append(" }\n"); + w.append(" }\n"); + w.append("\n"); + w.append(" }\n"); + } + + @Override + int getParameterCount() { + return NUMBER_OF_WRITE; + } + + @Override + String getTargetableNodeName() { + return TARGETABLE_WRITE_NODE; + } + + @Override + String getRootNodeName() { + return WRITE_ROOT_NODE; + } + + @Override + String checkSignature(ExecutableElement method) { + final List params = method.getParameters(); + if (params.size() != NUMBER_OF_WRITE) { + return ACCESS_METHOD_NAME + " method has to have " + getParameterCount() + " arguments"; + } + if (!params.get(0).asType().toString().equals(VirtualFrame.class.getName())) { + return "The first argument must be a " + VirtualFrame.class.getName() + "- but is " + params.get(0).asType().toString(); + } + return null; + } + + } + + private static class FactoryGenerator { + + private final String receiverTypeClass; + private final String packageName; + private final String className; + private final JavaFileObject factoryFile; + + private final Map messageHandlers; + + public FactoryGenerator(String packageName, String className, String receiverTypeClass, JavaFileObject factoryFile) { + this.receiverTypeClass = receiverTypeClass; + this.className = className; + this.packageName = packageName; + this.factoryFile = factoryFile; + this.messageHandlers = new HashMap<>(); + } + + public void addMessageHandler(Message message, String factoryMethodInvocation) { + messageHandlers.put(message, factoryMethodInvocation); + } + + public void generate() { + try { + Writer w = factoryFile.openWriter(); + w.append("package ").append(packageName).append(";\n"); + appendImports(w); + w.append("final class ").append(className).append(" implements Factory10, Factory {\n"); + + appendSingelton(w); + appendPrivateConstructor(w); + appendFactoryCanHandle(w); + + appendFactory10accessIsNull(w); + appendFactory10accessIsExecutable(w); + appendFactory10accessIsBoxed(w); + appendFactory10accessHasSize(w); + appendFactory10accessGetSize(w); + appendFactory10accessUnbox(w); + appendFactory10accessRead(w); + appendFactory10accessWrite(w); + appendFactory10accessExecute(w); + appendFactory10accessInvoke(w); + appendFactory10accessNew(w); + appendFactoryAccessMessage(w); + + w.append("}\n"); + w.close(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + private static void appendImports(Writer w) throws IOException { + w.append("import com.oracle.truffle.api.interop.UnsupportedMessageException;").append("\n"); + w.append("import com.oracle.truffle.api.interop.ForeignAccess.Factory10;").append("\n"); + w.append("import com.oracle.truffle.api.interop.ForeignAccess.Factory;").append("\n"); + w.append("import com.oracle.truffle.api.interop.Message;").append("\n"); + w.append("import com.oracle.truffle.api.interop.ForeignAccess;").append("\n"); + w.append("import com.oracle.truffle.api.interop.TruffleObject;").append("\n"); + w.append("import com.oracle.truffle.api.CallTarget;").append("\n"); + w.append("import com.oracle.truffle.api.Truffle;").append("\n"); + w.append("import com.oracle.truffle.api.nodes.RootNode;").append("\n"); + } + + private void appendSingelton(Writer w) throws IOException { + w.append(" public static final ForeignAccess ACCESS = ForeignAccess.create(null, new ").append(className).append("());").append("\n"); + w.append("\n"); + } + + private void appendPrivateConstructor(Writer w) throws IOException { + w.append(" private ").append(className).append("(){}").append("\n"); + w.append("\n"); + } + + private void appendFactoryCanHandle(Writer w) throws IOException { + w.append(" public boolean canHandle(TruffleObject obj) {").append("\n"); + w.append(" return ").append(receiverTypeClass).append(".isInstance(obj);").append("\n"); + w.append(" }").append("\n"); + w.append("\n"); + } + + private void appendFactory10accessIsNull(Writer w) throws IOException { + w.append(" public CallTarget accessIsNull() {").append("\n"); + appendOptionalDefaultHandlerBody(w, Message.IS_NULL); + w.append(" }").append("\n"); + } + + private void appendFactory10accessIsExecutable(Writer w) throws IOException { + w.append(" public CallTarget accessIsExecutable() {").append("\n"); + appendOptionalDefaultHandlerBody(w, Message.IS_EXECUTABLE); + w.append(" }").append("\n"); + } + + private void appendFactory10accessIsBoxed(Writer w) throws IOException { + w.append(" public CallTarget accessIsBoxed() {").append("\n"); + appendOptionalDefaultHandlerBody(w, Message.IS_BOXED); + w.append(" }").append("\n"); + } + + private void appendFactory10accessHasSize(Writer w) throws IOException { + w.append(" public CallTarget accessHasSize() {").append("\n"); + appendOptionalDefaultHandlerBody(w, Message.HAS_SIZE); + w.append(" }").append("\n"); + } + + private void appendOptionalDefaultHandlerBody(Writer w, Message message) throws IOException { + if (!messageHandlers.containsKey(message)) { + w.append(" return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));").append("\n"); + } else { + w.append(" return Truffle.getRuntime().createCallTarget(").append(messageHandlers.get(message)).append(");").append("\n"); + } + } + + private void appendFactory10accessGetSize(Writer w) throws IOException { + w.append(" public CallTarget accessGetSize() {").append("\n"); + appendOptionalHandlerBody(w, Message.GET_SIZE, "Message.GET_SIZE"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessUnbox(Writer w) throws IOException { + w.append(" public CallTarget accessUnbox() {").append("\n"); + appendOptionalHandlerBody(w, Message.UNBOX, "Message.UNBOX"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessRead(Writer w) throws IOException { + w.append(" public CallTarget accessRead() {").append("\n"); + appendOptionalHandlerBody(w, Message.READ, "Message.READ"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessWrite(Writer w) throws IOException { + w.append(" public CallTarget accessWrite() {").append("\n"); + appendOptionalHandlerBody(w, Message.WRITE, "Message.WRITE"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessExecute(Writer w) throws IOException { + w.append(" public CallTarget accessExecute(int argumentsLength) {").append("\n"); + appendOptionalHandlerBody(w, Message.createExecute(0), "Message.createExecute(argumentsLength)"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessInvoke(Writer w) throws IOException { + w.append(" public CallTarget accessInvoke(int argumentsLength) {").append("\n"); + appendOptionalHandlerBody(w, Message.createInvoke(0), "Message.createInvoke(argumentsLength)"); + w.append(" }").append("\n"); + } + + private void appendFactory10accessNew(Writer w) throws IOException { + w.append(" public CallTarget accessNew(int argumentsLength) {").append("\n"); + appendOptionalHandlerBody(w, Message.createNew(0), "Message.createNew(argumentsLength)"); + w.append(" }").append("\n"); + } + + private void appendOptionalHandlerBody(Writer w, Message message, String messageObjectAsString) throws IOException { + if (!messageHandlers.containsKey(message)) { + w.append(" throw UnsupportedMessageException.raise(").append(messageObjectAsString).append(");").append("\n"); + } else { + w.append(" return com.oracle.truffle.api.Truffle.getRuntime().createCallTarget(").append(messageHandlers.get(message)).append(");").append("\n"); + } + } + + private void appendFactoryAccessMessage(Writer w) throws IOException { + w.append(" public CallTarget accessMessage(Message unknown) {").append("\n"); + for (Message m : messageHandlers.keySet()) { + w.append(" if (Message.valueOf(\"").append(m.toString()).append("\").getClass().isInstance(unknown)) {").append("\n"); + w.append(" return Truffle.getRuntime().createCallTarget(").append(messageHandlers.get(m)).append(");").append("\n"); + w.append(" }").append("\n"); + } + w.append(" throw UnsupportedMessageException.raise(unknown);").append("\n"); + w.append(" }").append("\n"); + } + + @Override + public String toString() { + return "FactoryGenerator: " + className; + } + } +} diff --git a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java index 87017086b25e..1f86558670bf 100644 --- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java +++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java @@ -47,9 +47,10 @@ import org.junit.After; +import static org.junit.Assert.assertTrue; + import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.assertTrue; /** * This is the way to verify your language implementation is compatible. @@ -218,6 +219,12 @@ protected String complexCopy() { return null; } + @Override + protected String complexAddWithMethod() { + // skip these tests; SL doesn't have methods + return null; + } + @Override protected String complexSumReal() { // skip these tests; SL doesn't have arrays diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java index 511987ad374e..deee2d42dd52 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java @@ -48,6 +48,8 @@ import java.nio.file.Path; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives; @@ -60,8 +62,11 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.instrument.Visualizer; import com.oracle.truffle.api.instrument.WrapperNode; +import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.nodes.GraphPrintVisitor; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; @@ -114,8 +119,6 @@ import com.oracle.truffle.sl.runtime.SLFunction; import com.oracle.truffle.sl.runtime.SLFunctionRegistry; import com.oracle.truffle.sl.runtime.SLNull; -import java.util.Map; -import java.util.WeakHashMap; /** * SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as @@ -453,7 +456,11 @@ public Object execute(VirtualFrame frame) { Object[] arguments = frame.getArguments(); if (oneAndCnt == 1 && (arguments.length > 0 || node != null)) { Node callNode = Message.createExecute(arguments.length).createNode(); - return ForeignAccess.execute(callNode, frame, oneAndOnly, arguments); + try { + return ForeignAccess.sendExecute(callNode, frame, oneAndOnly, arguments); + } catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e) { + return null; + } } return null; } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java index f1b945c6491d..a933ba023504 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLReadPropertyNode.java @@ -47,6 +47,8 @@ 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.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.object.DynamicObject; @@ -55,6 +57,7 @@ import com.oracle.truffle.sl.nodes.interop.SLForeignToSLTypeNode; import com.oracle.truffle.sl.nodes.interop.SLForeignToSLTypeNodeGen; import com.oracle.truffle.sl.runtime.SLContext; +import com.oracle.truffle.sl.runtime.SLNull; /** * The node for accessing a property of an object. When executed, this node first evaluates the @@ -88,8 +91,12 @@ public Object doForeignObject(VirtualFrame frame, TruffleObject object) { this.foreignRead = insert(Message.READ.createNode()); this.toSLType = insert(SLForeignToSLTypeNodeGen.create(getSourceSection(), null)); } - Object result = ForeignAccess.execute(foreignRead, frame, object, new Object[]{propertyName}); - Object slValue = toSLType.executeWithTarget(frame, result); - return slValue; + try { + Object result = ForeignAccess.sendRead(foreignRead, frame, object, propertyName); + Object slValue = toSLType.executeWithTarget(frame, result); + return slValue; + } catch (UnknownIdentifierException | UnsupportedMessageException e) { + return SLNull.SINGLETON; + } } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java index acfcfa6181c9..32fe0879c103 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/access/SLWritePropertyNode.java @@ -48,12 +48,16 @@ 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.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.runtime.SLContext; +import com.oracle.truffle.sl.runtime.SLNull; /** * The node for setting a property of an object. When executed, this node first evaluates the value @@ -90,6 +94,10 @@ public Object doForeignObject(VirtualFrame frame, TruffleObject object, Object v CompilerDirectives.transferToInterpreterAndInvalidate(); this.foreignWrite = insert(Message.WRITE.createNode()); } - return ForeignAccess.execute(foreignWrite, frame, object, new Object[]{propertyName, value}); + try { + return ForeignAccess.sendWrite(foreignWrite, frame, object, propertyName, value); + } catch (UnknownIdentifierException | UnsupportedTypeException | UnsupportedMessageException e) { + return SLNull.SINGLETON; + } } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java index ce2849b183cd..7747e842827c 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLInvokeNode.java @@ -45,9 +45,12 @@ 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.ArityException; 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.interop.UnsupportedMessageException; +import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; @@ -55,6 +58,7 @@ import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.runtime.SLContext; import com.oracle.truffle.sl.runtime.SLFunction; +import com.oracle.truffle.sl.runtime.SLNull; /** * The node for function invocation in SL. Since SL has first class functions, the @@ -113,7 +117,11 @@ protected Object executeGeneric(VirtualFrame frame, TruffleObject function) { if (crossLanguageCall == null) { crossLanguageCall = insert(Message.createExecute(argumentValues.length).createNode()); } - Object res = ForeignAccess.execute(crossLanguageCall, frame, function, argumentValues); - return SLContext.fromForeignValue(res); + try { + Object res = ForeignAccess.sendExecute(crossLanguageCall, frame, function, argumentValues); + return SLContext.fromForeignValue(res); + } catch (ArityException | UnsupportedTypeException | UnsupportedMessageException e) { + return SLNull.SINGLETON; + } } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignInvokeNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignInvokeNode.java new file mode 100644 index 000000000000..c0ac75e23aee --- /dev/null +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignInvokeNode.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.truffle.sl.nodes.interop; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.sl.SLLanguage; +import com.oracle.truffle.sl.nodes.call.SLDispatchNode; +import com.oracle.truffle.sl.nodes.call.SLDispatchNodeGen; +import com.oracle.truffle.sl.runtime.SLContext; +import com.oracle.truffle.sl.runtime.SLFunction; +import com.oracle.truffle.sl.runtime.SLObjectType; + +@AcceptMessage(value = "INVOKE", receiverType = SLObjectType.class, language = SLLanguage.class) +public final class SLForeignInvokeNode extends SLInvokeBaseNode { + + @Child private SLDispatchNode dispatch = SLDispatchNodeGen.create(); + + @Override + public Object access(VirtualFrame frame, DynamicObject receiver, String name, Object[] arguments) { + Object property = receiver.get(name); + if (property instanceof SLFunction) { + SLFunction function = (SLFunction) property; + Object[] arr = new Object[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + arr[i] = SLContext.fromForeignValue(arguments[i]); + } + Object result = dispatch.executeDispatch(frame, function, arr); + return result; + } else { + throw UnknownIdentifierException.raise(name); + } + } +} diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java index 8732a6911b73..cb3dfbc84aaf 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignReadNode.java @@ -42,35 +42,31 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.AcceptMessage; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Property; import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.access.SLReadPropertyCacheNode; import com.oracle.truffle.sl.nodes.access.SLReadPropertyCacheNodeGen; +import com.oracle.truffle.sl.runtime.SLObjectType; -public class SLForeignReadNode extends RootNode { +@AcceptMessage(value = "READ", receiverType = SLObjectType.class, language = SLLanguage.class) +public final class SLForeignReadNode extends SLReadBaseNode { @Child private SLMonomorphicNameReadNode read; - public SLForeignReadNode() { - super(SLLanguage.class, null, null); - } - @Override - public Object execute(VirtualFrame frame) { + public Object access(VirtualFrame frame, DynamicObject receiver, String name) { if (read == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - String name = (String) ForeignAccess.getArguments(frame).get(0); read = insert(new SLMonomorphicNameReadNode(name)); } - return read.execute(frame); + return read.execute(receiver, name); } private abstract static class SLReadNode extends Node { - abstract Object execute(VirtualFrame frame); + abstract Object execute(DynamicObject receiver, String name); } private static final class SLMonomorphicNameReadNode extends SLReadNode { @@ -84,22 +80,19 @@ private static final class SLMonomorphicNameReadNode extends SLReadNode { } @Override - Object execute(VirtualFrame frame) { - if (name.equals(ForeignAccess.getArguments(frame).get(0))) { - return readPropertyCacheNode.executeObject((DynamicObject) ForeignAccess.getReceiver(frame)); + Object execute(DynamicObject receiver, String n) { + if (this.name.equals(n)) { + return readPropertyCacheNode.executeObject(receiver); } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - return this.replace(new SLPolymorphicNameReadNode()).execute(frame); + return this.replace(new SLPolymorphicNameReadNode()).execute(receiver, n); } } } private static final class SLPolymorphicNameReadNode extends SLReadNode { - @Override - Object execute(VirtualFrame frame) { - String name = (String) ForeignAccess.getArguments(frame).get(0); - DynamicObject obj = (DynamicObject) ForeignAccess.getReceiver(frame); + Object execute(DynamicObject obj, String name) { Property property = obj.getShape().getProperty(name); return obj.get(property.getKey()); } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java index abd1da9a0f3f..67427c10f0a1 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignToSLTypeNode.java @@ -47,11 +47,13 @@ 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.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.nodes.SLTargetableNode; import com.oracle.truffle.sl.runtime.SLContext; +import com.oracle.truffle.sl.runtime.SLNull; @NodeChild(type = SLExpressionNode.class) public abstract class SLForeignToSLTypeNode extends SLTargetableNode { @@ -98,13 +100,16 @@ protected final boolean isBoxedPrimitive(VirtualFrame frame, TruffleObject objec CompilerDirectives.transferToInterpreterAndInvalidate(); isBoxed = insert(Message.IS_BOXED.createNode()); } - return (boolean) ForeignAccess.execute(isBoxed, frame, object); + return ForeignAccess.sendIsBoxed(isBoxed, frame, object); } protected final Object doUnbox(VirtualFrame frame, TruffleObject value) { initializeUnbox(); - Object object = ForeignAccess.execute(unbox, frame, value); - return object; + try { + return ForeignAccess.sendUnbox(unbox, frame, value); + } catch (UnsupportedMessageException e) { + return SLNull.SINGLETON; + } } @Child private Node unbox; diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java index c8c7d75e0c12..18049e76082d 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/interop/SLForeignWriteNode.java @@ -42,59 +42,53 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.AcceptMessage; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Property; import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.access.SLWritePropertyCacheNode; import com.oracle.truffle.sl.nodes.access.SLWritePropertyCacheNodeGen; +import com.oracle.truffle.sl.runtime.SLObjectType; -public class SLForeignWriteNode extends RootNode { +@AcceptMessage(value = "WRITE", receiverType = SLObjectType.class, language = SLLanguage.class) +public final class SLForeignWriteNode extends SLWriteBaseNode { @Child private SLMonomorphicNameWriteNode write; - public SLForeignWriteNode() { - super(SLLanguage.class, null, null); - } - @Override - public Object execute(VirtualFrame frame) { + public Object access(VirtualFrame frame, DynamicObject receiver, String name, Object value) { if (write == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - String name = (String) ForeignAccess.getArguments(frame).get(0); write = insert(new SLMonomorphicNameWriteNode(name)); } - return write.execute(frame); + return write.execute(receiver, name, value); } private abstract static class SLWriteNode extends Node { @Child protected SLForeignToSLTypeNode toSLType = SLForeignToSLTypeNodeGen.create(getSourceSection(), null); - abstract Object execute(VirtualFrame frame); + abstract Object execute(DynamicObject receiver, String name, Object value); } private static final class SLMonomorphicNameWriteNode extends SLWriteNode { - private final String name; + private final String cachedName; @Child private SLWritePropertyCacheNode writePropertyCacheNode; SLMonomorphicNameWriteNode(String name) { - this.name = name; + this.cachedName = name; this.writePropertyCacheNode = SLWritePropertyCacheNodeGen.create(name); } @Override - Object execute(VirtualFrame frame) { - if (name.equals(ForeignAccess.getArguments(frame).get(0))) { - Object value = toSLType.executeWithTarget(frame, ForeignAccess.getArguments(frame).get(1)); - DynamicObject receiver = (DynamicObject) ForeignAccess.getReceiver(frame); + Object execute(DynamicObject receiver, String name, Object value) { + if (this.cachedName.equals(name)) { writePropertyCacheNode.executeObject(receiver, value); return receiver; } else { CompilerDirectives.transferToInterpreterAndInvalidate(); - return this.replace(new SLPolymorphicNameWriteNode()).execute(frame); + return this.replace(new SLPolymorphicNameWriteNode()).execute(receiver, name, value); } } } @@ -102,12 +96,9 @@ Object execute(VirtualFrame frame) { private static final class SLPolymorphicNameWriteNode extends SLWriteNode { @Override - Object execute(VirtualFrame frame) { - String name = (String) ForeignAccess.getArguments(frame).get(0); - DynamicObject obj = (DynamicObject) ForeignAccess.getReceiver(frame); - Property property = obj.getShape().getProperty(name); - Object value = toSLType.executeWithTarget(frame, ForeignAccess.getArguments(frame).get(0)); - return obj.set(property.getKey(), value); + Object execute(DynamicObject receiver, String name, Object value) { + Property property = receiver.getShape().getProperty(name); + return receiver.set(property.getKey(), value); } } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java index eb28bfa6d88e..112cd1a065b9 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLFunctionForeignAccess.java @@ -50,6 +50,7 @@ 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.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.sl.SLLanguage; import com.oracle.truffle.sl.nodes.call.SLDispatchNode; @@ -82,7 +83,7 @@ public CallTarget accessMessage(Message tree) { } else if (Message.IS_BOXED.equals(tree)) { return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); + throw UnsupportedMessageException.raise(tree); } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java index 328fe81248cb..534c2e77639c 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLObjectType.java @@ -40,127 +40,19 @@ */ package com.oracle.truffle.sl.runtime; -import static com.oracle.truffle.sl.runtime.SLContext.fromForeignValue; - -import java.util.List; - -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -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.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.ObjectType; -import com.oracle.truffle.sl.SLLanguage; -import com.oracle.truffle.sl.nodes.call.SLDispatchNode; -import com.oracle.truffle.sl.nodes.call.SLDispatchNodeGen; -import com.oracle.truffle.sl.nodes.interop.SLForeignReadNode; -import com.oracle.truffle.sl.nodes.interop.SLForeignWriteNode; -final class SLObjectType extends ObjectType implements ForeignAccess.Factory10, ForeignAccess.Factory { - private final ForeignAccess access; +public final class SLObjectType extends ObjectType { - public SLObjectType() { - this.access = ForeignAccess.create(null, this); + public static boolean isInstance(TruffleObject obj) { + return SLContext.isSLObject(obj); } @Override public ForeignAccess getForeignAccessFactory(DynamicObject obj) { - return access; - } - - @Override - public CallTarget accessIsNull() { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } - - @Override - public CallTarget accessIsExecutable() { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } - - @Override - public CallTarget accessIsBoxed() { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } - - @Override - public CallTarget accessHasSize() { - throw new UnsupportedOperationException(); - } - - @Override - public CallTarget accessGetSize() { - throw new UnsupportedOperationException(); - } - - @Override - public CallTarget accessUnbox() { - throw new UnsupportedOperationException(); - } - - @Override - public CallTarget accessRead() { - return Truffle.getRuntime().createCallTarget(new SLForeignReadNode()); + return SLObjectTypeForeign.ACCESS; } - - @Override - public CallTarget accessWrite() { - return Truffle.getRuntime().createCallTarget(new SLForeignWriteNode()); - } - - @Override - public CallTarget accessExecute(int argumentsLength) { - throw new UnsupportedOperationException(); - } - - @Override - public CallTarget accessInvoke(int argumentsLength) { - return Truffle.getRuntime().createCallTarget(new SLForeignInvokeRootNode()); - } - - @Override - public CallTarget accessNew(int argumentsLength) { - throw new UnsupportedOperationException(); - } - - @Override - public CallTarget accessMessage(Message unknown) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean canHandle(TruffleObject obj) { - return SLContext.isSLObject(obj); - } - - private static class SLForeignInvokeRootNode extends RootNode { - @Child private SLDispatchNode dispatch = SLDispatchNodeGen.create(); - - public SLForeignInvokeRootNode() { - super(SLLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - DynamicObject receiver = (DynamicObject) ForeignAccess.getReceiver(frame); - String name = (String) ForeignAccess.getArguments(frame).get(0); - Object property = receiver.get(name); - if (property instanceof SLFunction) { - SLFunction function = (SLFunction) property; - List args = ForeignAccess.getArguments(frame); - Object[] arr = new Object[args.size() - 1]; - for (int i = 1; i < args.size(); i++) { - arr[i - 1] = fromForeignValue(args.get(i)); - } - Object result = dispatch.executeDispatch(frame, function, arr); - return result; - } else { - throw new IllegalArgumentException(); - } - } - } - } diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexGetSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexGetSizeNode.java new file mode 100644 index 000000000000..bc90caf7eb29 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexGetSizeNode.java @@ -0,0 +1,37 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "GET_SIZE", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexGetSizeNode extends ComplexBaseGetSizeNode { + @Override + public Object access(VirtualFrame frame, ComplexNumber complex) { + return 2; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexHasSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexHasSizeNode.java new file mode 100644 index 000000000000..e6166232f984 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexHasSizeNode.java @@ -0,0 +1,37 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "HAS_SIZE", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexHasSizeNode extends ComplexBaseHasSizeNode { + @Override + public Object access(VirtualFrame frame, ComplexNumber complex) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexInvokeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexInvokeNode.java new file mode 100644 index 000000000000..995010f8f80c --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexInvokeNode.java @@ -0,0 +1,72 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.ArityException; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedTypeException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "INVOKE", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexInvokeNode extends ComplexBaseInvokeNode { + + private static final String ADD = "add"; + private static final String SUB = "sub"; + + @Override + public Object access(VirtualFrame frame, ComplexNumber complex, String identifier, Object[] arguments) { + if (arguments.length != 1) { + throw ArityException.raise(1, arguments.length); + } + if (!(arguments[0] instanceof ComplexNumber)) { + throw UnsupportedTypeException.raise(arguments); + } + ComplexNumber a = complex; + ComplexNumber b = (ComplexNumber) arguments[0]; + + switch (identifier) { + case ADD: + return add(a, b); + case SUB: + return sub(a, b); + default: + throw UnknownIdentifierException.raise(identifier); + } + } + + private static ComplexNumber add(ComplexNumber a, ComplexNumber b) { + a.set(ComplexNumber.REAL_IDENTIFIER, a.get(ComplexNumber.REAL_IDENTIFIER) + b.get(ComplexNumber.REAL_IDENTIFIER)); + a.set(ComplexNumber.IMAGINARY_IDENTIFIER, a.get(ComplexNumber.IMAGINARY_IDENTIFIER) + b.get(ComplexNumber.IMAGINARY_IDENTIFIER)); + return a; + } + + private static ComplexNumber sub(ComplexNumber a, ComplexNumber b) { + a.set(ComplexNumber.REAL_IDENTIFIER, a.get(ComplexNumber.REAL_IDENTIFIER) - b.get(ComplexNumber.REAL_IDENTIFIER)); + a.set(ComplexNumber.IMAGINARY_IDENTIFIER, a.get(ComplexNumber.IMAGINARY_IDENTIFIER) - b.get(ComplexNumber.IMAGINARY_IDENTIFIER)); + return a; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexIsNullNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexIsNullNode.java new file mode 100644 index 000000000000..9cb2e2cc99a4 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexIsNullNode.java @@ -0,0 +1,38 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "IS_NULL", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexIsNullNode extends ComplexBaseIsNullNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumber complex) { + return false; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumber.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumber.java index 9e8d8d912728..807c44871ad0 100644 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumber.java +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumber.java @@ -24,15 +24,8 @@ */ package com.oracle.truffle.tck; -import com.oracle.truffle.tck.impl.TckLanguage; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; -import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.RootNode; final class ComplexNumber implements TruffleObject { @@ -47,11 +40,12 @@ final class ComplexNumber implements TruffleObject { this.imag = imaginary; } + @Override public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new ComplexForeignAccessFactory()); + return ComplexNumberForeign.ACCESS; } - public void set(String identifier, double value) { + void set(String identifier, double value) { switch (identifier) { case REAL_IDENTIFIER: this.real = value; @@ -64,7 +58,7 @@ public void set(String identifier, double value) { } } - public double get(String identifier) { + double get(String identifier) { switch (identifier) { case REAL_IDENTIFIER: return this.real; @@ -75,57 +69,8 @@ public double get(String identifier) { } } - private static class ComplexForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof ComplexNumber; - } - - public CallTarget accessMessage(Message tree) { - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexReadNode()); - } else if (Message.WRITE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexWriteNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - } - - private static class ComplexWriteNode extends RootNode { - protected ComplexWriteNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumber complex = (ComplexNumber) ForeignAccess.getReceiver(frame); - String identifier = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - Number value = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(1)); - complex.set(identifier, value.doubleValue()); - return value; - } + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ComplexNumber; } - private static class ComplexReadNode extends RootNode { - protected ComplexReadNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumber complex = (ComplexNumber) ForeignAccess.getReceiver(frame); - String identifier = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - return complex.get(identifier); - } - - } } diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumberBEntry.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumberBEntry.java new file mode 100644 index 000000000000..f66d51ebb32c --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumberBEntry.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016, 2016, 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.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +class ComplexNumberBEntry implements TruffleObject { + + private final ComplexNumbersB numbers; + private final int index; + + public ComplexNumberBEntry(ComplexNumbersB numbers, int index) { + this.numbers = numbers; + this.index = index; + } + + public ForeignAccess getForeignAccess() { + return ComplexNumberBEntryForeign.ACCESS; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ComplexNumberBEntry; + } + + public int getIndex() { + return index; + } + + public ComplexNumbersB getNumbers() { + return numbers; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersA.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersA.java new file mode 100644 index 000000000000..e829d07ebbfe --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersA.java @@ -0,0 +1,51 @@ +/* + * 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.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +final class ComplexNumbersA implements TruffleObject { + + private final double[] data; + + ComplexNumbersA(double[] data) { + assert data.length % 2 == 0; + this.data = data; + } + + public double[] getData() { + return data; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ComplexNumbersA; + } + + public ForeignAccess getForeignAccess() { + return ComplexNumbersAForeign.ACCESS; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntry.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntry.java new file mode 100644 index 000000000000..4b0da19d81a8 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntry.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, 2016, 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.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +final class ComplexNumberAEntry implements TruffleObject { + + private final ComplexNumbersA numbers; + private final int index; + + public ComplexNumberAEntry(ComplexNumbersA numbers, int index) { + this.numbers = numbers; + this.index = index; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ComplexNumberAEntry; + } + + public ForeignAccess getForeignAccess() { + return ComplexNumberAEntryForeign.ACCESS; + } + + public ComplexNumbersA getNumbers() { + return numbers; + } + + public int getIndex() { + return index; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryReadNode.java new file mode 100644 index 000000000000..e6c9964813fc --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryReadNode.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = ComplexNumberAEntry.class, language = TckLanguage.class) +final class ComplexNumbersAEntryReadNode extends ComplexNumbersAEntryReadBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumberAEntry complexNumber, String name) { + if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { + return complexNumber.getNumbers().getData()[complexNumber.getIndex() * 2 + 1]; + } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { + return complexNumber.getNumbers().getData()[complexNumber.getIndex() * 2]; + } else { + throw UnknownIdentifierException.raise(name); + } + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryWriteNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryWriteNode.java new file mode 100644 index 000000000000..4dbf762342a2 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAEntryWriteNode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "WRITE", receiverType = ComplexNumberAEntry.class, language = TckLanguage.class) +final class ComplexNumbersAEntryWriteNode extends ComplexNumbersAEntryWriteBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumberAEntry complexNumber, String name, Number value) { + if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { + complexNumber.getNumbers().getData()[complexNumber.getIndex() * 2 + 1] = value.doubleValue(); + } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { + complexNumber.getNumbers().getData()[complexNumber.getIndex() * 2] = value.doubleValue(); + } else { + throw UnknownIdentifierException.raise(name); + } + return value; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAGetSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAGetSizeNode.java new file mode 100644 index 000000000000..01615ddae5f4 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAGetSizeNode.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "GET_SIZE", receiverType = ComplexNumbersA.class, language = TckLanguage.class) +final class ComplexNumbersAGetSizeNode extends ComplexNumbersAGetSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumbersA complexNumbers) { + return complexNumbers.getData().length / 2; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAHasSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAHasSizeNode.java new file mode 100644 index 000000000000..723034bd8f33 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAHasSizeNode.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "HAS_SIZE", receiverType = ComplexNumbersA.class, language = TckLanguage.class) +final class ComplexNumbersAHasSizeNode extends ComplexNumbersAHasSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumbersA complexNumbers) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAReadNode.java new file mode 100644 index 000000000000..22bc39f76af7 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAReadNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = ComplexNumbersA.class, language = TckLanguage.class) +final class ComplexNumbersAReadNode extends ComplexNumbersAReadBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumbersA complexNumbers, Number index) { + int idx = TckLanguage.checkBounds(index.intValue(), complexNumbers.getData().length / 2); + return new ComplexNumberAEntry(complexNumbers, idx); + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAWriteNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAWriteNode.java new file mode 100644 index 000000000000..20672a180c77 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersAWriteNode.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, 2016, 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.CompilerDirectives; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +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.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "WRITE", receiverType = ComplexNumbersA.class, language = TckLanguage.class) +final class ComplexNumbersAWriteNode extends ComplexNumbersAWriteBaseNode { + @Child private Node readReal; + @Child private Node readImag; + + @Override + public Object access(VirtualFrame frame, ComplexNumbersA complexNumbers, Number index, TruffleObject value) { + if (readReal == null || readImag == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + this.readReal = insert(Message.READ.createNode()); + this.readImag = insert(Message.READ.createNode()); + } + try { + Number realPart = TckLanguage.expectNumber(ForeignAccess.sendRead(readReal, frame, value, new Object[]{ComplexNumber.REAL_IDENTIFIER})); + Number imagPart = TckLanguage.expectNumber(ForeignAccess.sendRead(readImag, frame, value, new Object[]{ComplexNumber.IMAGINARY_IDENTIFIER})); + + int idx = TckLanguage.checkBounds(index.intValue(), complexNumbers.getData().length / 2); + + complexNumbers.getData()[idx * 2] = realPart.doubleValue(); + complexNumbers.getData()[idx * 2 + 1] = imagPart.doubleValue(); + return value; + } catch (UnknownIdentifierException | UnsupportedMessageException e) { + return null; + } + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersB.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersB.java new file mode 100644 index 000000000000..c08abf6c5c59 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersB.java @@ -0,0 +1,66 @@ +/* + * 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.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +final class ComplexNumbersB implements TruffleObject { + + private final double[] reals; + private final double[] imags; + + ComplexNumbersB(double[] reals, double[] imags) { + assert reals.length == imags.length; + this.reals = reals; + this.imags = imags; + } + + public double[] getData() { + double[] data = new double[reals.length * 2]; + for (int i = 0; i < reals.length; i++) { + data[i * 2] = reals[i]; + data[i * 2 + 1] = imags[i]; + } + return data; + } + + public double[] getImags() { + return imags; + } + + public double[] getReals() { + return reals; + } + + public ForeignAccess getForeignAccess() { + return ComplexNumbersAForeign.ACCESS; + } + + public static boolean isInstance(TruffleObject obj) { + return obj instanceof ComplexNumbersB; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryReadNode.java new file mode 100644 index 000000000000..4179c1a36504 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryReadNode.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = ComplexNumberBEntry.class, language = TckLanguage.class) +final class ComplexNumbersBEntryReadNode extends ComplexNumbersBEntryReadBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumberBEntry complexNumber, String name) { + if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { + return complexNumber.getNumbers().getImags()[complexNumber.getIndex()]; + } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { + return complexNumber.getNumbers().getReals()[complexNumber.getIndex()]; + } else { + throw UnknownIdentifierException.raise(name); + } + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryWriteNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryWriteNode.java new file mode 100644 index 000000000000..fb2a2a6717d9 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBEntryWriteNode.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "WRITE", receiverType = ComplexNumberBEntry.class, language = TckLanguage.class) +final class ComplexNumbersBEntryWriteNode extends ComplexNumbersBEntryWriteBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumberBEntry complexNumber, String name, Number value) { + if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { + complexNumber.getNumbers().getImags()[complexNumber.getIndex()] = value.doubleValue(); + } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { + complexNumber.getNumbers().getReals()[complexNumber.getIndex()] = value.doubleValue(); + } else { + throw UnknownIdentifierException.raise(name); + } + return value; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBGetSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBGetSizeNode.java new file mode 100644 index 000000000000..be5789a653d1 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBGetSizeNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "GET_SIZE", receiverType = ComplexNumbersB.class, language = TckLanguage.class) +final class ComplexNumbersBGetSizeNode extends ComplexNumbersBGetSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumbersB complexNumbers) { + assert complexNumbers.getReals().length == complexNumbers.getImags().length; + return complexNumbers.getReals().length; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBHasSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBHasSizeNode.java new file mode 100644 index 000000000000..cdb18431e82b --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBHasSizeNode.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "HAS_SIZE", receiverType = ComplexNumbersB.class, language = TckLanguage.class) +final class ComplexNumbersBHasSizeNode extends ComplexNumbersBHasSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumbersB complexNumbers) { + return true; + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBReadNode.java new file mode 100644 index 000000000000..3ad61755bc3b --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBReadNode.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = ComplexNumbersB.class, language = TckLanguage.class) +final class ComplexNumbersBReadNode extends ComplexNumbersBReadBaseNode { + @Override + public Object access(VirtualFrame frame, ComplexNumbersB complexNumbers, Number index) { + return new ComplexNumberBEntry(complexNumbers, index.intValue()); + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBWriteNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBWriteNode.java new file mode 100644 index 000000000000..d7d892578dba --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersBWriteNode.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, 2016, 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.CompilerDirectives; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +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.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "WRITE", receiverType = ComplexNumbersB.class, language = TckLanguage.class) +final class ComplexNumbersBWriteNode extends ComplexNumbersBWriteBaseNode { + @Child private Node readReal; + @Child private Node readImag; + + @Override + public Object access(VirtualFrame frame, ComplexNumbersB complexNumbers, Number index, TruffleObject value) { + if (readReal == null || readImag == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + this.readReal = insert(Message.READ.createNode()); + this.readImag = insert(Message.READ.createNode()); + } + try { + Number realPart = TckLanguage.expectNumber(ForeignAccess.sendRead(readReal, frame, value, ComplexNumber.REAL_IDENTIFIER)); + Number imagPart = TckLanguage.expectNumber(ForeignAccess.sendRead(readImag, frame, value, ComplexNumber.IMAGINARY_IDENTIFIER)); + complexNumbers.getReals()[index.intValue()] = realPart.doubleValue(); + complexNumbers.getImags()[index.intValue()] = imagPart.doubleValue(); + return value; + } catch (UnknownIdentifierException | UnsupportedMessageException e) { + return null; + } + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersColumnBased.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersColumnBased.java deleted file mode 100644 index 7c7274eff180..000000000000 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersColumnBased.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * 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.tck.impl.TckLanguage; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; -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 ComplexNumbersColumnBased implements TruffleObject { - - private final double[] reals; - private final double[] imags; - - ComplexNumbersColumnBased(double[] reals, double[] imags) { - assert reals.length == imags.length; - this.reals = reals; - this.imags = imags; - } - - public double[] getData() { - double[] data = new double[reals.length * 2]; - for (int i = 0; i < reals.length; i++) { - data[i * 2] = reals[i]; - data[i * 2 + 1] = imags[i]; - } - return data; - } - - public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new ComplexNumbersBForeignAccessFactory()); - } - - private static class ComplexNumbersBForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof ComplexNumbersColumnBased; - } - - public CallTarget accessMessage(Message tree) { - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersBReadNode()); - } else if (Message.WRITE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersBWriteNode()); - } else if (Message.GET_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersBSizeNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - } - - private static class ComplexNumbersBWriteNode extends RootNode { - protected ComplexNumbersBWriteNode() { - super(TckLanguage.class, null, null); - } - - @Child private Node readReal; - @Child private Node readImag; - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersColumnBased complexNumbers = (ComplexNumbersColumnBased) ForeignAccess.getReceiver(frame); - Number index = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(0)); - TruffleObject value = TckLanguage.expectTruffleObject(ForeignAccess.getArguments(frame).get(1)); - if (readReal == null || readImag == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - this.readReal = insert(Message.READ.createNode()); - this.readImag = insert(Message.READ.createNode()); - } - Number realPart = TckLanguage.expectNumber(ForeignAccess.execute(readReal, frame, value, new Object[]{ComplexNumber.REAL_IDENTIFIER})); - Number imagPart = TckLanguage.expectNumber(ForeignAccess.execute(readImag, frame, value, new Object[]{ComplexNumber.IMAGINARY_IDENTIFIER})); - - complexNumbers.reals[index.intValue()] = realPart.doubleValue(); - complexNumbers.imags[index.intValue()] = imagPart.doubleValue(); - return value; - } - } - - private static class ComplexNumbersBReadNode extends RootNode { - protected ComplexNumbersBReadNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersColumnBased complexNumbers = (ComplexNumbersColumnBased) ForeignAccess.getReceiver(frame); - Number index = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(0)); - return new ComplexNumberBEntry(complexNumbers, index.intValue()); - } - - } - - private static class ComplexNumbersBSizeNode extends RootNode { - protected ComplexNumbersBSizeNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersColumnBased complexNumbers = (ComplexNumbersColumnBased) ForeignAccess.getReceiver(frame); - assert complexNumbers.reals.length == complexNumbers.imags.length; - return complexNumbers.reals.length; - } - - } - - private static class ComplexNumberBEntry implements TruffleObject { - - private final ComplexNumbersColumnBased numbers; - private final int index; - - public ComplexNumberBEntry(ComplexNumbersColumnBased numbers, int index) { - this.numbers = numbers; - this.index = index; - } - - public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new ComplexNumberBEntryForeignAccessFactory()); - } - - private static class ComplexNumberBEntryForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof ComplexNumberBEntry; - } - - public CallTarget accessMessage(Message tree) { - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAEntryReadNode()); - } else if (Message.WRITE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAEntryWriteNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - - private static class ComplexNumbersAEntryReadNode extends RootNode { - protected ComplexNumbersAEntryReadNode() { - super(TckLanguage.class, null, null); - } - - @Child private Node readReal; - @Child private Node readImag; - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumberBEntry complexNumber = (ComplexNumberBEntry) ForeignAccess.getReceiver(frame); - String name = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { - return complexNumber.numbers.imags[complexNumber.index]; - } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { - return complexNumber.numbers.reals[complexNumber.index]; - } else { - throw new IllegalArgumentException(); - } - } - } - - private static class ComplexNumbersAEntryWriteNode extends RootNode { - protected ComplexNumbersAEntryWriteNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumberBEntry complexNumber = (ComplexNumberBEntry) ForeignAccess.getReceiver(frame); - String name = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - Number value = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(1)); - if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { - complexNumber.numbers.imags[complexNumber.index] = value.doubleValue(); - } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { - complexNumber.numbers.reals[complexNumber.index] = value.doubleValue(); - } else { - throw new IllegalArgumentException(); - } - return value; - } - - } - } - - } - -} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersRowBased.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersRowBased.java deleted file mode 100644 index 029355be5c99..000000000000 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexNumbersRowBased.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * 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.tck.impl.TckLanguage; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; -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 ComplexNumbersRowBased implements TruffleObject { - - private final double[] data; - - ComplexNumbersRowBased(double[] data) { - assert data.length % 2 == 0; - this.data = data; - } - - public double[] getData() { - return data; - } - - public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new ComplexNumbersAForeignAccessFactory()); - } - - private static class ComplexNumbersAForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof ComplexNumbersRowBased; - } - - public CallTarget accessMessage(Message tree) { - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAReadNode()); - } else if (Message.WRITE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAWriteNode()); - } else if (Message.GET_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersASizeNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - } - - private static class ComplexNumbersAWriteNode extends RootNode { - protected ComplexNumbersAWriteNode() { - super(TckLanguage.class, null, null); - } - - @Child private Node readReal; - @Child private Node readImag; - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersRowBased complexNumbers = (ComplexNumbersRowBased) ForeignAccess.getReceiver(frame); - Number index = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(0)); - TruffleObject value = TckLanguage.expectTruffleObject(ForeignAccess.getArguments(frame).get(1)); - if (readReal == null || readImag == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - this.readReal = insert(Message.READ.createNode()); - this.readImag = insert(Message.READ.createNode()); - } - Number realPart = TckLanguage.expectNumber(ForeignAccess.execute(readReal, frame, value, new Object[]{ComplexNumber.REAL_IDENTIFIER})); - Number imagPart = TckLanguage.expectNumber(ForeignAccess.execute(readImag, frame, value, new Object[]{ComplexNumber.IMAGINARY_IDENTIFIER})); - - int idx = TckLanguage.checkBounds(index.intValue(), complexNumbers.data.length / 2); - - complexNumbers.data[idx * 2] = realPart.doubleValue(); - complexNumbers.data[idx * 2 + 1] = imagPart.doubleValue(); - return value; - } - } - - private static class ComplexNumbersAReadNode extends RootNode { - protected ComplexNumbersAReadNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersRowBased complexNumbers = (ComplexNumbersRowBased) ForeignAccess.getReceiver(frame); - Number index = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(0)); - int idx = TckLanguage.checkBounds(index.intValue(), complexNumbers.data.length / 2); - return new ComplexNumberAEntry(complexNumbers, idx); - } - } - - private static class ComplexNumbersASizeNode extends RootNode { - protected ComplexNumbersASizeNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumbersRowBased complexNumbers = (ComplexNumbersRowBased) ForeignAccess.getReceiver(frame); - return complexNumbers.data.length / 2; - } - - } - - private static class ComplexNumberAEntry implements TruffleObject { - - private final ComplexNumbersRowBased numbers; - private final int index; - - public ComplexNumberAEntry(ComplexNumbersRowBased numbers, int index) { - this.numbers = numbers; - this.index = index; - } - - public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new ComplexNumberAEntryForeignAccessFactory()); - } - - private static class ComplexNumberAEntryForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof ComplexNumberAEntry; - } - - public CallTarget accessMessage(Message tree) { - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAEntryReadNode()); - } else if (Message.WRITE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new ComplexNumbersAEntryWriteNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } - - private static class ComplexNumbersAEntryReadNode extends RootNode { - protected ComplexNumbersAEntryReadNode() { - super(TckLanguage.class, null, null); - } - - @Child private Node readReal; - @Child private Node readImag; - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumberAEntry complexNumber = (ComplexNumberAEntry) ForeignAccess.getReceiver(frame); - String name = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { - return complexNumber.numbers.data[complexNumber.index * 2 + 1]; - } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { - return complexNumber.numbers.data[complexNumber.index * 2]; - } else { - throw new IllegalArgumentException(); - } - } - } - - private static class ComplexNumbersAEntryWriteNode extends RootNode { - protected ComplexNumbersAEntryWriteNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - ComplexNumberAEntry complexNumber = (ComplexNumberAEntry) ForeignAccess.getReceiver(frame); - String name = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - Number value = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(1)); - if (name.equals(ComplexNumber.IMAGINARY_IDENTIFIER)) { - complexNumber.numbers.data[complexNumber.index * 2 + 1] = value.doubleValue(); - } else if (name.equals(ComplexNumber.REAL_IDENTIFIER)) { - complexNumber.numbers.data[complexNumber.index * 2] = value.doubleValue(); - } else { - throw new IllegalArgumentException(); - } - return value; - } - - } - } - - } -} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexReadNode.java new file mode 100644 index 000000000000..4c64ddb6a101 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexReadNode.java @@ -0,0 +1,49 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexReadNode extends ComplexBaseReadNode { + + @Override + public Object access(VirtualFrame frame, ComplexNumber complex, String identifier) { + return complex.get(identifier); + } + + @Override + public Object access(VirtualFrame frame, ComplexNumber complex, int index) { + if (index == 0) { + return complex.get(ComplexNumber.REAL_IDENTIFIER); + } else if (index == 1) { + return complex.get(ComplexNumber.IMAGINARY_IDENTIFIER); + } + throw UnknownIdentifierException.raise("Index " + index + " out of bounds (idx 0 = real; idx 1 = imag"); + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexWriteNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexWriteNode.java new file mode 100644 index 000000000000..21e5a72098e5 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/ComplexWriteNode.java @@ -0,0 +1,51 @@ +/* + * 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "WRITE", receiverType = ComplexNumber.class, language = TckLanguage.class) +final class ComplexWriteNode extends ComplexBaseWriteNode { + @Override + public Object access(VirtualFrame frame, ComplexNumber complex, String identifier, Number value) { + complex.set(identifier, value.doubleValue()); + return value; + } + + @Override + public Object access(VirtualFrame frame, ComplexNumber complex, int index, Number value) { + if (index == 0) { + complex.set(ComplexNumber.REAL_IDENTIFIER, value.doubleValue()); + return value; + } else if (index == 1) { + complex.set(ComplexNumber.IMAGINARY_IDENTIFIER, value.doubleValue()); + return value; + } + throw UnknownIdentifierException.raise("Index " + index + " out of bounds (idx 0 = real; idx 1 = imag"); + } +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredData.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredData.java index 517fb35c184f..e6be27e6fe54 100644 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredData.java +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredData.java @@ -24,15 +24,8 @@ */ package com.oracle.truffle.tck; -import com.oracle.truffle.tck.impl.TckLanguage; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; -import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.RootNode; final class StructuredData implements TruffleObject { @@ -45,60 +38,18 @@ final class StructuredData implements TruffleObject { } public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new StructuredDataForeignAccessFactory()); + return StructuredDataForeign.ACCESS; } - private static class StructuredDataForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof StructuredData; - } - - public CallTarget accessMessage(Message tree) { - // for simplicity: this StructuredData is read-only - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new StructuredDataReadNode()); - } else if (Message.GET_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new StructuredDataSizeNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } + public static boolean isInstance(TruffleObject obj) { + return obj instanceof StructuredData; } - private static class StructuredDataReadNode extends RootNode { - protected StructuredDataReadNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - StructuredData data = (StructuredData) ForeignAccess.getReceiver(frame); - Number index = TckLanguage.expectNumber(ForeignAccess.getArguments(frame).get(0)); - int idx = TckLanguage.checkBounds(index.intValue(), data.schema.length()); - return new StructuredDataEntry(data.buffer, data.schema, idx); - } - + byte[] getBuffer() { + return buffer; } - private static class StructuredDataSizeNode extends RootNode { - protected StructuredDataSizeNode() { - super(TckLanguage.class, null, null); - } - - @Override - public Object execute(VirtualFrame frame) { - StructuredData data = (StructuredData) ForeignAccess.getReceiver(frame); - return data.schema.length(); - } - + Schema getSchema() { + return schema; } } diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntry.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntry.java index a924f6fe1902..4ec928739305 100644 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntry.java +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntry.java @@ -24,15 +24,8 @@ */ package com.oracle.truffle.tck; -import com.oracle.truffle.tck.impl.TckLanguage; -import com.oracle.truffle.api.CallTarget; -import com.oracle.truffle.api.Truffle; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.ForeignAccess.Factory; -import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.RootNode; final class StructuredDataEntry implements TruffleObject { @@ -47,44 +40,23 @@ final class StructuredDataEntry implements TruffleObject { } public ForeignAccess getForeignAccess() { - return ForeignAccess.create(new StructuredDataEntryForeignAccessFactory()); + return StructuredDataEntryForeign.ACCESS; } - private static class StructuredDataEntryForeignAccessFactory implements Factory { - - public boolean canHandle(TruffleObject obj) { - return obj instanceof StructuredDataEntry; - } - - public CallTarget accessMessage(Message tree) { - // for simplicity: this StructuredData is read-only - if (Message.IS_NULL.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_EXECUTABLE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.IS_BOXED.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.HAS_SIZE.equals(tree)) { - return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false)); - } else if (Message.READ.equals(tree)) { - return Truffle.getRuntime().createCallTarget(new StructuredDataEntryReadNode()); - } else { - throw new IllegalArgumentException(tree.toString() + " not supported"); - } - } + byte[] getBuffer() { + return buffer; } - private static class StructuredDataEntryReadNode extends RootNode { - protected StructuredDataEntryReadNode() { - super(TckLanguage.class, null, null); - } + int getIndex() { + return index; + } - @Override - public Object execute(VirtualFrame frame) { - StructuredDataEntry data = (StructuredDataEntry) ForeignAccess.getReceiver(frame); - String name = TckLanguage.expectString(ForeignAccess.getArguments(frame).get(0)); - return data.schema.get(data.buffer, data.index, name); - } + Schema getSchema() { + return schema; + } + public static boolean isInstance(TruffleObject obj) { + return obj instanceof StructuredDataEntry; } + } diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntryReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntryReadNode.java new file mode 100644 index 000000000000..0d4af110925e --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataEntryReadNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = StructuredDataEntry.class, language = TckLanguage.class) +final class StructuredDataEntryReadNode extends StructuredDataEntryReadBaseNode { + + @Override + public Object access(VirtualFrame frame, StructuredDataEntry data, String name) { + return data.getSchema().get(data.getBuffer(), data.getIndex(), name); + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataGetSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataGetSizeNode.java new file mode 100644 index 000000000000..78fb83c131f7 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataGetSizeNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "GET_SIZE", receiverType = StructuredData.class, language = TckLanguage.class) +final class StructuredDataGetSizeNode extends StructuredDataGetSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, StructuredData data) { + return data.getSchema().length(); + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataHasSizeNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataHasSizeNode.java new file mode 100644 index 000000000000..9e759de9298f --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataHasSizeNode.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "HAS_SIZE", receiverType = StructuredData.class, language = TckLanguage.class) +final class StructuredDataHasSizeNode extends StructuredDataHasSizeBaseNode { + + @Override + public Object access(VirtualFrame frame, StructuredData data) { + return true; + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataReadNode.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataReadNode.java new file mode 100644 index 000000000000..cdf7b5e034a7 --- /dev/null +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/StructuredDataReadNode.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016, 2016, 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.frame.VirtualFrame; +import com.oracle.truffle.api.interop.AcceptMessage; +import com.oracle.truffle.tck.impl.TckLanguage; + +@AcceptMessage(value = "READ", receiverType = StructuredData.class, language = TckLanguage.class) +final class StructuredDataReadNode extends StructuredDataReadBaseNode { + + @Override + public Object access(VirtualFrame frame, StructuredData data, Number index) { + int idx = TckLanguage.checkBounds(index.intValue(), data.getSchema().length()); + return new StructuredDataEntry(data.getBuffer(), data.getSchema(), idx); + } + +} diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java index a9ac7520edff..4212a08776b9 100644 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java @@ -68,12 +68,12 @@ * // create the engine * // execute necessary scripts * } - * + * * {@link Override @Override} * protected {@link String} fourtyTwo() { * return // name of function that returns 42 * } - * + * * // and so on... * } * @@ -174,7 +174,7 @@ protected String plusInt() { /** * Name of function to add two numbers together. The symbol will be invoked with two parameters - * of type1 and type2 and expects result of type {@link Number} + * of type1 and type2 and expects result of type {@link Number} * which's {@link Number#intValue()} is equivalent of param1 + param2. As some * languages may have different operations for different types of numbers, the actual types are * passed to the method and the implementation can decide to return different symbol based on @@ -220,6 +220,18 @@ protected String complexAdd() { throw new UnsupportedOperationException("complexAdd() method not implemented"); } + /** + * Name of a function that adds up two complex numbers using an add method of the first complex + * number. The function accepts two arguments and provides no return value. The arguments are + * complex numbers with members called real and imaginary. The first argument contains the + * result of the addition. + * + * @return name of globally exported symbol + */ + protected String complexAddWithMethod() { + throw new UnsupportedOperationException("complexAddWithMethod() method not implemented"); + } + /** * Name of a function that adds up the real part of complex numbers. The function accepts one * argument and provides the sum of all real parts. The argument is an array/buffer of complex @@ -270,7 +282,7 @@ protected String evaluateSource() { /** * Code snippet to multiplyCode two two variables. The test uses the snippet as a parameter to - * your language's + * your language' s * {@link TruffleLanguage#parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...)} * method. * @@ -367,7 +379,7 @@ protected String valuesObject() { * Default implementation of this method calls * {@link Assert#assertEquals(java.lang.String, double, double, double)} with delta * 0.1. - * + * * @param msg assertion message to display in case of error * @param expectedValue the value expected by the test * @param actualValue the real value produced by the language @@ -1073,6 +1085,23 @@ public void testAddComplexNumbers() throws Exception { assertEquals(42.0, a.get(ComplexNumber.IMAGINARY_IDENTIFIER), 0.1); } + @Test + public void testAddComplexNumbersWithMethod() throws Exception { + String id = complexAddWithMethod(); + if (id == null) { + return; + } + PolyglotEngine.Value apply = findGlobalSymbol(id); + + ComplexNumber a = new ComplexNumber(32, 10); + ComplexNumber b = new ComplexNumber(10, 32); + + apply.execute(a, b); + + assertDouble("The same value returned", 42.0, a.get(ComplexNumber.REAL_IDENTIFIER)); + assertDouble("The same value returned", 42.0, a.get(ComplexNumber.IMAGINARY_IDENTIFIER)); + } + @Test public void testSumRealOfComplexNumbersA() throws Exception { String id = complexSumReal(); @@ -1081,7 +1110,7 @@ public void testSumRealOfComplexNumbersA() throws Exception { } PolyglotEngine.Value apply = findGlobalSymbol(id); - ComplexNumbersRowBased numbers = new ComplexNumbersRowBased(new double[]{2, -1, 30, -1, 10, -1}); + ComplexNumbersA numbers = new ComplexNumbersA(new double[]{2, -1, 30, -1, 10, -1}); Number n = (Number) apply.execute(numbers).get(); assertDouble("The same value returned", 42.0, n.doubleValue()); @@ -1095,7 +1124,7 @@ public void testSumRealOfComplexNumbersB() throws Exception { } PolyglotEngine.Value apply = findGlobalSymbol(id); - ComplexNumbersColumnBased numbers = new ComplexNumbersColumnBased(new double[]{2, 30, 10}, new double[]{-1, -1, -1}); + ComplexNumbersB numbers = new ComplexNumbersB(new double[]{2, 30, 10}, new double[]{-1, -1, -1}); Number n = (Number) apply.execute(numbers).get(); assertDouble("The same value returned", 42.0, n.doubleValue()); @@ -1144,8 +1173,8 @@ public void testCopyComplexNumbersA() throws Exception { } PolyglotEngine.Value apply = findGlobalSymbol(id); - ComplexNumbersRowBased a = new ComplexNumbersRowBased(new double[]{-1, -1, -1, -1, -1, -1}); - ComplexNumbersRowBased b = new ComplexNumbersRowBased(new double[]{41, 42, 43, 44, 45, 46}); + ComplexNumbersA a = new ComplexNumbersA(new double[]{-1, -1, -1, -1, -1, -1}); + ComplexNumbersA b = new ComplexNumbersA(new double[]{41, 42, 43, 44, 45, 46}); apply.execute(a, b); @@ -1160,8 +1189,8 @@ public void testCopyComplexNumbersB() throws Exception { } PolyglotEngine.Value apply = findGlobalSymbol(id); - ComplexNumbersColumnBased a = new ComplexNumbersColumnBased(new double[]{-1, -1, -1}, new double[]{-1, -1, -1}); - ComplexNumbersColumnBased b = new ComplexNumbersColumnBased(new double[]{41, 43, 45}, new double[]{42, 44, 46}); + ComplexNumbersB a = new ComplexNumbersB(new double[]{-1, -1, -1}, new double[]{-1, -1, -1}); + ComplexNumbersB b = new ComplexNumbersB(new double[]{41, 43, 45}, new double[]{42, 44, 46}); apply.execute(a, b); @@ -1176,7 +1205,7 @@ public void testCopyStructuredComplexToComplexNumbersA() throws Exception { } PolyglotEngine.Value apply = findGlobalSymbol(id); - ComplexNumbersRowBased a = new ComplexNumbersRowBased(new double[]{-1, -1, -1, -1, -1, -1}); + ComplexNumbersA a = new ComplexNumbersA(new double[]{-1, -1, -1, -1, -1, -1}); Schema schema = new Schema(3, true, Arrays.asList(ComplexNumber.REAL_IDENTIFIER, ComplexNumber.IMAGINARY_IDENTIFIER), Arrays.asList(Type.DOUBLE, Type.DOUBLE)); byte[] buffer = new byte[6 * Double.SIZE / Byte.SIZE]; diff --git a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/impl/TckLanguage.java b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/impl/TckLanguage.java index 061db4a76ba0..42a85c78c9a2 100644 --- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/impl/TckLanguage.java +++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/impl/TckLanguage.java @@ -36,6 +36,7 @@ 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.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; @@ -141,7 +142,7 @@ public CallTarget accessMessage(Message tree) { } else if (Message.createExecute(2).equals(tree)) { return Truffle.getRuntime().createCallTarget(this); } else { - throw new IllegalArgumentException("" + tree); + throw UnsupportedMessageException.raise(tree); } }