Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / Node.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 Node {
28     visit(visitor)
29     {
30         let visitFunc = visitor["visit" + this.constructor.name];
31         if (!visitFunc)
32             throw new Error("No visit function for " + this.constructor.name + " in " + visitor.constructor.name);
33         let returnValue = visitFunc.call(visitor, this);
34         if ("returnValue" in visitor)
35             returnValue = visitor.returnValue;
36         
37         return returnValue;
38     }
39     
40     static visit(node, visitor)
41     {
42         if (node instanceof Node)
43             return node.visit(visitor);
44         return node;
45     }
46     
47     unify(unificationContext, other)
48     {
49         if (!other)
50             throw new Error("Null other");
51         let unifyThis = this.unifyNode;
52         let unifyOther = other.unifyNode;
53         if (unifyThis == unifyOther)
54             return true;
55         if (unifyOther.typeVariableUnify(unificationContext, unifyThis))
56             return true;
57         return unifyThis.unifyImpl(unificationContext, unifyOther);
58     }
59     
60     unifyImpl(unificationContext, other)
61     {
62         if (other.typeVariableUnify(unificationContext, this))
63             return true;
64         return this == other;
65     }
66     
67     typeVariableUnify(unificationContext, other)
68     {
69         return false;
70     }
71     
72     _typeVariableUnifyImpl(unificationContext, other)
73     {
74         let realThis = unificationContext.find(this);
75         if (realThis != this)
76             return realThis.unify(unificationContext, other);
77         
78         unificationContext.union(this, other);
79         return true;
80     }
81     
82     // Most type variables don't care about this.
83     prepareToVerify(unificationContext) { }
84     commitUnification(unificationContext) { }
85     
86     get unifyNode() { return this; }
87     get isUnifiable() { return false; }
88     get isLiteral() { return false; }
89     
90     get isNative() { return false; }
91     
92     conversionCost(unificationContext) { return 0; }
93     
94     equals(other)
95     {
96         let unificationContext = new UnificationContext();
97         if (this.unify(unificationContext, other) && unificationContext.verify().result)
98             return unificationContext;
99         return false;
100     }
101     
102     equalsWithCommit(other)
103     {
104         let unificationContext = this.equals(other);
105         if (!unificationContext)
106             return false;
107         unificationContext.commit();
108         return unificationContext;
109     }
110     
111     commit()
112     {
113         let unificationContext = new UnificationContext();
114         unificationContext.addExtraNode(this);
115         let result = unificationContext.verify();
116         if (!result.result)
117             throw new WError(node.origin.originString, "Could not infer type: " + result.reason);
118         unificationContext.commit();
119         return unificationContext.find(this);
120     }
121     
122     substitute(parameters, argumentList)
123     {
124         return this.visit(new Substitution(parameters, argumentList));
125     }
126     
127     substituteToUnification(parameters, unificationContext)
128     {
129         return this.substitute(
130             parameters,
131             parameters.map(type => unificationContext.find(type)));
132     }
133 }