Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / CallExpression.js
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 "use strict";
26
27 class CallExpression extends Expression {
28     constructor(origin, name, typeArguments, argumentList)
29     {
30         super(origin);
31         this._name = name;
32         this._typeArguments = typeArguments;
33         this._argumentList = argumentList;
34         this.func = null;
35         this._isCast = false;
36         this._returnType = null;
37     }
38     
39     get name() { return this._name; }
40     get typeArguments() { return this._typeArguments; }
41     get argumentList() { return this._argumentList; }
42     get isCast() { return this._isCast; }
43     get returnType() { return this._returnType; }
44     
45     static resolve(origin, possibleOverloads, typeParametersInScope, name, typeArguments, argumentList, argumentTypes, returnType)
46     {
47         let call = new CallExpression(origin, name, typeArguments, argumentList);
48         call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
49         call.possibleOverloads = possibleOverloads;
50         if (returnType)
51             call.setCastData(returnType);
52         return {call, resultType: call.resolve(possibleOverloads, typeParametersInScope, typeArguments)};
53     }
54     
55     resolve(possibleOverloads, typeParametersInScope, typeArguments)
56     {
57         if (!possibleOverloads)
58             throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name);
59         
60         let overload = null;
61         let failures = [];
62         for (let typeParameter of typeParametersInScope) {
63             if (!(typeParameter instanceof TypeVariable))
64                 continue;
65             if (!typeParameter.protocol)
66                 continue;
67             let signatures =
68                 typeParameter.protocol.protocolDecl.signaturesByNameWithTypeVariable(this.name, typeParameter);
69             if (!signatures)
70                 continue;
71             overload = resolveOverloadImpl(signatures, this.typeArguments, this.argumentTypes, this.returnType);
72             if (overload.func)
73                 break;
74             failures.push(...overload.failures);
75             overload = null;
76         }
77         if (!overload) {
78             overload = resolveOverloadImpl(
79                 possibleOverloads, this.typeArguments, this.argumentTypes, this.returnType);
80             if (!overload.func) {
81                 failures.push(...overload.failures);
82                 let message = "Did not find function named " + this.name + " for call with ";
83                 if (this.typeArguments.length)
84                     message += "type arguments <" + this.typeArguments + "> and ";
85                 message += "argument types (" + this.argumentTypes + ")";
86                 if (this.returnType)
87                     message +=" and return type " + this.returnType;
88                 if (failures.length)
89                     message += ", but considered:\n" + failures.join("\n")
90                 throw new WTypeError(this.origin.originString, message);
91             }
92         }
93         for (let i = 0; i < typeArguments.length; ++i) {
94             let typeArgumentType = typeArguments[i];
95             let typeParameter = overload.func.typeParameters[i];
96             if (!(typeParameter instanceof ConstexprTypeParameter))
97                 continue;
98             if (!typeParameter.type.equalsWithCommit(typeArgumentType))
99                 throw new Error("At " + this.origin.originString + " constexpr type argument and parameter types not equal: argument = " + typeArgumentType + ", parameter = " + typeParameter.type);
100         }
101         for (let i = 0; i < this.argumentTypes.length; ++i) {
102             let argumentType = this.argumentTypes[i];
103             let parameterType = overload.func.parameters[i].type.substituteToUnification(
104                 overload.func.typeParameters, overload.unificationContext);
105             let result = argumentType.equalsWithCommit(parameterType);
106             if (!result)
107                 throw new Error("At " + this.origin.originString + " argument and parameter types not equal after type argument substitution: argument = " + argumentType + ", parameter = " + parameterType);
108         }
109         return this.resolveToOverload(overload);
110     }
111     
112     resolveToOverload(overload)
113     {
114         this.func = overload.func;
115         this.actualTypeArguments = overload.typeArguments.map(typeArgument => typeArgument instanceof Type ? typeArgument.visit(new AutoWrapper()) : typeArgument);
116         this.instantiatedActualTypeArguments = this.actualTypeArguments;
117         let result = overload.func.returnType.substituteToUnification(
118             overload.func.typeParameters, overload.unificationContext);
119         if (!result)
120             throw new Error("Null return type");
121         result = result.visit(new AutoWrapper());
122         this.resultType = result;
123         return result;
124     }
125     
126     becomeCast(returnType)
127     {
128         this._returnType = new TypeRef(this.origin, this.name, this._typeArguments);
129         this._returnType.type = returnType;
130         this._name = "operator cast";
131         this._isCast = true;
132         this._typeArguments = [];
133     }
134     
135     setCastData(returnType)
136     {
137         this._returnType = returnType;
138         this._isCast = true;
139     }
140     
141     toString()
142     {
143         return (this.isCast ? "operator " + this.returnType : this.name) +
144             "<" + this.typeArguments + ">" +
145             (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") +
146             "(" + this.argumentList + ")";
147     }
148 }
149