Title: [221496] trunk/Tools
Revision
221496
Author
fpi...@apple.com
Date
2017-09-01 14:35:30 -0700 (Fri, 01 Sep 2017)

Log Message

WSL should be be able to call a function declared in a protocol from a generic function
https://bugs.webkit.org/show_bug.cgi?id=176242

Reviewed by Myles Maxfield.
        
It turns out that we need to know when a function is resolved to a protocol signature, so we
need to have a type for this. This introduces ProtocolFuncDecl.
        
Also, this introduces parsing of protocol decls.
        
When instantiating a function, we need to rewrite its CallExpressions if they were previously
resolved to a PrtococolFuncDecl instead of a FuncDef or NativeFunc. In that case, we need to
rerun the resolution on the program. That resolution is guaranteed to succeed if the type
system works correctly.

* WebGPUShadingLanguageRI/All.js:
* WebGPUShadingLanguageRI/CallExpression.js:
(CallExpression.prototype.resolve):
* WebGPUShadingLanguageRI/Checker.js:
(Checker.prototype.visitProtocolDecl.set throw):
* WebGPUShadingLanguageRI/EBufferBuilder.js:
(EBufferBuilder.prototype._createEPtr):
* WebGPUShadingLanguageRI/Func.js:
(Func):
(Func.prototype.get origin):
* WebGPUShadingLanguageRI/FuncDef.js:
(FuncDef):
(FuncDef.prototype.get origin): Deleted.
* WebGPUShadingLanguageRI/FuncInstantiator.js:
(FuncInstantiator):
(FuncInstantiator.prototype.getUnique.InstantiationSubstitution.prototype.visitCallExpression):
(FuncInstantiator.prototype.getUnique.InstantiationSubstitution):
* WebGPUShadingLanguageRI/NativeFunc.js:
(NativeFunc):
(NativeFunc.prototype.get origin): Deleted.
* WebGPUShadingLanguageRI/NativeFuncInstance.js:
(NativeFuncInstance):
* WebGPUShadingLanguageRI/Node.js:
(Node.prototype.substitute):
* WebGPUShadingLanguageRI/Parse.js:
(parseProtocolFuncDecl):
(parseProtocolDecl):
(parse):
* WebGPUShadingLanguageRI/Program.js:
(Program):
(Program.prototype.get protocols):
(Program.prototype.add):
* WebGPUShadingLanguageRI/ProtocolDecl.js:
(ProtocolDecl.prototype.add):
(ProtocolDecl.prototype.hasHeir):
(ProtocolDecl.prototype.addSignature): Deleted.
* WebGPUShadingLanguageRI/ProtocolFuncDecl.js: Added.
(ProtocolFuncDecl):
* WebGPUShadingLanguageRI/Rewriter.js:
(Rewriter.prototype.visitStructType):
(Rewriter.prototype.visitTypeVariable):
(Rewriter.prototype.visitProtocolFuncDecl):
(Rewriter.prototype.visitCallExpression):
* WebGPUShadingLanguageRI/StructType.js:
(StructType.prototype.instantiate):
* WebGPUShadingLanguageRI/Substitution.js:
(Substitution):
(Substitution.mapping): Deleted.
* WebGPUShadingLanguageRI/Test.js:
(TEST_simpleGeneric):
(TEST_simpleAssignment):
(TEST_simpleDefault):
(TEST_simpleDereference):
(TEST_dereferenceStore):
(TEST_simpleMakePtr):
(TEST_threadArrayLoad):
(TEST_deviceArrayLoad):
(TEST_threadArrayStore):
(TEST_deviceArrayStore):
(TEST_simpleProtocol):
* WebGPUShadingLanguageRI/Visitor.js:
(Visitor.prototype.visitProtocolFuncDecl):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (221495 => 221496)


--- trunk/Tools/ChangeLog	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/ChangeLog	2017-09-01 21:35:30 UTC (rev 221496)
@@ -1,3 +1,83 @@
+2017-09-01  Filip Pizlo  <fpi...@apple.com>
+
+        WSL should be be able to call a function declared in a protocol from a generic function
+        https://bugs.webkit.org/show_bug.cgi?id=176242
+
+        Reviewed by Myles Maxfield.
+        
+        It turns out that we need to know when a function is resolved to a protocol signature, so we
+        need to have a type for this. This introduces ProtocolFuncDecl.
+        
+        Also, this introduces parsing of protocol decls.
+        
+        When instantiating a function, we need to rewrite its CallExpressions if they were previously
+        resolved to a PrtococolFuncDecl instead of a FuncDef or NativeFunc. In that case, we need to
+        rerun the resolution on the program. That resolution is guaranteed to succeed if the type
+        system works correctly.
+
+        * WebGPUShadingLanguageRI/All.js:
+        * WebGPUShadingLanguageRI/CallExpression.js:
+        (CallExpression.prototype.resolve):
+        * WebGPUShadingLanguageRI/Checker.js:
+        (Checker.prototype.visitProtocolDecl.set throw):
+        * WebGPUShadingLanguageRI/EBufferBuilder.js:
+        (EBufferBuilder.prototype._createEPtr):
+        * WebGPUShadingLanguageRI/Func.js:
+        (Func):
+        (Func.prototype.get origin):
+        * WebGPUShadingLanguageRI/FuncDef.js:
+        (FuncDef):
+        (FuncDef.prototype.get origin): Deleted.
+        * WebGPUShadingLanguageRI/FuncInstantiator.js:
+        (FuncInstantiator):
+        (FuncInstantiator.prototype.getUnique.InstantiationSubstitution.prototype.visitCallExpression):
+        (FuncInstantiator.prototype.getUnique.InstantiationSubstitution):
+        * WebGPUShadingLanguageRI/NativeFunc.js:
+        (NativeFunc):
+        (NativeFunc.prototype.get origin): Deleted.
+        * WebGPUShadingLanguageRI/NativeFuncInstance.js:
+        (NativeFuncInstance):
+        * WebGPUShadingLanguageRI/Node.js:
+        (Node.prototype.substitute):
+        * WebGPUShadingLanguageRI/Parse.js:
+        (parseProtocolFuncDecl):
+        (parseProtocolDecl):
+        (parse):
+        * WebGPUShadingLanguageRI/Program.js:
+        (Program):
+        (Program.prototype.get protocols):
+        (Program.prototype.add):
+        * WebGPUShadingLanguageRI/ProtocolDecl.js:
+        (ProtocolDecl.prototype.add):
+        (ProtocolDecl.prototype.hasHeir):
+        (ProtocolDecl.prototype.addSignature): Deleted.
+        * WebGPUShadingLanguageRI/ProtocolFuncDecl.js: Added.
+        (ProtocolFuncDecl):
+        * WebGPUShadingLanguageRI/Rewriter.js:
+        (Rewriter.prototype.visitStructType):
+        (Rewriter.prototype.visitTypeVariable):
+        (Rewriter.prototype.visitProtocolFuncDecl):
+        (Rewriter.prototype.visitCallExpression):
+        * WebGPUShadingLanguageRI/StructType.js:
+        (StructType.prototype.instantiate):
+        * WebGPUShadingLanguageRI/Substitution.js:
+        (Substitution):
+        (Substitution.mapping): Deleted.
+        * WebGPUShadingLanguageRI/Test.js:
+        (TEST_simpleGeneric):
+        (TEST_simpleAssignment):
+        (TEST_simpleDefault):
+        (TEST_simpleDereference):
+        (TEST_dereferenceStore):
+        (TEST_simpleMakePtr):
+        (TEST_threadArrayLoad):
+        (TEST_deviceArrayLoad):
+        (TEST_threadArrayStore):
+        (TEST_deviceArrayStore):
+        (TEST_simpleProtocol):
+        * WebGPUShadingLanguageRI/Visitor.js:
+        (Visitor.prototype.visitProtocolFuncDecl):
+
 2017-09-01  Eric Carlson  <eric.carl...@apple.com>
 
         Switch HTMLMediaElement to release logging

Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/All.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/All.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -77,6 +77,7 @@
 load("Program.js");
 load("Protocol.js");
 load("ProtocolDecl.js");
+load("ProtocolFuncDecl.js");
 load("ProtocolRef.js");
 load("PtrType.js");
 load("ResolveNames.js");

Modified: trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -38,6 +38,17 @@
     get typeArguments() { return this._typeArguments; }
     get argumentList() { return this._argumentList; }
     
+    resolve(overload)
+    {
+        this.func = overload.func;
+        this.actualTypeArguments = overload.typeArguments;
+        let result = overload.func.returnType.substituteToUnification(
+            overload.func.typeParameters, overload.unificationContext);
+        if (!result)
+            throw new Error("Null return type");
+        return result;
+    }
+    
     toString()
     {
         return this.name + "<" + this.typeArguments + ">(" + this.argumentList + ")";

Modified: trunk/Tools/WebGPUShadingLanguageRI/Checker.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -204,6 +204,7 @@
                 throw new Error("visitor returned null for " + argument);
             return newArgument;
         });
+        node.argumentTypes = argumentTypes;
         
         let overload = null;
         let failures = [];
@@ -213,7 +214,7 @@
             if (!typeParameter.protocol)
                 continue;
             let signatures =
-                typeParameter.protocol.signaturesByNameWithTypeVariable(node.name, typeParameter);
+                typeParameter.protocol.protocolDecl.signaturesByNameWithTypeVariable(node.name, typeParameter);
             if (!signatures)
                 continue;
             overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes);
@@ -236,13 +237,7 @@
                 throw new WTypeError(node.origin.originString, message);
             }
         }
-        node.func = overload.func;
-        node.actualTypeArguments = overload.typeArguments;
-        let result = overload.func.returnType.substituteToUnification(
-            overload.func.typeParameters, overload.unificationContext);
-        if (!result)
-            throw new Error("Null result from CallExpression");
-        return result;
+        return node.resolve(overload);
     }
 }
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -35,6 +35,8 @@
     {
         type = type.instantiatedType;
         let buffer = new EBuffer(type.size);
+        if (!type.populateDefaultValue)
+            throw new Error("Cannot populateDefaultValue with: " + type);
         type.populateDefaultValue(buffer, 0);
         return new EPtr(buffer, 0);
     }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Func.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Func.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Func.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -25,9 +25,10 @@
 "use strict";
 
 class Func extends Node {
-    constructor(name, returnType, typeParameters, parameters)
+    constructor(origin, name, returnType, typeParameters, parameters)
     {
         super();
+        this._origin = origin;
         this._name = name;
         this._returnType = returnType;
         this._typeParameters = typeParameters;
@@ -34,6 +35,7 @@
         this._parameters = parameters;
     }
     
+    get origin() { return this._origin; }
     get name() { return this._name; }
     get returnType() { return this._returnType; }
     get typeParameters() { return this._typeParameters; }

Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -27,13 +27,10 @@
 class FuncDef extends Func {
     constructor(origin, name, returnType, typeParameters, parameters, body)
     {
-        super(name, returnType, typeParameters, parameters);
-        this._origin = origin;
+        super(origin, name, returnType, typeParameters, parameters);
         this.body = body;
     }
     
-    get origin() { return this._origin; }
-    
     toString()
     {
         return super.toString() + " " + this.body;

Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -25,12 +25,14 @@
 "use strict";
 
 class FuncInstantiator {
-    constructor()
+    constructor(program)
     {
+        this._program = program;
         this._instances = new Map();
     }
     
-    // Returns a Func object that uniquely identifies a particular system of type arguments.
+    // Returns a Func object that uniquely identifies a particular system of type arguments. You must
+    // intantiate things with concrete types, because this code casually assumes this.
     getUnique(func, typeArguments)
     {
         if (!func.typeParameters.length)
@@ -53,8 +55,27 @@
             return instance.func;
         }
         
-        let substitution = Substitution.mapping(func.typeParameters, typeArguments);
+        let thisInstantiator = this;
+        class InstantiationSubstitution extends Substitution {
+            visitCallExpression(node)
+            {
+                let result = super.visitCallExpression(node);
+                
+                // We may have to re-resolve the function call, if it was a call to a protocol
+                // signature.
+                if (result.func instanceof ProtocolFuncDecl) {
+                    let overload = thisInstantiator._program.resolveFuncOverload(node.name, node.typeArguments, node.argumentTypes);
+                    if (!overload.func)
+                        throw new Error("Could not resolve protocol signature function call during instantiation: " + result.func + (overload.failures.length ? "; tried:\n" + overload.failures.join("\n") : ""));
+                    result.resolve(overload);
+                }
+                
+                return result;
+            }
+        }
         
+        let substitution = new InstantiationSubstitution(func.typeParameters, typeArguments);
+        
         class Instantiate {
             visitFuncDef(func)
             {

Modified: trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -27,11 +27,9 @@
 class NativeFunc extends Func {
     constructor(origin, name, returnType, typeParameters, parameters)
     {
-        super(name, returnType, typeParameters, parameters);
-        this._origin = origin;
+        super(origin, name, returnType, typeParameters, parameters);
     }
     
-    get origin() { return this._origin; }
     get isNative() { return true; }
 
     toString()

Modified: trunk/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -27,8 +27,7 @@
 class NativeFuncInstance extends Func {
     constructor(func, returnType, parameters)
     {
-        super(func.name, returnType, [], parameters);
-        this._func = func;
+        super(func.origin, func.name, returnType, [], parameters);
     }
     
     get func() { return this._func; }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Node.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Node.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Node.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -72,7 +72,7 @@
     
     substitute(parameters, argumentList)
     {
-        return this.visit(Substitution.mapping(parameters, argumentList));
+        return this.visit(new Substitution(parameters, argumentList));
     }
     
     substituteToUnification(parameters, unificationContext)

Modified: trunk/Tools/WebGPUShadingLanguageRI/Parse.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Parse.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Parse.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -636,6 +636,15 @@
         return consumeKind("identifier").text;
     }
     
+    function parseProtocolFuncDecl()
+    {
+        let returnType = parseType();
+        let name = parseFuncName();
+        let typeParameters = parseTypeParameters();
+        let parameters = parseParameters();
+        return new ProtocolFuncDecl(returnType.origin, name, returnType, typeParameters, parameters);
+    }
+    
     function parseFuncDef()
     {
         let returnType = parseType();
@@ -646,6 +655,21 @@
         return new FuncDef(returnType.origin, name, returnType, typeParameters, parameters, body);
     }
     
+    function parseProtocolDecl()
+    {
+        let origin = consume("protocol");
+        let name = consumeKind("identifier").text;
+        // FIXME: Support protocol inclusion
+        // https://bugs.webkit.org/show_bug.cgi?id=176238
+        consume("{");
+        let result = new ProtocolDecl(origin, name);
+        while (!tryConsume("}")) {
+            result.add(parseProtocolFuncDecl());
+            consume(";");
+        }
+        return result;
+    }
+    
     for (;;) {
         let token = lexer.peek();
         if (!token)

Modified: trunk/Tools/WebGPUShadingLanguageRI/Program.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Program.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Program.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -31,12 +31,14 @@
         this._topLevelStatements = [];
         this._functions = new Map();
         this._types = new Map();
-        this._funcInstantiator = new FuncInstantiator();
+        this._protocols = new Map();
+        this._funcInstantiator = new FuncInstantiator(this);
     }
     
     get topLevelStatements() { return this._topLevelStatements; }
     get functions() { return this._functions; }
     get types() { return this._types; }
+    get protocols() { return this._protocols; }
     get funcInstantiator() { return this._funcInstantiator; }
     
     add(statement)
@@ -49,6 +51,8 @@
             array.push(statement);
         } else if (statement instanceof Type)
             this._types.set(statement.name, statement);
+        else if (statement instanceof Protocol)
+            this._protocols.set(statement.add, statement);
         else
             throw new Error("Statement is not a function or type: " + statement);
         this._topLevelStatements.push(statement);

Modified: trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -34,8 +34,12 @@
         this.isPrimitive = false;
     }
     
-    addSignature(signature)
+    add(signature)
     {
+        if (!(signature instanceof ProtocolFuncDecl))
+            throw new Error("Signature isn't a ProtocolFuncDecl but a " + signature.constructor.name);
+        
+        signature.protocolDecl = this;
         this._signatures.push(signature);
         let overloads = this._signatureMap.get(signature.name);
         if (!overloads)
@@ -82,9 +86,10 @@
     
     hasHeir(type)
     {
-        let substitution = Substitution.mapping([this._typeVariable], [type]);
-        for (let signature of this._signatures) {
-            let signature = signature.visit(substitution);
+        let substitution = new Substitution([this._typeVariable], [type]);
+        let signatures = this.signatures;
+        for (let signature of signatures) {
+            signature = signature.visit(substitution);
             let overload = this.program.resolveFuncOverload(signature.name, [], signature.parameterTypes);
             if (!overload)
                 return false;

Added: trunk/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js (0 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js	                        (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/ProtocolFuncDecl.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+"use strict";
+
+class ProtocolFuncDecl extends Func { }
+

Modified: trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -57,8 +57,22 @@
     visitNativeType(node) { return node; }
     visitTypeDef(node) { return node; }
     visitStructType(node) { return node; }
+    visitConstexprTypeParameter(node) { return node; }
+
+    // This is almost wrong. We instantiate Func in Substitution in ProtocolDecl. Then, we end up
+    // not rewriting type variables. I think that just works because not rewriting them there is OK.
     visitTypeVariable(node) { return node; }
-    visitConstexprTypeParameter(node) { return node; }
+
+    visitProtocolFuncDecl(node)
+    {
+        let result = new ProtocolFuncDecl(
+            node.origin, node.name,
+            node.returnType.visit(this),
+            node.typeParameters.map(parameter => parameter.visit(this)),
+            node.parameters.map(parameter => parameter.visit(this)));
+        result.protocolDecl = node.protocolDecl;
+        return result;
+    }
     
     visitNativeTypeInstance(node)
     {
@@ -192,6 +206,9 @@
             result.actualTypeArguments =
                 actualTypeArguments.map(actualTypeArgument => actualTypeArgument.visit(this));
         }
+        let argumentTypes = node.argumentTypes;
+        if (argumentTypes)
+            result.argumentTypes = argumentTypes.map(argumentType => argumentType.visit(this));
         result.func = node.func;
         result.nativeFuncInstance = node.nativeFuncInstance;
         return result;

Modified: trunk/Tools/WebGPUShadingLanguageRI/StructType.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/StructType.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/StructType.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -64,7 +64,7 @@
         if (!typeArguments.length)
             return this;
         
-        let substitution = Substitution.mapping(this.typeParameters, typeArguments);
+        let substitution = new Substitution(this.typeParameters, typeArguments);
         let instantiateImmediates = new InstantiateImmediates();
         let result = new StructType(this.origin, this.name, []);
         for (let field of this.fields)

Modified: trunk/Tools/WebGPUShadingLanguageRI/Substitution.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Substitution.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Substitution.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -25,20 +25,14 @@
 "use strict";
 
 class Substitution extends Rewriter {
-    constructor(map)
+    constructor(parameters, argumentList)
     {
         super();
-        this._map = map;
-    }
-    
-    static mapping(parameters, argumentList)
-    {
         if (parameters.length != argumentList.length)
             throw new Error("Parameters and arguments are mismatched");
-        let map = new Map();
+        this._map = new Map();
         for (let i = 0; i < parameters.length; ++i)
-            map.set(parameters[i], argumentList[i]);
-        return new Substitution(map);
+            this._map.set(parameters[i], argumentList[i]);
     }
     
     visitTypeRef(node)

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -66,7 +66,8 @@
 function TEST_simpleGeneric() {
     let program = doPrep(`
         T id<T>(T x) { return x; }
-        int foo(int x) { return id(x) + 1; }`);
+        int foo(int x) { return id(x) + 1; }
+    `);
     checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 43);
 }
 
@@ -84,7 +85,8 @@
         {
             int result = p;
             return result;
-        }`);
+        }
+    `);
     checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
 }
 
@@ -96,7 +98,8 @@
             int result;
             result = p;
             return result;
-        }`);
+        }
+    `);
     checkInt(program, callFunction(program, "foo", [], [makeInt(program, 42)]), 42);
 }
 
@@ -107,7 +110,8 @@
         {
             int result;
             return result;
-        }`);
+        }
+    `);
     checkInt(program, callFunction(program, "foo", [], []), 0);
 }
 
@@ -117,7 +121,8 @@
         int foo(device int^ p)
         {
             return ^p;
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 13);
     checkInt(program, callFunction(program, "foo", [], [TypedValue.box(new PtrType(null, "device", program.intrinsics.int32), new EPtr(buffer, 0))]), 13);
@@ -129,7 +134,8 @@
         void foo(device int^ p)
         {
             ^p = 52;
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 13);
     callFunction(program, "foo", [], [TypedValue.box(new PtrType(null, "device", program.intrinsics.int32), new EPtr(buffer, 0))]);
@@ -144,7 +150,8 @@
         {
             int x = 42;
             return \\x;
-        }`);
+        }
+    `);
     let result = callFunction(program, "foo", [], []);
     if (!result.type.isPtr)
         throw new Error("Return type is not a pointer: " + result.type);
@@ -163,7 +170,8 @@
         int foo(thread int[] array)
         {
             return array[0u];
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 89);
     let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(null, "thread", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]);
@@ -176,7 +184,8 @@
         int foo(device int[] array)
         {
             return array[0u];
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 89);
     let result = callFunction(program, "foo", [], [TypedValue.box(new ArrayRefType(null, "device", program.intrinsics.int32), new EArrayRef(new EPtr(buffer, 0), 1))]);
@@ -189,7 +198,8 @@
         void foo(thread int[] array, int value)
         {
             array[0u] = value;
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 15);
     let arrayRef = TypedValue.box(
@@ -209,7 +219,8 @@
         void foo(device int[] array, int value)
         {
             array[0u] = value;
-        }`);
+        }
+    `);
     let buffer = new EBuffer(1);
     buffer.set(0, 15);
     let arrayRef = TypedValue.box(
@@ -223,6 +234,24 @@
         throw new Error("Bad value stored into buffer (expected -111): " + buffer.get(0));
 }
 
+function TEST_simpleProtocol()
+{
+    let program = doPrep(`
+        protocol Addable {
+            Addable operator+(Addable, Addable);
+        }
+        T add<T:Addable>(T a, T b)
+        {
+            return a + b;
+        }
+        int foo(int x)
+        {
+            return add(x, 73);
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], [makeInt(program, 45)]), 45 + 73);
+}
+
 let before = preciseTime();
 
 let filter = /.*/; // run everything by default

Modified: trunk/Tools/WebGPUShadingLanguageRI/Visitor.js (221495 => 221496)


--- trunk/Tools/WebGPUShadingLanguageRI/Visitor.js	2017-09-01 21:33:02 UTC (rev 221495)
+++ trunk/Tools/WebGPUShadingLanguageRI/Visitor.js	2017-09-01 21:35:30 UTC (rev 221496)
@@ -40,6 +40,11 @@
             parameter.visit(this);
     }
     
+    visitProtocolFuncDecl(node)
+    {
+        this.visitFunc(node);
+    }
+    
     visitFuncParameter(node)
     {
         node.type.visit(this);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to