1 /*
  2  *  Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
  3  *  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  *  This code is free software; you can redistribute it and/or modify it
  6  *  under the terms of the GNU General Public License version 2 only, as
  7  *  published by the Free Software Foundation.
  8  *
  9  *  This code is distributed in the hope that it will be useful, but WITHOUT
 10  *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  *  version 2 for more details (a copy is included in the LICENSE file that
 13  *  accompanied this code).
 14  *
 15  *  You should have received a copy of the GNU General Public License version
 16  *  2 along with this work; if not, write to the Free Software Foundation,
 17  *  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  *   Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  *  or visit www.oracle.com if you need additional information or have any
 21  *  questions.
 22  *
 23  */
 24 
 25 /*
 26  * @test
 27  * @requires ((os.arch == "amd64" | os.arch == "x86_64") & sun.arch.data.model == "64") | os.arch == "aarch64"
 28  * @run testng TestFunctionDescriptor
 29  */
 30 
 31 import jdk.incubator.foreign.FunctionDescriptor;
 32 import jdk.incubator.foreign.MemoryLayout;
 33 import org.testng.annotations.Test;
 34 
 35 import java.lang.constant.Constable;
 36 import java.util.List;
 37 import java.util.Optional;
 38 import java.util.stream.Collectors;
 39 
 40 import static jdk.incubator.foreign.CLinker.C_DOUBLE;
 41 import static jdk.incubator.foreign.CLinker.C_INT;
 42 import static jdk.incubator.foreign.CLinker.C_LONG_LONG;
 43 import static jdk.incubator.foreign.CLinker.C_POINTER;
 44 import static org.testng.Assert.assertEquals;
 45 import static org.testng.Assert.assertFalse;
 46 import static org.testng.Assert.assertTrue;
 47 
 48 public class TestFunctionDescriptor {
 49 
 50     static final String DUMMY_ATTR = "dummy";
 51 
 52     @Test
 53     public void testOf() {
 54         FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_DOUBLE, C_LONG_LONG);
 55 
 56         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG));
 57         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
 58         assertTrue(returnLayoutOp.isPresent());
 59         assertEquals(returnLayoutOp.get(), C_INT);
 60     }
 61 
 62     @Test
 63     public void testOfVoid() {
 64         FunctionDescriptor fd = FunctionDescriptor.ofVoid(C_DOUBLE, C_LONG_LONG);
 65 
 66         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG));
 67         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
 68         assertFalse(returnLayoutOp.isPresent());
 69     }
 70 
 71     @Test
 72     public void testAttribute() {
 73         FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_DOUBLE, C_LONG_LONG);
 74         fd = fd.withAttribute(DUMMY_ATTR, true);
 75 
 76         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG));
 77         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
 78         assertTrue(returnLayoutOp.isPresent());
 79         assertEquals(returnLayoutOp.get(), C_INT);
 80         assertEquals(fd.attributes().collect(Collectors.toList()), List.of(DUMMY_ATTR));
 81         Optional<Constable> attr = fd.attribute(DUMMY_ATTR);
 82         assertTrue(attr.isPresent());
 83         assertEquals(attr.get(), true);
 84     }
 85 
 86     @Test
 87     public void testAppendArgumentLayouts() {
 88         FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_DOUBLE, C_LONG_LONG)
 89                                                   .withAttribute(DUMMY_ATTR, true);
 90         fd = fd.withAppendedArgumentLayouts(C_POINTER);
 91 
 92         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG, C_POINTER));
 93         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
 94         assertTrue(returnLayoutOp.isPresent());
 95         assertEquals(returnLayoutOp.get(), C_INT);
 96         assertEquals(fd.attributes().collect(Collectors.toList()), List.of(DUMMY_ATTR));
 97     }
 98 
 99     @Test
100     public void testChangeReturnLayout() {
101         FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_DOUBLE, C_LONG_LONG)
102                                                   .withAttribute(DUMMY_ATTR, true);
103         fd = fd.withReturnLayout(C_INT);
104 
105         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG));
106         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
107         assertTrue(returnLayoutOp.isPresent());
108         assertEquals(returnLayoutOp.get(), C_INT);
109         assertEquals(fd.attributes().collect(Collectors.toList()), List.of(DUMMY_ATTR));
110     }
111 
112     @Test
113     public void testDropReturnLayout() {
114         FunctionDescriptor fd = FunctionDescriptor.of(C_INT, C_DOUBLE, C_LONG_LONG)
115                                                   .withAttribute(DUMMY_ATTR, true);
116         fd = fd.withVoidReturnLayout();
117 
118         assertEquals(fd.argumentLayouts(), List.of(C_DOUBLE, C_LONG_LONG));
119         Optional<MemoryLayout> returnLayoutOp = fd.returnLayout();
120         assertFalse(returnLayoutOp.isPresent());
121         assertEquals(fd.attributes().collect(Collectors.toList()), List.of(DUMMY_ATTR));
122     }
123 }