Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / NameContext.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 const Anything = Symbol();
28
29 function isWildcardKind(kind)
30 {
31     return kind == Anything;
32 }
33
34 class NameContext {
35     constructor(delegate)
36     {
37         this._map = new Map();
38         this._set = new Set();
39         this._currentStatement = null;
40         this._delegate = delegate;
41         this._intrinsics = null;
42         this._program = null;
43     }
44     
45     add(thing)
46     {
47         if (!thing.name)
48             return;
49         if (!thing.origin)
50             throw new Error("Thing does not have origin: " + thing);
51         
52         if (thing.isNative && !thing.implementation) {
53             if (!this._intrinsics)
54                 throw new Error("Native function in a scope that does not recognize intrinsics");
55             this._intrinsics.add(thing);
56         }
57         
58         if (thing.kind == Func) {
59             this._set.add(thing);
60             let array = this._map.get(thing.name);
61             if (!array) {
62                 array = [];
63                 array.kind = Func;
64                 this._map.set(thing.name, array);
65             }
66             if (array.kind != Func)
67                 throw new WTypeError(thing.origin.originString, "Cannot reuse type name for function: " + thing.name);
68             array.push(thing);
69             return;
70         }
71         if (this._map.has(thing.name))
72             throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name);
73         this._set.add(thing);
74         this._map.set(thing.name, thing);
75     }
76     
77     get(kind, name)
78     {
79         let result = this._map.get(name);
80         if (!result && this._delegate)
81             return this._delegate.get(kind, name);
82         if (result && !isWildcardKind(kind) && result.kind != kind)
83             return null;
84         return result;
85     }
86     
87     underlyingThings(kind, name)
88     {
89         let things = this.get(kind, name);
90         return NameContext.underlyingThings(things);
91     }
92     
93     static *underlyingThings(thing)
94     {
95         if (!thing)
96             return;
97         if (thing.kind === Func) {
98             if (!(thing instanceof Array))
99                 throw new Error("Func thing is not array: " + thing);
100             for (let func of thing)
101                 yield func;
102             return;
103         }
104         yield thing;
105     }
106     
107     resolveFuncOverload(name, typeArguments, argumentTypes, returnType, allowEntryPoint = false)
108     {
109         let functions = this.get(Func, name);
110         if (!functions)
111             return {failures: []};
112         
113         return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType, allowEntryPoint);
114     }
115     
116     get currentStatement()
117     {
118         if (this._currentStatement)
119             return this._currentStatement;
120         if (this._delegate)
121             return this._delegate.currentStatement;
122         return null;
123     }
124     
125     doStatement(statement, callback)
126     {
127         this._currentStatement = statement;
128         callback();
129         this._currentStatement = null;
130     }
131     
132     recognizeIntrinsics()
133     {
134         this._intrinsics = new Intrinsics(this);
135     }
136     
137     get intrinsics()
138     {
139         if (this._intrinsics)
140             return this._intrinsics;
141         if (this._delegate)
142             return this._delegate.intrinsics;
143         return null;
144     }
145     
146     set program(value)
147     {
148         this._program = value;
149     }
150     
151     get program()
152     {
153         if (this._program)
154             return this._program;
155         if (this._delegate)
156             return this._delegate.program;
157         return null;
158     }
159     
160     *[Symbol.iterator]()
161     {
162         for (let value of this._map.values()) {
163             if (value instanceof Array) {
164                 for (let func of value)
165                     yield func;
166                 continue;
167             }
168             yield value;
169         }
170     }
171 }