Diff
Modified: trunk/Tools/ChangeLog (221836 => 221837)
--- trunk/Tools/ChangeLog 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/ChangeLog 2017-09-10 21:49:13 UTC (rev 221837)
@@ -1,3 +1,131 @@
+2017-09-07 Filip Pizlo <fpi...@apple.com>
+
+ WSL overload resolution should not be cascading
+ https://bugs.webkit.org/show_bug.cgi?id=176333
+
+ Reviewed by Myles Maxfield.
+
+ This removes the cascading nature of overload resolution that WSL used to have, and replaces it with
+ something C++-like. If there are multiple overload candidates that match the callsite, then we resolve
+ them against each other. Anytime a function cannot be resolved onto another function, it is removed,
+ since this means that this function is in some way more general than the other one, and we are just
+ looking for the most specific function.
+
+ If this process ends with only one function being selected, then we succeed, else we fail.
+
+ Also changed the syntax for defining generic casts to:
+
+ operator<T> Thingy<T>(things)
+
+ Also fixed parsing of cast expressions. It's now possible to say a cast _expression_ in WSL.
+
+ The removal of cascading causes some problems. For example, the following two operators in our standard
+ library are ambiguous for bool(bool):
+
+ operator<T> T(T)
+ operator<T:Equatable> bool(T)
+
+ I think that what we really want is to say that the following operators are restricted to the standard
+ library:
+
+ operator<T> T()
+ operator<T> T(T)
+
+ It should not be possible to ever overload these.
+
+ These changes are mostly tested by existing tests and the changes in the standard library, which has to
+ be parsed for every test.
+
+ * WebGPUShadingLanguageRI/All.js:
+ * WebGPUShadingLanguageRI/ArrayRefType.js:
+ (ArrayRefType.prototype.unifyImpl):
+ * WebGPUShadingLanguageRI/CallExpression.js:
+ (CallExpression):
+ (CallExpression.prototype.get isCast):
+ (CallExpression.prototype.get returnType):
+ (CallExpression.prototype.resolve):
+ (CallExpression.prototype.becomeCast):
+ (CallExpression.prototype.setCastData):
+ (CallExpression.prototype.toString):
+ * WebGPUShadingLanguageRI/Checker.js:
+ * WebGPUShadingLanguageRI/Evaluator.js:
+ (Evaluator.prototype.visitLogicalNot):
+ * WebGPUShadingLanguageRI/Func.js:
+ (Func.prototype.get returnTypeForOverloadResolution):
+ * WebGPUShadingLanguageRI/FuncDef.js:
+ (FuncDef):
+ * WebGPUShadingLanguageRI/FuncInstantiator.js:
+ (FuncInstantiator.prototype.getUnique.FindTypeVariable.prototype.visitTypeVariable):
+ (FuncInstantiator.prototype.getUnique.FindTypeVariable):
+ (FuncInstantiator.prototype.getUnique.InstantiationSubstitution.prototype.visitCallExpression):
+ (FuncInstantiator.prototype.getUnique.InstantiationSubstitution):
+ * WebGPUShadingLanguageRI/FunctionLikeBlock.js:
+ (FunctionLikeBlock.prototype.toString):
+ (FunctionLikeBlock):
+ * WebGPUShadingLanguageRI/InferTypesForCall.js: Added.
+ (inferTypesForCall):
+ * WebGPUShadingLanguageRI/Inline.js:
+ (resolveInlinedFunction):
+ * WebGPUShadingLanguageRI/Lexer.js:
+ (Lexer):
+ (Lexer.prototype.next):
+ * WebGPUShadingLanguageRI/NameContext.js:
+ (NameContext):
+ (NameContext.prototype.mapFor):
+ (NameContext.prototype.add):
+ (NameContext.prototype.get let):
+ (NameContext.prototype.Symbol.iterator):
+ (NameContext.get currentStatement): Deleted.
+ * WebGPUShadingLanguageRI/NameResolver.js:
+ (NameResolver.prototype.visitProgram):
+ (NameResolver.prototype.determinePossibleOverloads):
+ (NameResolver.prototype.visitProtocolFuncDecl):
+ (NameResolver.prototype.visitCallExpression):
+ (NameResolver):
+ * WebGPUShadingLanguageRI/NativeFunc.js:
+ (NativeFunc):
+ * WebGPUShadingLanguageRI/Node.js:
+ (Node.prototype.visit):
+ * WebGPUShadingLanguageRI/Parse.js:
+ (parsePossiblePrefix):
+ (parseFuncDecl):
+ (parseNativeFunc):
+ (parseNative):
+ (parsePreferredFuncDef):
+ (parse):
+ * WebGPUShadingLanguageRI/Prepare.js:
+ (prepare):
+ * WebGPUShadingLanguageRI/Program.js:
+ (Program.prototype.resolveFuncOverload): Deleted.
+ (Program.prototype.get nameContext): Deleted.
+ * WebGPUShadingLanguageRI/ProtocolDecl.js:
+ (ProtocolDecl.prototype.inherits):
+ (ProtocolDecl.prototype.hasHeir):
+ * WebGPUShadingLanguageRI/PtrType.js:
+ (PtrType.prototype.unifyImpl):
+ * WebGPUShadingLanguageRI/ResolveOverloadImpl.js:
+ (resolveOverloadImpl):
+ * WebGPUShadingLanguageRI/Rewriter.js:
+ (Rewriter.prototype.visitProtocolFuncDecl):
+ (Rewriter.prototype.processDerivedCallData):
+ (Rewriter.prototype.visitCastExpression): Deleted.
+ * WebGPUShadingLanguageRI/StandardLibrary.js: Added.
+ (preferred.operator.T.T):
+ (operator.T.Equatable.bool):
+ * WebGPUShadingLanguageRI/StandardLibraryEpilogue.js: Removed.
+ * WebGPUShadingLanguageRI/StandardLibraryPrologue.js: Removed.
+ * WebGPUShadingLanguageRI/Test.html:
+ * WebGPUShadingLanguageRI/Test.js:
+ (doLex):
+ (checkUInt):
+ (checkBool):
+ * WebGPUShadingLanguageRI/TypeRef.js:
+ (TypeRef.prototype.toString):
+ (TypeRef):
+ * WebGPUShadingLanguageRI/Visitor.js:
+ (Visitor.prototype.visitCallExpression):
+ (Visitor.prototype.visitCastExpression): Deleted.
+
2017-09-10 Brady Eidson <beid...@apple.com>
Try to avoid creating the default WKWebsiteDataStore until its actually needed.
Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/All.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/All.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -42,7 +42,6 @@
load("CallAssignment.js");
load("CallExpression.js");
load("CallFunction.js");
-load("CastExpression.js");
load("Check.js");
load("CheckLiteralTypes.js");
load("CheckRecursion.js");
@@ -66,6 +65,7 @@
load("FuncParameter.js");
load("FunctionLikeBlock.js");
load("IfStatement.js");
+load("InferTypesForCall.js");
load("Inline.js");
load("Inliner.js");
load("InstantiateImmediates.js");
@@ -101,8 +101,7 @@
load("Return.js");
load("ReturnChecker.js");
load("ReturnException.js");
-load("StandardLibraryEpilogue.js");
-load("StandardLibraryPrologue.js");
+load("StandardLibrary.js");
load("StructLayoutBuilder.js");
load("StructType.js");
load("Substitution.js");
Modified: trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -29,7 +29,10 @@
class ArrayRefType extends ReferenceType {
unifyImpl(unificationContext, other)
{
- if (!(other instanceof ArrayRefType)) {
+ if (other instanceof ArrayRefType) {
+ if (this.addressSpace != other.addressSpace)
+ return false;
+ } else {
if (!(other instanceof ArrayType))
return false;
if (this.addressSpace != "thread")
Modified: trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -32,16 +32,20 @@
this._typeArguments = typeArguments;
this._argumentList = argumentList;
this.func = null;
+ this._isCast = false;
+ this._returnType = null;
}
get name() { return this._name; }
get typeArguments() { return this._typeArguments; }
get argumentList() { return this._argumentList; }
+ get isCast() { return this._isCast; }
+ get returnType() { return this._returnType; }
resolve(overload)
{
this.func = overload.func;
- this.actualTypeArguments = overload.typeArguments;
+ this.actualTypeArguments = overload.typeArguments.map(TypeRef.wrap);
let result = overload.func.returnType.substituteToUnification(
overload.func.typeParameters, overload.unificationContext);
if (!result)
@@ -49,9 +53,27 @@
return result;
}
+ becomeCast(returnType)
+ {
+ this._returnType = new TypeRef(this.origin, this.name, this._typeArguments);
+ this._returnType.type = returnType;
+ this._name = "operator cast";
+ this._isCast = true;
+ this._typeArguments = [];
+ }
+
+ setCastData(returnType)
+ {
+ this._returnType = returnType;
+ this._isCast = true;
+ }
+
toString()
{
- return this.name + "<" + this.typeArguments + ">(" + this.argumentList + ")";
+ return (this.isCast ? "operator " + this.returnType : this.name) +
+ "<" + this.typeArguments + ">" +
+ (this.actualTypeArguments ? "<<" + this.actualTypeArguments + ">>" : "") +
+ "(" + this.argumentList + ")";
}
}
Deleted: trunk/Tools/WebGPUShadingLanguageRI/CastExpression.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/CastExpression.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/CastExpression.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -1,46 +0,0 @@
-/*
- * 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";
-
-// This is a bit of a misnomer, as this represents casts as well as constructors.
-// Syntactically they are identical; a cast just takes one argument whereas a
-// constructor takes 0-n.
-class CastExpression extends CallExpression {
- constructor(origin, returnType, typeArguments, argumentList)
- {
- super(origin, CastExpression.functionName, typeArguments, argumentList);
- this._returnType = returnType;
- }
-
- static get functionName() { return "operator cast"; }
-
- get returnType() { return this._returnType; }
-
- toString()
- {
- return this.returnType + "<" + this.typeArguments + ">(" + this.argumentList + ")";
- }
-}
-
Modified: trunk/Tools/WebGPUShadingLanguageRI/Checker.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Checker.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Checker.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -246,7 +246,7 @@
return result;
}
- checkCastOrCallExpression(node, returnType)
+ visitCallExpression(node)
{
for (let typeArgument of node.typeArguments)
typeArgument.visit(this);
@@ -257,8 +257,8 @@
return TypeRef.wrap(newArgument);
});
node.argumentTypes = argumentTypes;
- if (returnType)
- returnType.visit(this);
+ if (node.returnType)
+ node.returnType.visit(this);
let overload = null;
let failures = [];
@@ -271,7 +271,7 @@
typeParameter.protocol.protocolDecl.signaturesByNameWithTypeVariable(node.name, typeParameter);
if (!signatures)
continue;
- overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes, returnType);
+ overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes, node.returnType);
if (overload.func)
break;
failures.push(...overload.failures);
@@ -278,11 +278,16 @@
overload = null;
}
if (!overload) {
- overload = this._program.resolveFuncOverload(
- node.name, node.typeArguments, argumentTypes, returnType);
+ overload = resolveOverloadImpl(
+ node.possibleOverloads, node.typeArguments, argumentTypes, node.returnType);
if (!overload.func) {
failures.push(...overload.failures);
- let message = "Did not find function for call";
+ let message = "Did not find function for call with ";
+ if (node.typeArguments.length)
+ message += "type arguments <" + node.typeArguments + "> and ";
+ message += "argument types (" + argumentTypes + ")";
+ if (node.returnType)
+ message +=" and return type " + node.returnType;
if (failures.length)
message += ", but considered:\n" + failures.join("\n")
throw new WTypeError(node.origin.originString, message);
@@ -298,15 +303,5 @@
}
return node.resolve(overload);
}
-
- visitCastExpression(node)
- {
- return this.checkCastOrCallExpression(node, node.returnType);
- }
-
- visitCallExpression(node)
- {
- return this.checkCastOrCallExpression(node, undefined);
- }
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -148,7 +148,8 @@
visitLogicalNot(node)
{
- return EPtr.box(!node.operand.visit(this).loadValue());
+ let result = !node.operand.visit(this).loadValue();
+ return EPtr.box(result);
}
visitIfStatement(node)
Modified: trunk/Tools/WebGPUShadingLanguageRI/Func.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Func.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Func.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -45,6 +45,7 @@
get parameters() { return this._parameters; }
get parameterTypes() { return this.parameters.map(parameter => parameter.type); }
get isCast() { return this._isCast; }
+ get returnTypeForOverloadResolution() { return this.isCast ? this.returnType : null; }
get kind() { return Func; }
Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncDef.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -29,6 +29,7 @@
{
super(origin, name, returnType, typeParameters, parameters, isCast);
this._body = body;
+ this.isRestricted = false;
}
get body() { return this._body; }
Modified: trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -38,6 +38,14 @@
// resolutions on the original Program.
getUnique(func, typeArguments)
{
+ class FindTypeVariable extends Visitor {
+ visitTypeVariable(node) {
+ throw new Error("Unexpected type variable: " + node);
+ }
+ }
+ for (let typeArgument of typeArguments)
+ typeArgument.visit(new FindTypeVariable());
+
let instances = this._instances.get(func);
if (!instances)
this._instances.set(func, instances = []);
@@ -64,7 +72,7 @@
// 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(result.name, result.typeArguments, result.argumentTypes);
+ let overload = resolveOverloadImpl(result.possibleOverloads, result.typeArguments, result.argumentTypes, result.returnTypeForOverloadResolution);
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);
Modified: trunk/Tools/WebGPUShadingLanguageRI/FunctionLikeBlock.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/FunctionLikeBlock.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/FunctionLikeBlock.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -43,6 +43,6 @@
toString()
{
- return "([&] (" + this.parameters + ") -> " + this.returnType + " { " + this.block + " }(" + this.argumentList + "))";
+ return "([&] (" + this.parameters + ") -> " + this.returnType + " { " + this.body + " }(" + this.argumentList + "))";
}
}
Added: trunk/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js (0 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/InferTypesForCall.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -0,0 +1,62 @@
+/*
+ * 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";
+
+function inferTypesForCall(func, typeArguments, argumentTypes, returnType)
+{
+ if (typeArguments.length && typeArguments.length != func.typeParameters.length)
+ return {failure: new OverloadResolutionFailure(func, "Wrong number of type arguments (passed " + typeArguments.length + ", require " + func.typeParameters.length + ")")};
+ if (argumentTypes.length != func.parameters.length)
+ return {failure: new OverloadResolutionFailure(func, "Wrong number of arguments (passed " + argumentTypes.length + ", require " + func.parameters.length + ")")};
+ let unificationContext = new UnificationContext(func.typeParameters);
+ for (let i = 0; i < typeArguments.length; ++i) {
+ let argument = typeArguments[i];
+ let parameter = func.typeParameters[i];
+ if (!argument.unify(unificationContext, parameter))
+ return {failure: new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + parameter.name + " does not match (passed " + argument + ", require " + parameter + ")")};
+ }
+ for (let i = 0; i < argumentTypes.length; ++i) {
+ if (!argumentTypes[i])
+ throw new Error("Null argument type at i = " + i);
+ if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type))
+ return {failure: new OverloadResolutionFailure(func, "Argument #" + (i + 1) + " " + (func.parameters[i].name ? "for parameter " + func.parameters[i].name : "") + " does not match (passed " + argumentTypes[i] + ", require " + func.parameters[i].type + ")")};
+ }
+ if (returnType && !returnType.unify(unificationContext, func.returnType))
+ return {failure: new OverloadResolutionFailure(func, "Return type " + func.returnType + " does not match " + returnType)};
+ if (!unificationContext.verify())
+ return {failure: new OverloadResolutionFailure(func, "Violates type variable constraints")};
+ let shouldBuildTypeArguments = !typeArguments.length;
+ if (shouldBuildTypeArguments)
+ typeArguments = [];
+ for (let typeParameter of func.typeParameters) {
+ let typeArgument = unificationContext.find(typeParameter);
+ if (typeArgument == typeParameter)
+ return {failure: new OverloadResolutionFailure(func, "Type parameter " + typeParameter + " did not get assigned a type")};
+ if (shouldBuildTypeArguments)
+ typeArguments.push(typeArgument);
+ }
+ return {func, unificationContext, typeArguments};
+}
+
Modified: trunk/Tools/WebGPUShadingLanguageRI/Inline.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Inline.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Inline.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -57,7 +57,7 @@
function resolveInlinedFunction(program, name, typeArguments, argumentTypes)
{
- let overload = program.resolveFuncOverload(name, typeArguments, argumentTypes);
+ let overload = program.globalNameContext.resolveFuncOverload(name, typeArguments, argumentTypes);
if (!overload.func)
return overload.failures;
if (!overload.func.typeParameters)
Modified: trunk/Tools/WebGPUShadingLanguageRI/Lexer.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Lexer.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Lexer.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -25,9 +25,10 @@
"use strict";
class Lexer {
- constructor(origin, lineNumberOffset, text)
+ constructor(origin, originKind, lineNumberOffset, text)
{
this._origin = origin;
+ this._originKind = originKind;
this._lineNumberOffset = lineNumberOffset;
this._text = text;
this._index = 0;
@@ -103,8 +104,12 @@
// FIXME: Make this do Unicode.
if (/^[^\d\W]\w*/.test(relevantText)) {
- if (["struct", "protocol", "typedef", "if", "else", "enum", "continue", "break", "switch", "case", "default", "for", "while", "do", "return", "sizeof", "constant", "device", "threadgroup", "thread", "operator", "null", "true", "false"].includes(RegExp.lastMatch))
+ if (/^(struct|protocol|typedef|if|else|enum|continue|break|switch|case|default|for|while|do|return|constant|device|threadgroup|thread|operator|null|true|false)$/.test(RegExp.lastMatch))
return result("keyword");
+
+ if (this._originKind == "native" && /^(native|restricted)$/.test(RegExp.lastMatch))
+ return result("keyword");
+
return result("identifier");
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/NameContext.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/NameContext.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/NameContext.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -34,7 +34,6 @@
class NameContext {
constructor(delegate)
{
- this._funcMap = new Map();
this._map = new Map();
this._set = new Set();
this._defined = null;
@@ -51,9 +50,8 @@
case Value:
case Type:
case Protocol:
+ case Func:
return this._map;
- case Func:
- return this._funcMap;
default:
throw new Error("Bad kind: " + kind);
}
@@ -72,9 +70,14 @@
if (thing.kind == Func) {
this._set.add(thing);
- let array = this._funcMap.get(thing.name);
- if (!array)
- this._funcMap.set(thing.name, array = []);
+ let array = this._map.get(thing.name);
+ if (!array) {
+ array = [];
+ array.kind = Func;
+ this._map.set(thing.name, array);
+ }
+ if (array.kind != Func)
+ throw new WTypeError(thing.origin.originString, "Cannot reuse type name for function: " + thing.name);
array.push(thing);
return;
}
@@ -94,6 +97,15 @@
return result;
}
+ resolveFuncOverload(name, typeArguments, argumentTypes, returnType)
+ {
+ let functions = this.get(Func, name);
+ if (!functions)
+ return {failures: []};
+
+ return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType);
+ }
+
get currentStatement()
{
if (this._currentStatement)
@@ -165,11 +177,13 @@
*[Symbol.iterator]()
{
- for (let value of this._map.values())
+ for (let value of this._map.values()) {
+ if (value instanceof Array) {
+ for (let func of value)
+ yield func;
+ continue;
+ }
yield value;
- for (let funcs of this._funcMap.values()) {
- for (let func of funcs)
- yield func;
}
}
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/NameResolver.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -50,6 +50,7 @@
let checker = new NameResolver(nameContext);
for (let statement of node.topLevelStatements)
nameContext.doStatement(statement, () => statement.visit(checker));
+ node.globalNameContext = nameContext;
}
_visitTypeParametersAndBuildNameContext(node)
@@ -117,6 +118,15 @@
node.protocolDecl = result;
}
+ visitProtocolFuncDecl(node)
+ {
+ this.visitFunc(node);
+ let funcs = this._nameContext.get(Func, node.name);
+ if (!funcs)
+ throw new WTypeError(node.origin.originString, "Cannot find any functions named " + node.na,e);
+ node.possibleOverloads = funcs;
+ }
+
visitTypeDef(node)
{
let nameContext = new NameContext(this._nameContext);
@@ -218,6 +228,20 @@
visitCallExpression(node)
{
this._resolveTypeArguments(node.typeArguments);
+
+ let funcs = this._nameContext.get(Func, node.name);
+ if (funcs)
+ node.possibleOverloads = funcs;
+ else {
+ let type = this._nameContext.get(Type, node.name);
+ if (!type)
+ throw new WTypeError(node.origin.originString, "Cannot find any function or type named " + node.name);
+ node.becomeCast(type);
+ node.possibleOverloads = this._nameContext.get(Func, "operator cast");
+ if (!node.possibleOverloads)
+ throw new WTypeError(node.origin.originString, "Cannot find any operator cast implementations in cast to " + type);
+ }
+
super.visitCallExpression(node);
}
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -28,6 +28,7 @@
constructor(origin, name, returnType, typeParameters, parameters, isCast)
{
super(origin, name, returnType, typeParameters, parameters, isCast);
+ this.isRestricted = false;
}
get isNative() { return true; }
Modified: trunk/Tools/WebGPUShadingLanguageRI/Node.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Node.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Node.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -27,10 +27,6 @@
class Node {
visit(visitor)
{
- let memoTable = visitor._memoTable;
- if (memoTable.has(this))
- return memoTable.get(this);
-
let visitFunc = visitor["visit" + this.constructor.name];
if (!visitFunc)
throw new Error("No visit function for " + this.constructor.name + " in " + visitor.constructor.name);
@@ -37,7 +33,6 @@
let returnValue = visitFunc.call(visitor, this);
if ("returnValue" in visitor)
returnValue = visitor.returnValue;
- memoTable.set(this, returnValue);
return returnValue;
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/Parse.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Parse.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Parse.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -24,9 +24,9 @@
*/
"use strict";
-function parse(program, origin, lineNumberOffset, text)
+function parse(program, origin, originKind, lineNumberOffset, text)
{
- let lexer = new Lexer(origin, lineNumberOffset, text);
+ let lexer = new Lexer(origin, originKind, lineNumberOffset, text);
// The hardest part of dealing with C-like languages is parsing variable declaration statements.
// Let's consider if this happens in WSL. Here are the valid statements in WSL that being with an
@@ -382,7 +382,7 @@
return new MakeArrayRefExpression(token, parsePossiblePrefix());
if (token = tryConsume("!")) {
let remainder = parsePossiblePrefix();
- return new LogicalNot(token, new CastExpression(remainder.origin, new TypeRef(remainder.origin, "bool", []), [], [remainder]));
+ return new LogicalNot(token, new CallExpression(remainder.origin, "bool", [], [remainder]));
}
return parsePossibleSuffix();
}
@@ -546,7 +546,7 @@
let elseBody;
if (tryConsume("else"))
elseBody = parseStatement();
- return new IfStatement(origin, new CastExpression(conditional.origin, new TypeRef(conditional.origin, "bool", []), [], [conditional]), body, elseBody);
+ return new IfStatement(origin, new CallExpression(conditional.origin, "bool", [], [conditional]), body, elseBody);
}
function parseVariableDecls()
@@ -644,20 +644,22 @@
let origin;
let returnType;
let name;
+ let typeParameters;
let isCast;
let operatorToken = tryConsume("operator");
if (operatorToken) {
origin = operatorToken;
+ typeParameters = parseTypeParameters();
returnType = parseType();
- name = CastExpression.functionName;
+ name = "operator cast";
isCast = true;
} else {
returnType = parseType();
origin = returnType.origin;
name = parseFuncName();
+ typeParameters = parseTypeParameters();
isCast = false;
}
- let typeParameters = parseTypeParameters();
let parameters = parseParameters();
return new Func(origin, name, returnType, typeParameters, parameters, isCast);
}
@@ -710,6 +712,13 @@
return result;
}
+ function parseNativeFunc()
+ {
+ let func = parseFuncDecl();
+ consume(";");
+ return new NativeFunc(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast);
+ }
+
function parseNative()
{
let origin = consume("native");
@@ -726,11 +735,21 @@
consume(";");
return new NativeType(origin, name.text, isType == "primitive", parameters);
}
- let func = parseFuncDecl();
- consume(";");
- return new NativeFunc(func.origin, func.name, func.returnType, func.typeParameters, func.parameters, func.isCast);
+ return parseNativeFunc();
}
+ function parseRestrictedFuncDef()
+ {
+ consume("restricted");
+ let result;
+ if (tryConsume("native"))
+ result = parseNativeFunc();
+ else
+ result = parseFuncDef();
+ result.isRestricted = true;
+ return result;
+ }
+
for (;;) {
let token = lexer.peek();
if (!token)
@@ -739,8 +758,10 @@
lexer.next();
else if (token.text == "typedef")
program.add(parseTypeDef());
- else if (token.text == "native")
+ else if (originKind == "native" && token.text == "native")
program.add(parseNative());
+ else if (originKind == "native" && token.text == "restricted")
+ program.add(parseRestrictedFuncDef());
else if (token.text == "struct")
program.add(parseStructType());
else if (token.text == "enum")
Modified: trunk/Tools/WebGPUShadingLanguageRI/Prepare.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Prepare.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Prepare.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -27,9 +27,8 @@
function prepare(origin, lineNumberOffset, text)
{
let program = new Program();
- parse(program, "/internal/stdlib/prologue", 28, standardLibraryPrologue);
- parse(program, origin, lineNumberOffset, text);
- parse(program, "/internal/stdlib/epilogue", 28, standardLibraryEpilogue);
+ parse(program, "/internal/stdlib", "native", 27, standardLibrary);
+ parse(program, origin, "user", lineNumberOffset, text);
resolveNames(program);
resolveTypeDefs(program);
check(program);
Modified: trunk/Tools/WebGPUShadingLanguageRI/Program.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Program.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Program.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -58,23 +58,6 @@
this._topLevelStatements.push(statement);
}
- resolveFuncOverload(name, typeArguments, argumentTypes, returnType)
- {
- let functions = this.functions.get(name);
- if (!functions)
- return {failures: []};
-
- return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType);
- }
-
- get nameContext()
- {
- let result = new NameContext();
- for (let statement of this.topLevelStatements)
- result.add(statement);
- return result;
- }
-
toString()
{
if (!this._topLevelStatements.length)
Modified: trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/ProtocolDecl.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -72,7 +72,7 @@
let signatures = this.signaturesByName(otherSignature.name);
if (!signatures)
return false;
- let overload = resolveOverloadImpl(signatures, [], otherSignature.parameterTypes);
+ let overload = resolveOverloadImpl(signatures, [], otherSignature.parameterTypes, otherSignature.returnTypeForOverloadResolution);
if (!overload.func)
return false;
let substitutedReturnType =
@@ -90,7 +90,7 @@
let signatures = this.signatures;
for (let signature of signatures) {
signature = signature.visit(substitution);
- let overload = this.program.resolveFuncOverload(signature.name, signature.typeParameters, signature.parameterTypes);
+ let overload = resolveOverloadImpl(signature.possibleOverloads, signature.typeParameters, signature.parameterTypes, signature.returnTyupeForOverloadResolution);
if (!overload.func)
return false;
Modified: trunk/Tools/WebGPUShadingLanguageRI/PtrType.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/PtrType.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/PtrType.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -31,6 +31,8 @@
{
if (!(other instanceof PtrType))
return false;
+ if (this.addressSpace != other.addressSpace)
+ return false;
return this.elementType.unify(unificationContext, other.elementType);
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -27,66 +27,69 @@
function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType)
{
let failures = [];
+ let successes = [];
for (let func of functions) {
- if (typeArguments.length && typeArguments.length != func.typeParameters.length) {
- failures.push(new OverloadResolutionFailure(func, "Wrong number of type arguments (passed " + typeArguments.length + ", require " + func.typeParameters.length + ")"));
- continue;
+ let overload = inferTypesForCall(func, typeArguments, argumentTypes, returnType);
+ if (overload.failure)
+ failures.push(overload.failure);
+ else
+ successes.push(overload);
+ }
+
+ if (!successes.length)
+ return {failures: failures};
+
+ // If any of the signatures are restricted then we consider those first. This is an escape mechanism for
+ // built-in things.
+ // FIXME: It should be an error to declare a function that is at least as specific as a restricted function.
+ // https://bugs.webkit.org/show_bug.cgi?id=176580
+ let hasRestricted = false;
+ for (let overload of successes) {
+ if (overload.func.isRestricted) {
+ hasRestricted = true;
+ break;
}
- if (argumentTypes.length != func.parameters.length) {
- failures.push(new OverloadResolutionFailure(func, "Wrong number of arguments (passed " + argumentTypes.length + ", require " + func.parameters.length + ")"));
- continue;
- }
- let unificationContext = new UnificationContext(func.typeParameters);
+ }
+
+ if (hasRestricted)
+ successes = successes.filter(overload => overload.func.isRestricted);
+
+ // We are only interested in functions that are at least as specific as all of the others. This means
+ // that they can be "turned around" and applied onto all of the other functions in the list.
+ let prunedSuccesses = [];
+ for (let i = 0; i < successes.length; ++i) {
let ok = true;
- for (let i = 0; i < typeArguments.length; ++i) {
- let argument = typeArguments[i];
- let parameter = func.typeParameters[i];
- if (!argument.unify(unificationContext, parameter)) {
- failures.push(new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + parameter.name + " does not match (passed " + argument + ", require " + parameter + ")"));
- ok = false;
- break;
- }
- }
- if (!ok)
- continue;
- for (let i = 0; i < argumentTypes.length; ++i) {
- if (!argumentTypes[i])
- throw new Error("Null argument type at i = " + i);
- if (!argumentTypes[i].unify(unificationContext, func.parameters[i].type)) {
- failures.push(new OverloadResolutionFailure(func, "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;
- }
- }
- if (!ok)
- continue;
- if (returnType) {
- if (!returnType.unify(unificationContext, func.returnType)) {
- failures.push(new OverloadResolutionFailure(func, "Return type " + func.returnType + " does not match " + returnType));
+ let argumentFunc = successes[i].func;
+ for (let j = 0; j < successes.length; ++j) {
+ if (i == j)
continue;
- }
- }
- if (!unificationContext.verify()) {
- failures.push(new OverloadResolutionFailure(func, "Violates type variable constraints"));
- continue;
- }
- let shouldBuildTypeArguments = !typeArguments.length;
- if (shouldBuildTypeArguments)
- typeArguments = [];
- for (let typeParameter of func.typeParameters) {
- let typeArgument = unificationContext.find(typeParameter);
- if (typeArgument == typeParameter) {
- failures.push(new OverloadResolutionFailure(func, "Type parameter " + typeParameter + " did not get assigned a type"));
+ let parameterFunc = successes[j].func;
+ let overload = inferTypesForCall(
+ parameterFunc,
+ typeArguments.length ? argumentFunc.typeParameters : [],
+ argumentFunc.parameterTypes,
+ argumentFunc.returnTypeForOverloadResolution);
+ if (!overload.func) {
ok = false;
break;
}
- if (shouldBuildTypeArguments)
- typeArguments.push(typeArgument);
}
- if (!ok)
- continue;
- return {func, unificationContext, typeArguments};
+ if (ok)
+ prunedSuccesses.push(successes[i]);
}
- return {failures: failures};
+ if (prunedSuccesses.length == 1)
+ return prunedSuccesses[0];
+
+ let ambiguityList;
+ let message;
+ if (prunedSuccesses.length == 0) {
+ ambiguityList = successes;
+ message = "Ambiguous overload - no function can be applied to all others";
+ } else {
+ ambiguityList = prunedSuccesses;
+ message = "Ambiguous overload - functions mutually applicable";
+ }
+
+ return {failures: ambiguityList.map(overload => new OverloadResolutionFailure(overload.func, message))};
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -74,6 +74,7 @@
node.typeParameters.map(parameter => parameter.visit(this)),
node.parameters.map(parameter => parameter.visit(this)));
result.protocolDecl = node.protocolDecl;
+ result.possibleOverloads = node.possibleOverloads;
return result;
}
@@ -249,18 +250,12 @@
result.argumentTypes = argumentTypes.map(argumentType => argumentType.visit(this));
result.func = node.func;
result.nativeFuncInstance = node.nativeFuncInstance;
+ result.possibleOverloads = node.possibleOverloads;
+ if (node.isCast)
+ result.setCastData(node.returnType.visit(this));
return result;
}
- visitCastExpression(node)
- {
- let result = new CastExpression(
- node.origin, node.returnType.visit(this),
- node.typeArguments.map(typeArgument => typeArgument.visit(this)),
- node.argumentList.map(argument => argument.visit(this)));
- return this.processDerivedCallData(node, result);
- }
-
visitCallExpression(node)
{
let result = new CallExpression(
Added: trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js (0 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -0,0 +1,80 @@
+/*
+ * 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";
+
+// NOTE: The next line is line 28, and we rely on this in Prepare.js.
+const standardLibrary = `
+// This is the WSL standard library. Implementations of all of these things are in
+// Intrinsics.js. The only thing that gets defined before we get here is the primitive
+// protocol.
+
+// Need to bootstrap void first.
+native primitive typedef void;
+
+native primitive typedef int32;
+native primitive typedef uint32;
+native primitive typedef bool;
+typedef int = int32;
+typedef uint = uint32;
+
+native primitive typedef double;
+
+native int operator+(int, int);
+native uint operator+(uint, uint);
+native int operator-(int, int);
+native uint operator-(uint, uint);
+native int operator*(int, int);
+native uint operator*(uint, uint);
+native int operator/(int, int);
+native uint operator/(uint, uint);
+native bool operator==(int, int);
+native bool operator==(uint, uint);
+native bool operator==(bool, bool);
+
+protocol Equatable {
+ bool operator==(Equatable, Equatable);
+}
+
+restricted operator<T> T()
+{
+ T defaultValue;
+ return defaultValue;
+}
+
+restricted operator<T> T(T x)
+{
+ return x;
+}
+
+operator<T:Equatable> bool(T x)
+{
+ return x != T();
+}
+
+native thread T^ operator&[]<T>(thread T[], uint);
+native threadgroup T^ operator&[]<T:primitive>(threadgroup T[], uint);
+native device T^ operator&[]<T:primitive>(device T[], uint);
+native constant T^ operator&[]<T:primitive>(constant T[], uint);
+`;
Deleted: trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryEpilogue.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryEpilogue.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryEpilogue.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -1,33 +0,0 @@
-/*
- * 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";
-
-// NOTE: The next line is line 28, and we rely on this in Prepare.js.
-const standardLibraryEpilogue = `
-operator bool<><T:Equatable>(T x) {
- T defaultValue;
- return x != defaultValue;
-}
-`;
Deleted: trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryPrologue.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryPrologue.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/StandardLibraryPrologue.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -1,68 +0,0 @@
-/*
- * 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";
-
-// NOTE: The next line is line 28, and we rely on this in Prepare.js.
-const standardLibraryPrologue = `
-// This is the WSL standard library. Implementations of all of these things are in
-// Intrinsics.js. The only thing that gets defined before we get here is the primitive
-// protocol.
-
-// Need to bootstrap void first.
-native primitive typedef void;
-
-native primitive typedef int32;
-native primitive typedef uint32;
-native primitive typedef bool;
-typedef int = int32;
-typedef uint = uint32;
-
-native primitive typedef double;
-
-native int operator+(int, int);
-native uint operator+(uint, uint);
-native int operator-(int, int);
-native uint operator-(uint, uint);
-native int operator*(int, int);
-native uint operator*(uint, uint);
-native int operator/(int, int);
-native uint operator/(uint, uint);
-native bool operator==(int, int);
-native bool operator==(uint, uint);
-native bool operator==(bool, bool);
-
-protocol Equatable {
- bool operator==(Equatable, Equatable);
-}
-
-operator T<><T>(T x) {
- return x;
-}
-
-native thread T^ operator&[]<T>(thread T[], uint);
-native threadgroup T^ operator&[]<T:primitive>(threadgroup T[], uint);
-native device T^ operator&[]<T:primitive>(device T[], uint);
-native constant T^ operator&[]<T:primitive>(constant T[], uint);
-`;
Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.html (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Test.html 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.html 2017-09-10 21:49:13 UTC (rev 221837)
@@ -18,7 +18,6 @@
<script src=""
<script src=""
<script src=""
-<script src=""
<script src=""
<script src=""
<script src=""
@@ -42,6 +41,7 @@
<script src=""
<script src=""
<script src=""
+<script src=""
<script src=""
<script src=""
<script src=""
@@ -77,8 +77,7 @@
<script src=""
<script src=""
<script src=""
-<script src=""
-<script src=""
+<script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Test.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -41,7 +41,7 @@
function doLex(code)
{
- let lexer = new Lexer("/internal/test", 0, code);
+ let lexer = new Lexer("/internal/test", "native", 0, code);
var result = [];
for (;;) {
let next = lexer.next();
@@ -85,17 +85,17 @@
function checkUInt(program, result, expected)
{
if (!result.type.equals(program.intrinsics.uint32))
- throw new Error("Wrong result type; result: " + result);
+ throw new Error("Wrong result type: " + result.type);
if (result.value != expected)
- throw new Error("Wrong result: " + result + " (expected " + expected + ")");
+ throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
}
function checkBool(program, result, expected)
{
if (!result.type.equals(program.intrinsics.bool))
- throw new Error("Wrong result type; result: " + result);
+ throw new Error("Wrong result type: " + result.type);
if (result.value != expected)
- throw new Error("Wrong result: " + result + " (expected " + expected + ")");
+ throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
}
function checkLexerToken(result, expectedIndex, expectedKind, expectedText)
@@ -1368,6 +1368,38 @@
(e) => e instanceof WTypeError);
}
+function TEST_ambiguousOverloadSimple()
+{
+ checkFail(
+ () => doPrep(`
+ void foo<T>(int, T) { }
+ void foo<T>(T, int) { }
+ void bar(int a, int b) { foo(a, b); }
+ `),
+ (e) => e instanceof WTypeError);
+}
+
+function TEST_ambiguousOverloadOverlapping()
+{
+ checkFail(
+ () => doPrep(`
+ void foo<T>(int, T) { }
+ void foo<T>(T, T) { }
+ void bar(int a, int b) { foo(a, b); }
+ `),
+ (e) => e instanceof WTypeError);
+}
+
+function TEST_ambiguousOverloadTieBreak()
+{
+ doPrep(`
+ void foo<T>(int, T) { }
+ void foo<T>(T, T) { }
+ void foo(int, int) { }
+ void bar(int a, int b) { foo(a, b); }
+ `);
+}
+
let filter = /.*/; // run everything by default
if (this["arguments"]) {
for (let i = 0; i < arguments.length; i++) {
Modified: trunk/Tools/WebGPUShadingLanguageRI/TypeRef.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/TypeRef.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/TypeRef.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -116,6 +116,8 @@
toString()
{
+ if (!this.name)
+ return this.type.toString();
if (!this.typeArguments.length)
return this.name;
return this.name + "<" + this.typeArguments + ">";
Modified: trunk/Tools/WebGPUShadingLanguageRI/Visitor.js (221836 => 221837)
--- trunk/Tools/WebGPUShadingLanguageRI/Visitor.js 2017-09-10 19:00:03 UTC (rev 221836)
+++ trunk/Tools/WebGPUShadingLanguageRI/Visitor.js 2017-09-10 21:49:13 UTC (rev 221837)
@@ -263,14 +263,10 @@
for (let argument of actualTypeArguments)
argument.visit(this);
}
+ if (node.returnType)
+ node.returnType.visit(this);
}
- visitCastExpression(node)
- {
- this.visitCallExpression(node);
- node.returnType.visit(this);
- }
-
visitLogicalNot(node)
{
node.operand.visit(this);