Make JetStream 2
[WebKit-https.git] / PerformanceTests / JetStream2 / WSL / SPIRVTypeAnalyzer.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 SPIRVTypeAnalyzer extends Visitor {
28     constructor(program, typeMap, currentId)
29     {
30         super();
31         this._program = program;
32         this._typeMap = typeMap;
33         this._currentId = currentId;
34         this._stack = [];
35     }
36
37     get program()
38     {
39         this._program;
40     }
41
42     get typeMap()
43     {
44         return this._typeMap;
45     }
46
47     get currentId()
48     {
49         return this._currentId;
50     }
51
52     get stack()
53     {
54         return this._stack;
55     }
56
57     visitTypeRef(node)
58     {
59         node.type.visit(this);
60     }
61
62     _encounterType(id)
63     {
64         if (this.stack.length > 0)
65             this.stack[this.stack.length - 1].push(id);
66     }
67
68     visitNullType(node)
69     {
70         super.visit(this);
71     }
72
73     visitGenericLiteralType(node)
74     {
75         node.type.visit(this);
76     }
77
78     visitNativeType(node)
79     {
80         if (!this.typeMap.has(node))
81             this.typeMap.set(node, this._currentId++);
82         let id = this.typeMap.get(node);
83         this._encounterType(id);
84     }
85
86     visitEnumType(node)
87     {
88         super.visit(this);
89     }
90
91     visitPtrType(node)
92     {
93         // Intentionally blank
94     }
95
96     visitArrayRefType(node)
97     {
98         this.visitNativeType(program.intrinsics.uint32);
99         this.visitNativeType(program.intrinsics.uint32);
100     }
101
102     // FIXME: Using toString() in these functions is a hack. Instead, we should implement a proper type deduper.
103     visitArrayType(node)
104     {
105         let id;
106         if (this.typeMap.has(node.toString())) {
107             id = this.typeMap.get(node);
108             if (typeof id == "object")
109                 id = id.id;
110         } else {
111             let fieldType = [];
112             this.stack.push(fieldType);
113             node.elementType.visit(this);
114             this.stack.pop();
115             if (fieldType.length != 1)
116                 throw new Error("Arrays can only have one element type!");
117             id = this._currentId++;
118             node.numElements.visit(this);
119             this.typeMap.set(node.toString(), {id: id, elementType: fieldType[0], numElements: node.numElements.value});
120         }
121         this._encounterType(id);
122     }
123
124     visitStructType(node)
125     {
126         let id;
127         if (this.typeMap.has(node.toString())) {
128             id = this.typeMap.get(node.toString());
129             if (typeof id == "object")
130                 id = id.id;
131         } else {
132             let fieldTypes = [];
133             this.stack.push(fieldTypes);
134             for (let field of node.fields)
135                 field.visit(this);
136             this.stack.pop();
137             id = this._currentId++;
138             this.typeMap.set(node.toString(), {id: id, fieldTypes: fieldTypes});
139         }
140         this._encounterType(id);
141     }
142 }