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 |