| 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 |