1/*
2 * Copyright (c) 2015, 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
24package jdk.test.lib.jittester.factories;
25
26import java.util.ArrayList;
27import jdk.test.lib.jittester.CastOperator;
28import jdk.test.lib.jittester.IRNode;
29import jdk.test.lib.jittester.ProductionFailedException;
30import jdk.test.lib.jittester.SymbolTable;
31import jdk.test.lib.jittester.Type;
32import jdk.test.lib.jittester.TypeList;
33import jdk.test.lib.jittester.types.TypeKlass;
34import jdk.test.lib.jittester.utils.PseudoRandom;
35
36class CastOperatorFactory extends OperatorFactory<CastOperator> {
37    private final Type resultType;
38    private final Type ownerClass;
39
40    CastOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
41            Type resultType, boolean exceptionSafe, boolean noconsts) {
42        super(13, complexityLimit, operatorLimit, exceptionSafe, noconsts);
43        this.resultType = resultType;
44        this.ownerClass = ownerClass;
45    }
46
47    @Override
48    public CastOperator produce() throws ProductionFailedException {
49        ArrayList<Type> argType = new ArrayList<>(TypeList.getAll());
50        PseudoRandom.shuffle(argType);
51        for (Type type : argType) {
52            try {
53                Factory<IRNode> expressionFactory = new IRNodeBuilder()
54                        .setComplexityLimit(complexityLimit - 1)
55                        .setOperatorLimit(operatorLimit - 1)
56                        .setOwnerKlass((TypeKlass) ownerClass)
57                        .setExceptionSafe(exceptionSafe)
58                        .setNoConsts(noconsts)
59                        .setResultType(type)
60                        .getExpressionFactory();
61                SymbolTable.push();
62                if (type.equals(resultType) ||
63                        ((!exceptionSafe || exceptionSafe && !(type instanceof TypeKlass))
64                            && type.canExplicitlyCastTo(resultType))) {
65                    // In safe mode we cannot explicitly cast an object, because it may throw.
66                    CastOperator castOperator = new CastOperator(resultType, expressionFactory.produce());
67                    SymbolTable.merge();
68                    return castOperator;
69                }
70                throw new ProductionFailedException();
71            } catch (ProductionFailedException e) {
72                SymbolTable.pop();
73            }
74        }
75        throw new ProductionFailedException();
76    }
77}
78