Title: [221434] trunk/Tools
Revision
221434
Author
fpi...@apple.com
Date
2017-08-31 12:33:35 -0700 (Thu, 31 Aug 2017)

Log Message

WSL should be able to run a program that uses generics
https://bugs.webkit.org/show_bug.cgi?id=176152

Reviewed by Keith Miller.
        
This fixes the WSL parser and type checker to the point that we can:
        
- Parse a function call!
- Type check a generic function call with an inferred type parameter.
- Instantiate a generic function.
- Inline a function call.
- Evaluate an inlined function call.
        
This also changes the test suite so that it's a little nicer to add new tests. Functions whose
names start with "TEST_" are tests.

* WebGPUShadingLanguageRI/Checker.js:
(Checker.prototype.visitProtocolDecl.set throw):
* WebGPUShadingLanguageRI/EBufferBuilder.js:
(EBufferBuilder.prototype.visitFuncParameter):
(EBufferBuilder):
* WebGPUShadingLanguageRI/Evaluator.js:
(Evaluator.prototype.visitFunctionLikeBlock):
* WebGPUShadingLanguageRI/FuncDef.js:
(FuncDef.prototype.toString):
(FuncDef):
* WebGPUShadingLanguageRI/FuncInstantiator.js:
(FuncInstantiator.prototype.getUnique):
(FuncInstantiator):
* WebGPUShadingLanguageRI/Inliner.js:
(Inliner.prototype.visitCallExpression):
(Inliner):
* WebGPUShadingLanguageRI/Lexer.js:
(Lexer):
* WebGPUShadingLanguageRI/NameContext.js:
(NameContext):
(NameContext.prototype.add):
(NameContext.prototype.get let):
(NameContext.prototype.defineAll):
(NameContext.get intrinsics): Deleted.
(NameContext.set program): Deleted.
(NameContext.get program): Deleted.
* WebGPUShadingLanguageRI/NameResolver.js:
(NameResolver.prototype.visitProgram):
* WebGPUShadingLanguageRI/Parse.js:
(parseTerm):
(parsePossibleSuffix):
(genericParseCommaExpression):
(parseReturn):
* WebGPUShadingLanguageRI/Program.js:
(Program.prototype.resolveFuncOverload):
* WebGPUShadingLanguageRI/ProtocolDecl.js:
(ProtocolDecl.prototype.inherits):
* WebGPUShadingLanguageRI/ResolveOverloadImpl.js:
(resolveOverloadImpl):
* WebGPUShadingLanguageRI/Rewriter.js:
(Rewriter.prototype.visitFuncParameter):
(Rewriter.prototype.visitCallExpression):
(Rewriter.prototype._map): Deleted.
* WebGPUShadingLanguageRI/Test.js:
(checkInt):
(TEST_add1):
(TEST_simpleGeneric):
(let.s.in.this.s.startsWith):
(load): Deleted.
* WebGPUShadingLanguageRI/TypeVariable.js:
(TypeVariable.prototype.typeVariableUnify):
* WebGPUShadingLanguageRI/UnificationContext.js:
(UnificationContext.prototype.union):

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (221433 => 221434)


--- trunk/Tools/ChangeLog	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/ChangeLog	2017-08-31 19:33:35 UTC (rev 221434)
@@ -1,3 +1,75 @@
+2017-08-30  Filip Pizlo  <fpi...@apple.com>
+
+        WSL should be able to run a program that uses generics
+        https://bugs.webkit.org/show_bug.cgi?id=176152
+
+        Reviewed by Keith Miller.
+        
+        This fixes the WSL parser and type checker to the point that we can:
+        
+        - Parse a function call!
+        - Type check a generic function call with an inferred type parameter.
+        - Instantiate a generic function.
+        - Inline a function call.
+        - Evaluate an inlined function call.
+        
+        This also changes the test suite so that it's a little nicer to add new tests. Functions whose
+        names start with "TEST_" are tests.
+
+        * WebGPUShadingLanguageRI/Checker.js:
+        (Checker.prototype.visitProtocolDecl.set throw):
+        * WebGPUShadingLanguageRI/EBufferBuilder.js:
+        (EBufferBuilder.prototype.visitFuncParameter):
+        (EBufferBuilder):
+        * WebGPUShadingLanguageRI/Evaluator.js:
+        (Evaluator.prototype.visitFunctionLikeBlock):
+        * WebGPUShadingLanguageRI/FuncDef.js:
+        (FuncDef.prototype.toString):
+        (FuncDef):
+        * WebGPUShadingLanguageRI/FuncInstantiator.js:
+        (FuncInstantiator.prototype.getUnique):
+        (FuncInstantiator):
+        * WebGPUShadingLanguageRI/Inliner.js:
+        (Inliner.prototype.visitCallExpression):
+        (Inliner):
+        * WebGPUShadingLanguageRI/Lexer.js:
+        (Lexer):
+        * WebGPUShadingLanguageRI/NameContext.js:
+        (NameContext):
+        (NameContext.prototype.add):
+        (NameContext.prototype.get let):
+        (NameContext.prototype.defineAll):
+        (NameContext.get intrinsics): Deleted.
+        (NameContext.set program): Deleted.
+        (NameContext.get program): Deleted.
+        * WebGPUShadingLanguageRI/NameResolver.js:
+        (NameResolver.prototype.visitProgram):
+        * WebGPUShadingLanguageRI/Parse.js:
+        (parseTerm):
+        (parsePossibleSuffix):
+        (genericParseCommaExpression):
+        (parseReturn):
+        * WebGPUShadingLanguageRI/Program.js:
+        (Program.prototype.resolveFuncOverload):
+        * WebGPUShadingLanguageRI/ProtocolDecl.js:
+        (ProtocolDecl.prototype.inherits):
+        * WebGPUShadingLanguageRI/ResolveOverloadImpl.js:
+        (resolveOverloadImpl):
+        * WebGPUShadingLanguageRI/Rewriter.js:
+        (Rewriter.prototype.visitFuncParameter):
+        (Rewriter.prototype.visitCallExpression):
+        (Rewriter.prototype._map): Deleted.
+        * WebGPUShadingLanguageRI/Test.js:
+        (checkInt):
+        (TEST_add1):
+        (TEST_simpleGeneric):
+        (let.s.in.this.s.startsWith):
+        (load): Deleted.
+        * WebGPUShadingLanguageRI/TypeVariable.js:
+        (TypeVariable.prototype.typeVariableUnify):
+        * WebGPUShadingLanguageRI/UnificationContext.js:
+        (UnificationContext.prototype.union):
+
 2017-08-30  Alex Christensen  <achristen...@webkit.org>
 
         Add WKUIDelegatePrivate equivalent of WKPageUIClient's didClickAutoFillButton

Modified: trunk/Tools/WebGPUShadingLanguageRI/Checker.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -165,6 +165,7 @@
         });
         
         let overload = null;
+        let failures = [];
         for (let typeParameter of this._currentStatement.typeParameters) {
             if (!(typeParameter instanceof TypeVariable))
                 continue;
@@ -175,15 +176,25 @@
             if (!signatures)
                 continue;
             overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes);
-            if (overload)
+            if (overload.func)
                 break;
+            failures.push(...overload.failures);
+            overload = null;
         }
         if (!overload) {
             overload = this._program.resolveFuncOverload(
                 node.name, node.typeArguments, argumentTypes);
+            if (!overload.func) {
+                failures.push(...overload.failures);
+                let message = "Did not find function for call";
+                if (failures.length) {
+                    let stringifyFailure =
+                        failure => failure.func + " did not match because: " + failure.reason;
+                    message += ", but considered:\n" + failures.map(stringifyFailure).join("\n")
+                }
+                throw new WTypeError(node.origin.originString, message);
+            }
         }
-        if (!overload)
-            throw new WTypeError(node.origin.originString, "Did not find function for call");
         node.func = overload.func;
         node.actualTypeArguments = overload.typeArguments.map(TypeRef.wrap);
         let result = overload.func.returnType.substituteToUnification(

Modified: trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/EBufferBuilder.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -41,6 +41,8 @@
     
     visitFuncParameter(node)
     {
+        if (!node.type)
+            throw new Error("Func parameter has no type: " + node);
         node.ePtr = this._createEPtr(node.type);
     }
 }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -51,8 +51,8 @@
     visitFunctionLikeBlock(node)
     {
         for (let i = 0; i < node.argumentList.length; ++i)
-            node.parameters[i].lValue.value = node.argumentList[i].visit(this);
-        return visitFunctionBody(node.block);
+            node.parameters[i].ePtr.copyFrom(node.argumentList[i].visit(this));
+        return this.visitFunctionBody(node.body);
     }
     
     visitReturn(node)

Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -36,7 +36,7 @@
     
     toString()
     {
-        return super.toString() + " { " + this.body + " }";
+        return super.toString() + " " + this.body;
     }
 }
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -37,8 +37,8 @@
             return func;
         
         let instances = this._instances.get(func);
-        if (!functions)
-            this._functions.set(func, functions = []);
+        if (!instances)
+            this._instances.set(func, instances = []);
         
         for (let instance of instances) {
             let ok = true;
@@ -62,7 +62,7 @@
             func.body.visit(substitution));
         let instance = {func: resultingFunc, typeArguments};
         instances.push(instance);
-        return func;
+        return resultingFunc;
     }
 }
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/Inliner.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Inliner.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Inliner.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -35,7 +35,7 @@
     visitCallExpression(node)
     {
         if (node.func.isNative)
-            return node;
+            return super.visitCallExpression(node);
         return this._visiting.doVisit(node.func, () => {
             let func = this._program.funcInstantiator.getUnique(node.func, node.actualTypeArguments);
             _inlineFunction(this._program, func, this._visiting);

Modified: trunk/Tools/WebGPUShadingLanguageRI/Lexer.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Lexer.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Lexer.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -154,4 +154,19 @@
             throw e;
         }
     }
+    
+    testScope(callback)
+    {
+        let state = this.state;
+        try {
+            callback();
+            return true;
+        } catch (e) {
+            if (e instanceof WSyntaxError)
+                return false;
+            throw e;
+        } finally {
+            this.state = state;
+        }
+    }
 }

Modified: trunk/Tools/WebGPUShadingLanguageRI/NameContext.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/NameContext.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/NameContext.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -36,7 +36,8 @@
     {
         this._funcMap = new Map();
         this._map = new Map();
-        this._defined = new Set();
+        this._set = new Set();
+        this._defined = null;
         this._currentStatement = null;
         this._delegate = delegate;
         this._intrinsics = null;
@@ -70,6 +71,7 @@
         }
         
         if (thing.kind == Func) {
+            this._set.add(thing);
             let array = this._funcMap.get(thing.name);
             if (!array)
                 this._funcMap.set(thing.name, array = []);
@@ -78,6 +80,7 @@
         }
         if (this._map.has(thing.name))
             throw new WTypeError(thing.origin.originString, "Duplicate name: " + thing.name);
+        this._set.add(thing);
         this._map.set(thing.name, thing);
     }
     
@@ -100,10 +103,18 @@
         return null;
     }
     
+    handleDefining()
+    {
+        this._defined = new Set();
+    }
+    
     isDefined(thing)
     {
-        return this._defined.has(thing)
-            || (this._delegate && this._delegate.isDefined(thing));
+        if (this._set.has(thing)) {
+            return !this._defined
+                || this._defined.has(thing);
+        }
+        return this._delegate && this._delegate.isDefined(thing);
     }
     
     define(thing)
@@ -113,8 +124,7 @@
     
     defineAll()
     {
-        for (let thing of this)
-            this.define(thing);
+        this._defined = null;
     }
     
     doStatement(statement, callback)

Modified: trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -43,6 +43,7 @@
         let nameContext = new NameContext(this._nameContext);
         nameContext.program = node;
         nameContext.recognizeIntrinsics();
+        nameContext.handleDefining();
         node.intrinsics = nameContext.intrinsics;
         for (let statement of node.topLevelStatements)
             nameContext.add(statement);

Modified: trunk/Tools/WebGPUShadingLanguageRI/Parse.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Parse.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Parse.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -177,9 +177,15 @@
                 lexer.fail("Integer literal is not 32-bit integer");
             return new IntLiteral(token.origin, intVersion);
         }
+        if (token = tryConsumeKind("doubleLiteral")) {
+            token = consumeKind("doubleLiteral");
+            return new DoubleLiteral(token.origin, +token.text);
+        }
         // FIXME: Need support for float literals and probably other literals too.
-        token = consumeKind("doubleLiteral");
-        return new DoubleLiteral(token.origin, +token.text);
+        consume("(");
+        let result = parseExpression();
+        consume(")");
+        return result;
     }
     
     function parseConstexpr()
@@ -336,42 +342,46 @@
                 break;
         }
         consume(")");
-        return new CallExpression(name.origin, name, typeArguments, argumentList);
+        return new CallExpression(name.origin, name.text, typeArguments, argumentList);
     }
     
     function parsePossibleSuffix()
     {
-        let simpleCase = lexer.backtrackingScope(() => {
-            let left = parseTerm();
-            let token;
-            while (token = tryConsume("++", "--", ".", "->", "[")) {
-                switch (token.text) {
-                case "++":
-                case "--":
-                    left = new SuffixCallAssignment(token.origin, "operator" + token.text, left);
-                    break;
-                case ".":
-                case "->":
-                    if (token.text == "->")
-                        left = new DereferenceExpression(token.origin, left);
-                    left = new DotExpression(token.origin, left, consumeKind("identifier"));
-                    break;
-                case "[": {
-                    let index = parseExpression();
-                    consume("]");
-                    left = new IndexExpression(token.origin, left, index);
-                    break;
-                }
-                default:
-                    throw new Error("Bad token: " + token);
-                }
-            }
-            return left;
+        // First check if this is a call _expression_.
+        let isCallExpression = lexer.testScope(() => {
+            consumeKind("identifier");
+            parseTypeArguments();
+            consume("(");
         });
-        if (simpleCase)
-            return simpleCase;
         
-        return parseCallExpression();
+        if (isCallExpression)
+            return parseCallExpression();
+        
+        let left = parseTerm();
+        let token;
+        while (token = tryConsume("++", "--", ".", "->", "[")) {
+            switch (token.text) {
+            case "++":
+            case "--":
+                left = new SuffixCallAssignment(token.origin, "operator" + token.text, left);
+                break;
+            case ".":
+            case "->":
+                if (token.text == "->")
+                    left = new DereferenceExpression(token.origin, left);
+                left = new DotExpression(token.origin, left, consumeKind("identifier"));
+                break;
+            case "[": {
+                let index = parseExpression();
+                consume("]");
+                left = new IndexExpression(token.origin, left, index);
+                break;
+            }
+            default:
+                throw new Error("Bad token: " + token);
+            }
+        }
+        return left;
     }
     
     function parsePossiblePrefix()
@@ -497,7 +507,10 @@
             lexer.fail("Unexpected end of file");
         origin = origin.origin;
         for (;;) {
-            let effectfulExpression = lexer.backtrackingScope(parseEffectfulExpression);
+            let effectfulExpression = lexer.backtrackingScope(() => {
+                parseEffectfulExpression();
+                consume(",");
+            });
             if (!effectfulExpression) {
                 let final = finalExpressionParser();
                 list.push(final);
@@ -504,8 +517,6 @@
                 break;
             }
             list.push(effectfulExpression);
-            if (!tryConsume(","))
-                break;
         }
         return new CommaExpression(origin, list);
     }
@@ -530,7 +541,9 @@
     function parseReturn()
     {
         let origin = consume("return").origin;
-        return new Return(origin, parseExpression());
+        let _expression_ = parseExpression();
+        consume(";");
+        return new Return(origin, _expression_);
     }
     
     function parseVariableDecls()

Modified: trunk/Tools/WebGPUShadingLanguageRI/Program.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Program.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Program.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -58,7 +58,7 @@
     {
         let functions = this.functions.get(name);
         if (!functions)
-            return null;
+            return {failures: []};
         
         return resolveOverloadImpl(functions, typeArguments, argumentTypes);
     }

Modified: trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -68,7 +68,7 @@
             if (!signatures)
                 return false;
             let overload = resolveOverloadImpl(signatures, [], otherSignature.parameterTypes);
-            if (!overload)
+            if (!overload.func)
                 return false;
             let substitutedReturnType =
                 overload.func.returnType.substituteToUnification(

Modified: trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -26,11 +26,16 @@
 
 function resolveOverloadImpl(functions, typeArguments, argumentTypes)
 {
+    let failures = [];
     for (let func of functions) {
-        if (typeArguments.length && typeArguments.length != func.typeParameters.length)
+        if (typeArguments.length && typeArguments.length != func.typeParameters.length) {
+            failures.push({func, reason: "Wrong number of type arguments (passed " + typeArguments.length + ", require " + func.typeParameters.length + ")"});
             continue;
-        if (argumentTypes.length != func.parameters.length)
+        }
+        if (argumentTypes.length != func.parameters.length) {
+            failures.push({func, reason: "Wrong number of arguments (passed " + argumentTypes.length + ", require " + func.parameters.length + ")"});
             continue;
+        }
         let unificationContext = new UnificationContext(func.typeParameters);
         let ok = true;
         for (let i = 0; i < typeArguments.length; ++i) {
@@ -37,6 +42,7 @@
             let argument = typeArguments[i];
             let parameter = func.typeParameters[i];
             if (!argument.unify(unificationContext, parameter)) {
+                failures.push({func, reason: "Type argument #" + (i + 1) + " for parameter " + func.typeParameters.name + " does not match (passed " + argument + ", require " + parameter + ")"});
                 ok = false;
                 break;
             }
@@ -47,6 +53,7 @@
             if (!argumentTypes[i])
                 throw new Error("Null argument type at i = " + i);
             if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type)) {
+                failures.push({func, reason: "Argument #" + (i + 1) + " " + (func.parameters[i].name ? "for parameter " + func.parameters[i].name : "") + " does not match (passed " + argumentTypes[i] + ", require " + func.parameters[i].type + ")"});
                 ok = false;
                 break;
             }
@@ -53,8 +60,10 @@
         }
         if (!ok)
             continue;
-        if (!unificationContext.verify())
+        if (!unificationContext.verify()) {
+            failures.push({func, reason: "Violates type variable constraints"});
             continue;
+        }
         let shouldBuildTypeArguments = !typeArguments.length;
         if (shouldBuildTypeArguments)
             typeArguments = [];
@@ -61,6 +70,7 @@
         for (let typeParameter of func.typeParameters) {
             let typeArgument = unificationContext.find(typeParameter);
             if (typeArgument == typeParameter) {
+                failures.push({func, reason: "Type parameter " + typeParameter + " did not get assigned a type"});
                 ok = false;
                 break;
             }
@@ -72,5 +82,5 @@
         return {func, unificationContext, typeArguments};
     }
     
-    return null;
+    return {failures: failures};
 }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -30,7 +30,7 @@
         this._mapping = new Map();
     }
     
-    _map(oldItem, newItem)
+    _mapNode(oldItem, newItem)
     {
         this._mapping.set(oldItem, newItem);
         return newItem;
@@ -54,8 +54,8 @@
     
     visitFuncParameter(node)
     {
-        let result = new FuncParameter(node.name, node.type.visit(this));
-        this._map(node, result);
+        let result = new FuncParameter(node.origin, node.name, node.type.visit(this));
+        this._mapNode(node, result);
         result.lValue = node.lValue;
         return result;
     }
@@ -151,12 +151,13 @@
         let result = new CallExpression(
             node.origin, node.name,
             node.typeArguments.map(typeArgument => typeArgument.visit(this)),
-            node.argumentlist.map(argument => argument.visit(this)));
+            node.argumentList.map(argument => argument.visit(this)));
         let actualTypeArguments = node.actualTypeArguments;
         if (actualTypeArguments) {
             result.actualTypeArguments =
                 actualTypeArguments.map(actualTypeArgument => actualTypeArgument.visit(this));
         }
+        result.func = node.func;
         return result;
     }
     

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -26,12 +26,37 @@
 
 load("All.js");
 
+function checkInt(result, expected)
 {
-    let program = prepare("<test>", 0, "int foo(int x) { return x + 1; }");
-    let result = callFunction(program, "foo", [], [new EInt(program.intrinsics.int32, 42)]);
     if (!(result instanceof EInt))
         throw new Error("Wrong result type; result: " + result);
-    if (result.value != 43)
-        throw new Error("Wrong result: " + result);
+    if (result.value != expected)
+        throw new Error("Wrong result: " + result + " (expected " + expected + ")");
 }
 
+function TEST_add1() {
+    let program = prepare("<test>", 0, "int foo(int x) { return x + 1; }");
+    checkInt(callFunction(program, "foo", [], [new EInt(program.intrinsics.int32, 42)]), 43);
+}
+
+function TEST_simpleGeneric() {
+    let program = prepare(
+        "<test>", 0,
+        `T id<T>(T x) { return x; }
+         int foo(int x) { return id(x) + 1; }`);
+    checkInt(callFunction(program, "foo", [], [new EInt(program.intrinsics.int32, 42)]), 43);
+}
+
+let before = preciseTime();
+
+for (let s in this) {
+    if (s.startsWith("TEST_")) {
+        print(s + "...");
+        this[s]();
+        print("    OK!");
+    }
+}
+
+let after = preciseTime();
+
+print("That took " + (after - before) * 1000 + " ms.");

Modified: trunk/Tools/WebGPUShadingLanguageRI/TypeVariable.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/TypeVariable.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/TypeVariable.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -60,7 +60,7 @@
         if (realThis != this)
             return realThis.unify(unificationContext, other);
         
-        unificationContext.unify(this, other);
+        unificationContext.union(this, other);
         return true;
     }
     

Modified: trunk/Tools/WebGPUShadingLanguageRI/UnificationContext.js (221433 => 221434)


--- trunk/Tools/WebGPUShadingLanguageRI/UnificationContext.js	2017-08-31 19:20:36 UTC (rev 221433)
+++ trunk/Tools/WebGPUShadingLanguageRI/UnificationContext.js	2017-08-31 19:33:35 UTC (rev 221434)
@@ -33,20 +33,21 @@
     
     union(a, b)
     {
-        a = find(a);
-        b = find(b);
+        a = this.find(a);
+        b = this.find(b);
         if (a == b)
             return;
         
-        if (!b.isUnifiable)
+        if (!a.isUnifiable) {
             [a, b] = [b, a];
-        if (!a.isUnifiable)
-            throw new Error("Cannot unify non-unifiable things " + a + " and " + b);
+            if (!a.isUnifiable)
+                throw new Error("Cannot unify non-unifiable things " + a + " and " + b);
+        }
         
         // Make sure that type parameters don't end up being roots.
         if (a.isUnifiable && b.isUnifiable && this._typeParameters.has(b))
             [a, b] = [b, a];
-
+        
         this._nextMap.set(a, b);
     }
     
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to