https://bugs.webkit.org/show_bug.cgi?id=177120
Reviewed by Myles Maxfield.
It turns out that we still need to instantiate structs even if not passing type arguments,
since its fields may need to be instantiated.
This makes Myles's test case pass. When writing the test case, I encountered parser bugs, and
I fixed them.
* WebGPUShadingLanguageRI/CallFunction.js:
(callFunction):
* WebGPUShadingLanguageRI/Checker.js:
(Checker.prototype.visitReferenceType):
* WebGPUShadingLanguageRI/FuncInstantiator.js:
(FuncInstantiator.prototype.getUnique):
(FuncInstantiator):
* WebGPUShadingLanguageRI/Parse.js:
(parseSuffixOperator):
(parsePossibleSuffix):
(parsePostIncrement):
* WebGPUShadingLanguageRI/StructType.js:
(StructType.prototype.instantiate):
* WebGPUShadingLanguageRI/Test.js:
(checkNumber):
(checkEnum):
(TEST_instantiateStructInStruct):
* WebGPUShadingLanguageRI/TypeRef.js:
(TypeRef.prototype.get instantiatedType):
(TypeRef.prototype.get isPrimitive):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@222201
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
2017-09-18 Filip Pizlo <fpizlo@apple.com>
+ [WSL] Cannot put templated structs inside structs
+ https://bugs.webkit.org/show_bug.cgi?id=177120
+
+ Reviewed by Myles Maxfield.
+
+ It turns out that we still need to instantiate structs even if not passing type arguments,
+ since its fields may need to be instantiated.
+
+ This makes Myles's test case pass. When writing the test case, I encountered parser bugs, and
+ I fixed them.
+
+ * WebGPUShadingLanguageRI/CallFunction.js:
+ (callFunction):
+ * WebGPUShadingLanguageRI/Checker.js:
+ (Checker.prototype.visitReferenceType):
+ * WebGPUShadingLanguageRI/FuncInstantiator.js:
+ (FuncInstantiator.prototype.getUnique):
+ (FuncInstantiator):
+ * WebGPUShadingLanguageRI/Parse.js:
+ (parseSuffixOperator):
+ (parsePossibleSuffix):
+ (parsePostIncrement):
+ * WebGPUShadingLanguageRI/StructType.js:
+ (StructType.prototype.instantiate):
+ * WebGPUShadingLanguageRI/Test.js:
+ (checkNumber):
+ (checkEnum):
+ (TEST_instantiateStructInStruct):
+ * WebGPUShadingLanguageRI/TypeRef.js:
+ (TypeRef.prototype.get instantiatedType):
+ (TypeRef.prototype.get isPrimitive):
+
+2017-09-18 Filip Pizlo <fpizlo@apple.com>
+
WSL should support enum
https://bugs.webkit.org/show_bug.cgi?id=176977
func.parameters[i].ePtr.copyFrom(argumentList[i].ePtr, type.size);
}
let result = new Evaluator(program).runFunc(func);
- return new TypedValue(func.returnType.unifyNode, result);
+ return new TypedValue(func.uninstantiatedReturnType, result);
}
if (node.addressSpace == "thread")
return;
- if (!node.elementType.instantiatedType.isPrimitive)
+ let instantiatedType = node.elementType.instantiatedType;
+ if (!instantiatedType.isPrimitive)
throw new WTypeError(node.origin.originString, "Illegal pointer to non-primitive type: " + node.elementType + " (instantiated to " + node.elementType.instantiatedType + ")");
}
}
}
let resultingFunc = func.visit(new Instantiate());
+ resultingFunc.uninstantiatedReturnType = func.returnType.visit(substitution);
let instance = {func: resultingFunc, typeArguments};
instances.push(instance);
return resultingFunc;
return readModifyWrite;
}
- function parsePossibleSuffix()
+ function parseSuffixOperator(left, acceptableOperators)
{
- let acceptableOperators = ["++", "--", ".", "->", "["];
- let limitedOperators = [".", "->", "["];
- let left;
- if (isCallExpression()) {
- left = parseCallExpression();
- acceptableOperators = limitedOperators;
- } else
- left = parseTerm();
-
let token;
while (token = tryConsume(...acceptableOperators)) {
switch (token.text) {
case "++":
case "--":
- left = finishParsingPostIncrement(token, left);
- break;
+ return finishParsingPostIncrement(token, left);
case ".":
case "->":
if (token.text == "->")
default:
throw new Error("Bad token: " + token);
}
- acceptableOperators = limitedOperators;
}
return left;
}
+ function parsePossibleSuffix()
+ {
+ let acceptableOperators = ["++", "--", ".", "->", "["];
+ let limitedOperators = [".", "->", "["];
+ let left;
+ if (isCallExpression()) {
+ left = parseCallExpression();
+ acceptableOperators = limitedOperators;
+ } else
+ left = parseTerm();
+
+ return parseSuffixOperator(left, acceptableOperators);
+ }
+
function finishParsingPreIncrement(token, left, extraArg)
{
let readModifyWrite = new ReadModifyWriteExpression(token, left);
function parsePostIncrement()
{
- let left = parseTerm();
+ let left = parseSuffixOperator(parseTerm(), ".", "->", "[");
let token = consume("++", "--");
return finishParsingPostIncrement(token, left);
}
if (typeArguments.length != this.typeParameters.length)
throw new WTypeError(this.origin.originString, "Wrong number of type arguments to instantiation");
- if (!typeArguments.length)
- return this;
-
substitution = new Substitution(this.typeParameters, typeArguments);
typeParameters = [];
}
newField = newField.visit(instantiateImmediates);
result.add(newField);
}
+
return result;
}
function checkNumber(program, result, expected)
{
- if (!result.type.isNumber)
+ if (!result.type.unifyNode.isNumber)
throw new Error("Wrong result type; result: " + result);
if (result.value != expected)
throw new Error("Wrong result: " + result + " (expected " + expected + ")");
function checkEnum(program, result, expected)
{
- if (!(result.type instanceof EnumType))
+ if (!(result.type.unifyNode instanceof EnumType))
throw new Error("Wrong result type; result: " + result);
if (result.value != expected)
throw new Error("Wrong result: " + result.value + " (expected " + expected + ")");
checkBool(program, callFunction(program, "food6", [], []), false);
}
+function TEST_instantiateStructInStruct()
+{
+ let program = doPrep(`
+ struct Bar<T> {
+ T x;
+ }
+ struct Foo {
+ Bar<int> x;
+ }
+ int foo()
+ {
+ Foo x;
+ x.x.x = 42;
+ x.x.x++;
+ return x.x.x;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [], []), 43);
+}
+
function TEST_simpleEnum()
{
let program = doPrep(`
get instantiatedType()
{
let type = this.type.unifyNode;
- if (!this.typeArguments.length)
- return type;
- if (!type.instantiate)
- throw new Error("type does not support instantiation: " + type + " (" + type.constructor.name + ")");
+ if (!type.instantiate) {
+ if (this.typeArguments.length)
+ throw new Error("type does not support instantiation: " + type + " (" + type.constructor.name + ")");
+ return this;
+ }
return type.instantiate(this.typeArguments);
}
{
if (!this.typeArguments.length)
return this.type.isPrimitive;
- throw new Error("Cannot determine if an uninstantiated type is primitive");
+ throw new Error("Cannot determine if an uninstantiated type is primitive: " + this);
}
setTypeAndArguments(type, typeArguments)