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