Changeset 221686 in webkit
- Timestamp:
- Sep 6, 2017 11:25:55 AM (7 years ago)
- Location:
- trunk/Tools
- Files:
-
- 1 deleted
- 18 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r221679 r221686 1 2017-09-06 Myles C. Maxfield <mmaxfield@apple.com> 2 3 WSL should correctly handle the interaction between casting operators and complex types 4 https://bugs.webkit.org/show_bug.cgi?id=176316 5 6 Reviewed by Filip Pizlo. 7 8 This allows the standard library to include all identity cast operators for all exsting 9 and yet-to-exist types. The standard library now has a function with the signature: 10 operator T<><T>(T). This means "for all T, define a cast operator from T to T<>." The 11 duplicate <>s lets us say things like operator OutputVector<T><T>(InputVector<T> x). 12 13 For testing, this patch also adds the ability to cast an arbitrary Equatable type to bool, 14 by comparing the value to the default value for that type. 15 16 * WebGPUShadingLanguageRI/All.js: 17 * WebGPUShadingLanguageRI/CastExpression.js: Copied from Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js. 18 (CastExpression): 19 (CastExpression.prototype.get functionName): 20 (CastExpression.prototype.get returnType): 21 (CastExpression.prototype.toString): 22 * WebGPUShadingLanguageRI/Checker.js: 23 * WebGPUShadingLanguageRI/Func.js: 24 (Func.prototype.toDeclString): 25 * WebGPUShadingLanguageRI/FuncInstantiator.js: 26 (FuncInstantiator.prototype.getUnique.Instantiate.prototype.visitNativeFunc): 27 (FuncInstantiator.prototype.getUnique.Instantiate): 28 (FuncInstantiator.prototype.getUnique): 29 (FuncInstantiator): 30 * WebGPUShadingLanguageRI/Inliner.js: 31 (Inliner.prototype.visitCastExpression): 32 (Inliner): 33 * WebGPUShadingLanguageRI/Intrinsics.js: 34 (Intrinsics): 35 * WebGPUShadingLanguageRI/NativeFunc.js: 36 * WebGPUShadingLanguageRI/NativeFuncInstance.js: 37 (NativeFuncInstance): 38 * WebGPUShadingLanguageRI/Parse.js: 39 (parsePossiblePrefix): 40 (parseFuncDecl): 41 (parseOperatorFuncDefValues): Deleted. 42 (parseNonOperatorFuncDefValues): Deleted. 43 (parseGenericFuncDefValues): Deleted. 44 * WebGPUShadingLanguageRI/Prepare.js: 45 (prepare): 46 * WebGPUShadingLanguageRI/Program.js: 47 (Program.prototype.resolveFuncOverload): 48 * WebGPUShadingLanguageRI/ResolveOverloadImpl.js: 49 (resolveOverloadImpl): 50 * WebGPUShadingLanguageRI/Rewriter.js: 51 (Rewriter.prototype.processDerivedCallData): 52 (Rewriter.prototype.visitCastExpression): 53 (Rewriter.prototype.visitCallExpression): 54 * WebGPUShadingLanguageRI/StandardLibrary.js: Removed. 55 * WebGPUShadingLanguageRI/Test.html: 56 * WebGPUShadingLanguageRI/Test.js: 57 * WebGPUShadingLanguageRI/TypeDefResolver.js: 58 (TypeDefResolver): 59 (TypeDefResolver.prototype.visitFuncDef): Deleted. 60 * WebGPUShadingLanguageRI/Visitor.js: 61 (Visitor.prototype.visitCastExpression): 62 1 63 2017-09-06 Daniel Bates <dabates@apple.com> 2 64 -
trunk/Tools/WebGPUShadingLanguageRI/All.js
r221634 r221686 42 42 load("CallExpression.js"); 43 43 load("CallFunction.js"); 44 load("CastExpression.js"); 44 45 load("Check.js"); 45 46 load("CheckLiteralTypes.js"); … … 97 98 load("ReturnChecker.js"); 98 99 load("ReturnException.js"); 99 load("StandardLibrary.js"); 100 load("StandardLibraryEpilogue.js"); 101 load("StandardLibraryPrologue.js"); 100 102 load("StructLayoutBuilder.js"); 101 103 load("StructType.js"); -
trunk/Tools/WebGPUShadingLanguageRI/CastExpression.js
r221684 r221686 25 25 "use strict"; 26 26 27 class NativeFuncInstance extends Func { 28 constructor(func, returnType, parameters) 27 // This is a bit of a misnomer, as this represents casts as well as constructors. 28 // Syntactically they are identical; a cast just takes one argument whereas a 29 // constructor takes 0-n. 30 class CastExpression extends CallExpression { 31 constructor(origin, returnType, typeArguments, argumentList) 29 32 { 30 super(func.origin, func.name, returnType, [], parameters); 33 super(origin, CastExpression.functionName, typeArguments, argumentList); 34 this._returnType = returnType; 31 35 } 36 37 static get functionName() { return "operator cast"; } 32 38 33 get func() { return this._func; } 34 get isNative() { return true; } 35 36 toDeclString() 39 get returnType() { return this._returnType; } 40 41 toString() 37 42 { 38 return "native " + super.toDeclString();43 return this.returnType + "<" + this.typeArguments + ">(" + this.argumentList + ")"; 39 44 } 40 45 } -
trunk/Tools/WebGPUShadingLanguageRI/Checker.js
r221634 r221686 234 234 return result; 235 235 } 236 237 visitCallExpression(node)236 237 checkCastOrCallExpression(node, returnType) 238 238 { 239 239 for (let typeArgument of node.typeArguments) … … 246 246 }); 247 247 node.argumentTypes = argumentTypes; 248 if (returnType) 249 returnType.visit(this); 248 250 249 251 let overload = null; … … 258 260 if (!signatures) 259 261 continue; 260 overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes );262 overload = resolveOverloadImpl(signatures, node.typeArguments, argumentTypes, returnType); 261 263 if (overload.func) 262 264 break; … … 266 268 if (!overload) { 267 269 overload = this._program.resolveFuncOverload( 268 node.name, node.typeArguments, argumentTypes );270 node.name, node.typeArguments, argumentTypes, returnType); 269 271 if (!overload.func) { 270 272 failures.push(...overload.failures); … … 285 287 return node.resolve(overload); 286 288 } 289 290 visitCastExpression(node) 291 { 292 return this.checkCastOrCallExpression(node, node.returnType); 293 } 294 295 visitCallExpression(node) 296 { 297 return this.checkCastOrCallExpression(node, undefined); 298 } 287 299 } 288 300 -
trunk/Tools/WebGPUShadingLanguageRI/Func.js
r221634 r221686 49 49 toDeclString() 50 50 { 51 return (this.isCast ? " " : this.returnType + " ") + this.name+ "<" + this.typeParameters + ">(" + this.parameters + ")";51 return (this.isCast ? "operator " + this.returnType : this.returnType + " " + this.name) + "<" + this.typeParameters + ">(" + this.parameters + ")"; 52 52 } 53 53 -
trunk/Tools/WebGPUShadingLanguageRI/FuncInstantiator.js
r221592 r221686 93 93 func, 94 94 func.returnType.visit(substitution), 95 func.parameters.map(parameter => parameter.visit(substitution))); 95 func.parameters.map(parameter => parameter.visit(substitution)), 96 func.isCast); 96 97 } 97 98 } -
trunk/Tools/WebGPUShadingLanguageRI/Inliner.js
r221550 r221686 59 59 }); 60 60 } 61 62 visitCastExpression(node) 63 { 64 return this.visitCallExpression(node); 65 } 61 66 } 62 67 -
trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js
r221634 r221686 35 35 36 36 // NOTE: Intrinsic resolution happens before type name resolution, so the strings we use here 37 // to catch the intrinsics must be based on the type names that StandardLibrary .js uses. For38 // example, if a native function is declared using "int" rather than "int32", then we must use39 // "int" here, since we don't yet know that they are the same type.37 // to catch the intrinsics must be based on the type names that StandardLibraryPrologue.js uses. 38 // For example, if a native function is declared using "int" rather than "int32", then we must 39 // use "int" here, since we don't yet know that they are the same type. 40 40 41 41 this._map.set( … … 179 179 }); 180 180 181 this._map.set(182 "native operator int<>(int)",183 func => {184 func.implementation = ([value]) =>185 EPtr.box(value.loadValue());186 });187 188 this._map.set(189 "native operator uint<>(uint)",190 func => {191 func.implementation = ([value]) =>192 EPtr.box(value.loadValue());193 });194 195 this._map.set(196 "native operator bool<>(bool)",197 func => {198 func.implementation = ([value]) =>199 EPtr.box(value.loadValue());200 });201 202 181 let arrayElementPtr = func => { 203 182 func.implementation = ([ref, index], node) => { -
trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js
r221634 r221686 26 26 27 27 class NativeFunc extends Func { 28 constructor(origin, name, returnType, typeParameters, parameters, isCast = false)28 constructor(origin, name, returnType, typeParameters, parameters, isCast) 29 29 { 30 30 super(origin, name, returnType, typeParameters, parameters, isCast); -
trunk/Tools/WebGPUShadingLanguageRI/NativeFuncInstance.js
r221549 r221686 26 26 27 27 class NativeFuncInstance extends Func { 28 constructor(func, returnType, parameters )28 constructor(func, returnType, parameters, isCast) 29 29 { 30 super(func.origin, func.name, returnType, [], parameters );30 super(func.origin, func.name, returnType, [], parameters, isCast); 31 31 } 32 32 -
trunk/Tools/WebGPUShadingLanguageRI/Parse.js
r221634 r221686 381 381 if (token = tryConsume("@")) 382 382 return new MakeArrayRefExpression(token, parsePossiblePrefix()); 383 if (token = tryConsume("!")) 384 return new LogicalNot(token, new CallExpression(token, "operator bool", [], [parsePossiblePrefix()])); 383 if (token = tryConsume("!")) { 384 let remainder = parsePossiblePrefix(); 385 return new LogicalNot(token, new CastExpression(remainder.origin, new TypeRef(remainder.origin, "bool", []), [], [remainder])); 386 } 385 387 return parsePossibleSuffix(); 386 388 } … … 621 623 } 622 624 623 function parseOperatorFuncDefValues() 624 { 625 let result = {}; 626 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=176316 Correctly handle the interaction between casting operators and complex types 627 let castType = consumeKind("identifier").text; 628 result.returnType = new TypeRef(name, castType, []); 629 result.name = "operator " + castType; 630 result.isCast = true; 631 return result; 632 } 633 634 function parseNonOperatorFuncDefValues() 635 { 636 let result = {}; 637 result.returnType = parseType(); 638 result.origin = result.returnType.origin; 639 result.name = parseFuncName(); 640 result.isCast = false; 641 return result; 642 } 643 644 function parseGenericFuncDefValues() 645 { 625 function parseFuncDecl() 626 { 627 let origin; 628 let returnType; 629 let name; 630 let isCast; 646 631 let operatorToken = tryConsume("operator"); 647 632 if (operatorToken) { 648 let result = parseOperatorFuncDefValues();649 re sult.origin = operatorToken.origin;650 return result;651 }652 return parseNonOperatorFuncDefValues();653 }654 655 function parseFuncDecl()656 {657 let values = parseGenericFuncDefValues();633 origin = operatorToken; 634 returnType = parseType(); 635 name = CastExpression.functionName; 636 isCast = true; 637 } else { 638 returnType = parseType(); 639 origin = returnType.origin; 640 name = parseFuncName(); 641 isCast = false; 642 } 658 643 let typeParameters = parseTypeParameters(); 659 644 let parameters = parseParameters(); 660 return new Func( values.origin, values.name, values.returnType, typeParameters, parameters, values.isCast);645 return new Func(origin, name, returnType, typeParameters, parameters, isCast); 661 646 } 662 647 -
trunk/Tools/WebGPUShadingLanguageRI/Prepare.js
r221593 r221686 28 28 { 29 29 let program = new Program(); 30 parse(program, "/internal/stdlib ", 28, standardLibrary);30 parse(program, "/internal/stdlib/prologue", 28, standardLibraryPrologue); 31 31 parse(program, origin, lineNumberOffset, text); 32 parse(program, "/internal/stdlib/epilogue", 28, standardLibraryEpilogue); 32 33 resolveNames(program); 33 34 resolveTypeDefs(program); -
trunk/Tools/WebGPUShadingLanguageRI/Program.js
r221496 r221686 59 59 } 60 60 61 resolveFuncOverload(name, typeArguments, argumentTypes )61 resolveFuncOverload(name, typeArguments, argumentTypes, returnType) 62 62 { 63 63 let functions = this.functions.get(name); … … 65 65 return {failures: []}; 66 66 67 return resolveOverloadImpl(functions, typeArguments, argumentTypes );67 return resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType); 68 68 } 69 69 -
trunk/Tools/WebGPUShadingLanguageRI/ResolveOverloadImpl.js
r221550 r221686 25 25 "use strict"; 26 26 27 function resolveOverloadImpl(functions, typeArguments, argumentTypes )27 function resolveOverloadImpl(functions, typeArguments, argumentTypes, returnType) 28 28 { 29 29 let failures = []; … … 43 43 let parameter = func.typeParameters[i]; 44 44 if (!argument.unify(unificationContext, parameter)) { 45 failures.push(new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + func.typeParameters.name + " does not match (passed " + argument + ", require " + parameter + ")"));45 failures.push(new OverloadResolutionFailure(func, "Type argument #" + (i + 1) + " for parameter " + parameter.name + " does not match (passed " + argument + ", require " + parameter + ")")); 46 46 ok = false; 47 47 break; … … 61 61 if (!ok) 62 62 continue; 63 if (returnType) { 64 if (!returnType.unify(unificationContext, func.returnType)) { 65 failures.push(new OverloadResolutionFailure(func, "Return type " + func.returnType + " does not match " + returnType)); 66 continue; 67 } 68 } 63 69 if (!unificationContext.verify()) { 64 70 failures.push(new OverloadResolutionFailure(func, "Violates type variable constraints")); -
trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js
r221634 r221686 236 236 return result; 237 237 } 238 239 visitCallExpression(node) 240 { 241 let result = new CallExpression( 242 node.origin, node.name, 243 node.typeArguments.map(typeArgument => typeArgument.visit(this)), 244 node.argumentList.map(argument => argument.visit(this))); 238 239 processDerivedCallData(node, result) 240 { 245 241 let actualTypeArguments = node.actualTypeArguments; 246 242 if (actualTypeArguments) { … … 255 251 return result; 256 252 } 253 254 visitCastExpression(node) 255 { 256 let result = new CastExpression( 257 node.origin, node.returnType.visit(this), 258 node.typeArguments.map(typeArgument => typeArgument.visit(this)), 259 node.argumentList.map(argument => argument.visit(this))); 260 return this.processDerivedCallData(node, result); 261 } 262 263 visitCallExpression(node) 264 { 265 let result = new CallExpression( 266 node.origin, node.name, 267 node.typeArguments.map(typeArgument => typeArgument.visit(this)), 268 node.argumentList.map(argument => argument.visit(this))); 269 return this.processDerivedCallData(node, result); 270 } 257 271 258 272 visitFunctionLikeBlock(node) -
trunk/Tools/WebGPUShadingLanguageRI/Test.html
r221634 r221686 18 18 <script src="CallExpression.js"></script> 19 19 <script src="CallFunction.js"></script> 20 <script src="CastExpression.js"></script> 20 21 <script src="Check.js"></script> 21 22 <script src="CheckLiteralTypes.js"></script> … … 73 74 <script src="ReturnChecker.js"></script> 74 75 <script src="ReturnException.js"></script> 75 <script src="StandardLibrary.js"></script> 76 <script src="StandardLibraryEpilogue.js"></script> 77 <script src="StandardLibraryPrologue.js"></script> 76 78 <script src="StructLayoutBuilder.js"></script> 77 79 <script src="StructType.js"></script> -
trunk/Tools/WebGPUShadingLanguageRI/Test.js
r221634 r221686 202 202 } 203 203 204 function TEST_generalNegation() 205 { 206 let program = doPrep("bool foo(int x) { return !x; }"); 207 checkBool(program, callFunction(program, "foo", [], [makeInt(program, 7)]), false); 208 checkBool(program, callFunction(program, "foo", [], [makeInt(program, 0)]), true); 209 } 210 204 211 function TEST_add1() { 205 212 let program = doPrep("int foo(int x) { return x + 1; }"); -
trunk/Tools/WebGPUShadingLanguageRI/TypeDefResolver.js
r221634 r221686 31 31 this._visiting = new VisitingSet(); 32 32 } 33 34 visitFuncDef(node)35 {36 if (node.isCast && node.returnType.type instanceof TypeDef) {37 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=176316 Correctly handle the interaction between casting operators and complex types38 throw new Error("Casting operators don't work with typedefs.");39 }40 super.visitFuncDef(node);41 }42 33 43 34 visitTypeRef(node) -
trunk/Tools/WebGPUShadingLanguageRI/Visitor.js
r221634 r221686 256 256 } 257 257 } 258 259 visitCastExpression(node) 260 { 261 this.visitCallExpression(node); 262 node.returnType.visit(this); 263 } 258 264 259 265 visitLogicalNot(node)
Note: See TracChangeset
for help on using the changeset viewer.