OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSLIRGenerator.h" | 8 #include "SkSLIRGenerator.h" |
9 | 9 |
10 #include "limits.h" | 10 #include "limits.h" |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } else { | 364 } else { |
365 fErrors.error(c.fPosition, "continue statement must be inside a loop"); | 365 fErrors.error(c.fPosition, "continue statement must be inside a loop"); |
366 return nullptr; | 366 return nullptr; |
367 } | 367 } |
368 } | 368 } |
369 | 369 |
370 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement
& d) { | 370 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement
& d) { |
371 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); | 371 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); |
372 } | 372 } |
373 | 373 |
374 static const Type& expand_generics(const Type& type, int i) { | |
375 if (type.kind() == Type::kGeneric_Kind) { | |
376 return *type.coercibleTypes()[i]; | |
377 } | |
378 return type; | |
379 } | |
380 | |
381 static void expand_generics(const FunctionDeclaration& decl, | |
382 std::shared_ptr<SymbolTable> symbolTable) { | |
383 for (int i = 0; i < 4; i++) { | |
384 const Type& returnType = expand_generics(decl.fReturnType, i); | |
385 std::vector<const Variable*> parameters; | |
386 for (const auto& p : decl.fParameters) { | |
387 Variable* var = new Variable(p->fPosition, Modifiers(p->fModifiers),
p->fName, | |
388 expand_generics(p->fType, i), | |
389 Variable::kParameter_Storage); | |
390 symbolTable->takeOwnership(var); | |
391 parameters.push_back(var); | |
392 } | |
393 symbolTable->add(decl.fName, std::unique_ptr<FunctionDeclaration>(new Fu
nctionDeclaration( | |
394 decl.
fPosition, | |
395 decl.
fName, | |
396 std::
move(parameters), | |
397 std::
move(returnType)))); | |
398 } | |
399 } | |
400 | |
401 std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti
on& f) { | 374 std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti
on& f) { |
402 bool isGeneric; | |
403 const Type* returnType = this->convertType(*f.fReturnType); | 375 const Type* returnType = this->convertType(*f.fReturnType); |
404 if (!returnType) { | 376 if (!returnType) { |
405 return nullptr; | 377 return nullptr; |
406 } | 378 } |
407 isGeneric = returnType->kind() == Type::kGeneric_Kind; | |
408 std::vector<const Variable*> parameters; | 379 std::vector<const Variable*> parameters; |
409 for (const auto& param : f.fParameters) { | 380 for (const auto& param : f.fParameters) { |
410 const Type* type = this->convertType(*param->fType); | 381 const Type* type = this->convertType(*param->fType); |
411 if (!type) { | 382 if (!type) { |
412 return nullptr; | 383 return nullptr; |
413 } | 384 } |
414 for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) { | 385 for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) { |
415 int size = param->fSizes[j]; | 386 int size = param->fSizes[j]; |
416 std::string name = type->name() + "[" + to_string(size) + "]"; | 387 std::string name = type->name() + "[" + to_string(size) + "]"; |
417 Type* newType = new Type(std::move(name), Type::kArray_Kind, *type,
size); | 388 Type* newType = new Type(std::move(name), Type::kArray_Kind, *type,
size); |
418 fSymbolTable->takeOwnership(newType); | 389 fSymbolTable->takeOwnership(newType); |
419 type = newType; | 390 type = newType; |
420 } | 391 } |
421 std::string name = param->fName; | 392 std::string name = param->fName; |
422 Modifiers modifiers = this->convertModifiers(param->fModifiers); | 393 Modifiers modifiers = this->convertModifiers(param->fModifiers); |
423 Position pos = param->fPosition; | 394 Position pos = param->fPosition; |
424 Variable* var = new Variable(pos, modifiers, std::move(name), *type, | 395 Variable* var = new Variable(pos, modifiers, std::move(name), *type, |
425 Variable::kParameter_Storage); | 396 Variable::kParameter_Storage); |
426 fSymbolTable->takeOwnership(var); | 397 fSymbolTable->takeOwnership(var); |
427 parameters.push_back(var); | 398 parameters.push_back(var); |
428 isGeneric |= type->kind() == Type::kGeneric_Kind; | |
429 } | 399 } |
430 | 400 |
431 // find existing declaration | 401 // find existing declaration |
432 const FunctionDeclaration* decl = nullptr; | 402 const FunctionDeclaration* decl = nullptr; |
433 auto entry = (*fSymbolTable)[f.fName]; | 403 auto entry = (*fSymbolTable)[f.fName]; |
434 if (entry) { | 404 if (entry) { |
435 std::vector<const FunctionDeclaration*> functions; | 405 std::vector<const FunctionDeclaration*> functions; |
436 switch (entry->fKind) { | 406 switch (entry->fKind) { |
437 case Symbol::kUnresolvedFunction_Kind: | 407 case Symbol::kUnresolvedFunction_Kind: |
438 functions = ((UnresolvedFunction*) entry)->fFunctions; | 408 functions = ((UnresolvedFunction*) entry)->fFunctions; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 fErrors.error(f.fPosition, "duplicate definition of " + | 446 fErrors.error(f.fPosition, "duplicate definition of " + |
477 other->description()); | 447 other->description()); |
478 } | 448 } |
479 break; | 449 break; |
480 } | 450 } |
481 } | 451 } |
482 } | 452 } |
483 } | 453 } |
484 if (!decl) { | 454 if (!decl) { |
485 // couldn't find an existing declaration | 455 // couldn't find an existing declaration |
486 if (isGeneric) { | 456 auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDeclarat
ion(f.fPosition, |
487 ASSERT(!f.fBody); | 457
f.fName, |
488 expand_generics(FunctionDeclaration(f.fPosition, f.fName, parameters
, *returnType), | 458
parameters, |
489 fSymbolTable); | 459
*returnType)); |
490 } else { | 460 decl = newDecl.get(); |
491 auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDecl
aration( | 461 fSymbolTable->add(decl->fName, std::move(newDecl)); |
492
f.fPosition, | |
493
f.fName, | |
494
parameters, | |
495
*returnType)); | |
496 decl = newDecl.get(); | |
497 fSymbolTable->add(decl->fName, std::move(newDecl)); | |
498 } | |
499 } | 462 } |
500 if (f.fBody) { | 463 if (f.fBody) { |
501 ASSERT(!fCurrentFunction); | 464 ASSERT(!fCurrentFunction); |
502 fCurrentFunction = decl; | 465 fCurrentFunction = decl; |
503 decl->fDefined = true; | 466 decl->fDefined = true; |
504 std::shared_ptr<SymbolTable> old = fSymbolTable; | 467 std::shared_ptr<SymbolTable> old = fSymbolTable; |
505 AutoSymbolTable table(this); | 468 AutoSymbolTable table(this); |
506 for (size_t i = 0; i < parameters.size(); i++) { | 469 for (size_t i = 0; i < parameters.size(); i++) { |
507 fSymbolTable->addWithoutOwnership(parameters[i]->fName, decl->fParam
eters[i]); | 470 fSymbolTable->addWithoutOwnership(parameters[i]->fName, decl->fParam
eters[i]); |
508 } | 471 } |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 std::string msg = "call to '" + function.fName + "' expected " + | 871 std::string msg = "call to '" + function.fName + "' expected " + |
909 to_string((uint64_t) function.fParameters.size(
)) + | 872 to_string((uint64_t) function.fParameters.size(
)) + |
910 " argument"; | 873 " argument"; |
911 if (function.fParameters.size() != 1) { | 874 if (function.fParameters.size() != 1) { |
912 msg += "s"; | 875 msg += "s"; |
913 } | 876 } |
914 msg += ", but found " + to_string((uint64_t) arguments.size()); | 877 msg += ", but found " + to_string((uint64_t) arguments.size()); |
915 fErrors.error(position, msg); | 878 fErrors.error(position, msg); |
916 return nullptr; | 879 return nullptr; |
917 } | 880 } |
| 881 std::vector<const Type*> types; |
| 882 const Type* returnType; |
| 883 if (!function.determineFinalTypes(arguments, &types, &returnType)) { |
| 884 std::string msg = "no match for " + function.fName + "("; |
| 885 std::string separator = ""; |
| 886 for (size_t i = 0; i < arguments.size(); i++) { |
| 887 msg += separator; |
| 888 separator = ", "; |
| 889 msg += arguments[i]->fType.description(); |
| 890 } |
| 891 msg += ")"; |
| 892 fErrors.error(position, msg); |
| 893 return nullptr; |
| 894 } |
918 for (size_t i = 0; i < arguments.size(); i++) { | 895 for (size_t i = 0; i < arguments.size(); i++) { |
919 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); | 896 arguments[i] = this->coerce(std::move(arguments[i]), *types[i]); |
920 if (!arguments[i]) { | 897 if (!arguments[i]) { |
921 return nullptr; | 898 return nullptr; |
922 } | 899 } |
923 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { | 900 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { |
924 this->markWrittenTo(*arguments[i]); | 901 this->markWrittenTo(*arguments[i]); |
925 } | 902 } |
926 } | 903 } |
927 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, | 904 return std::unique_ptr<FunctionCall>(new FunctionCall(position, *returnType,
function, |
928 std::move(arguments)))
; | 905 std::move(arguments)))
; |
929 } | 906 } |
930 | 907 |
931 /** | 908 /** |
932 * Determines the cost of coercing the arguments of a function to the required t
ypes. Returns true | 909 * Determines the cost of coercing the arguments of a function to the required t
ypes. Returns true |
933 * if the cost could be computed, false if the call is not valid. Cost has no pa
rticular meaning | 910 * if the cost could be computed, false if the call is not valid. Cost has no pa
rticular meaning |
934 * other than "lower costs are preferred". | 911 * other than "lower costs are preferred". |
935 */ | 912 */ |
936 bool IRGenerator::determineCallCost(const FunctionDeclaration& function, | 913 bool IRGenerator::determineCallCost(const FunctionDeclaration& function, |
937 const std::vector<std::unique_ptr<Expression
>>& arguments, | 914 const std::vector<std::unique_ptr<Expression
>>& arguments, |
938 int* outCost) { | 915 int* outCost) { |
939 if (function.fParameters.size() != arguments.size()) { | 916 if (function.fParameters.size() != arguments.size()) { |
940 return false; | 917 return false; |
941 } | 918 } |
942 int total = 0; | 919 int total = 0; |
| 920 std::vector<const Type*> types; |
| 921 const Type* ignored; |
| 922 if (!function.determineFinalTypes(arguments, &types, &ignored)) { |
| 923 return false; |
| 924 } |
943 for (size_t i = 0; i < arguments.size(); i++) { | 925 for (size_t i = 0; i < arguments.size(); i++) { |
944 int cost; | 926 int cost; |
945 if (arguments[i]->fType.determineCoercionCost(function.fParameters[i]->f
Type, &cost)) { | 927 if (arguments[i]->fType.determineCoercionCost(*types[i], &cost)) { |
946 total += cost; | 928 total += cost; |
947 } else { | 929 } else { |
948 return false; | 930 return false; |
949 } | 931 } |
950 } | 932 } |
951 *outCost = total; | 933 *outCost = total; |
952 return true; | 934 return true; |
953 } | 935 } |
954 | 936 |
955 std::unique_ptr<Expression> IRGenerator::call(Position position, | 937 std::unique_ptr<Expression> IRGenerator::call(Position position, |
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1376 case Expression::kIndex_Kind: | 1358 case Expression::kIndex_Kind: |
1377 this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1359 this->markWrittenTo(*((IndexExpression&) expr).fBase); |
1378 break; | 1360 break; |
1379 default: | 1361 default: |
1380 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); | 1362 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); |
1381 break; | 1363 break; |
1382 } | 1364 } |
1383 } | 1365 } |
1384 | 1366 |
1385 } | 1367 } |
OLD | NEW |