# HG changeset patch # User anatofuz # Date 1598271634 -32400 # Node ID ed7183a46dca610ee47ea910c7f48cc547e6f6b0 # Parent 4e80cdea307d883bd4fa33e2cfe5253ccb7f7bb6 create a stub when the output is a different interface diff -r 4e80cdea307d -r ed7183a46dca src/parallel_execution/generate_stub.pl --- a/src/parallel_execution/generate_stub.pl Mon Aug 24 14:51:25 2020 +0900 +++ b/src/parallel_execution/generate_stub.pl Mon Aug 24 21:20:34 2020 +0900 @@ -11,7 +11,6 @@ use Gears::Interface; use Gears::Util; -use DDP {deparse => 1}; # interface.h # typedef struct Worker { @@ -67,12 +66,13 @@ my %dataGearVarType; my %codeGear; my %call_interfaces; -my $interfaceNameToHeaderPath = createInterfaceNameToHeaderPath($FindBin::Bin); -my $searchCbCFromCodeGearAndFilename = createSearchCbCFileFromCodeGearNameAndFilename($FindBin::Bin); +my $headerNameToInfo = createHeaderNameToInfo($FindBin::Bin); +my $searchCbCFromCodeGearNameWCurrentFrileName = createSearchCbCFromCodeGearNameWCurrentFrileName($FindBin::Bin); my %filename2EachCodeGearArgs; -my %specialyEmitStubCodeGears; +my %stub; my $implInterfaceInfo = {isImpl => undef, implementation => undef, interface => undef}; +my $generateHaveOutputStub = { counter => {}, list => {} }; # this for statement is main routine @@ -141,13 +141,13 @@ $implInterfaceInfo->{isImpl} = 1; $implInterfaceInfo->{interface} = $interfaceName; $implInterfaceInfo->{implementation} = $3; - my $cbc_source_path = $searchCbCFromCodeGearAndFilename->($interfaceName, $filename); + my $cbc_source_path = $searchCbCFromCodeGearNameWCurrentFrileName->($interfaceName, $filename); if ($cbc_source_path) { &getDataGear($cbc_source_path); } } elsif(/^(.*)par goto (\w+)\((.*)\)/) { my $codeGearName = $2; - my $cbc_source_path = $searchCbCFromCodeGearAndFilename->($codeGearName, $filename); + my $cbc_source_path = $searchCbCFromCodeGearNameWCurrentFrileName->($codeGearName, $filename); if ($cbc_source_path) { &getCodeGear($cbc_source_path); } @@ -157,11 +157,17 @@ next if ($interfaceHeader =~ /context.h/); $interfaceHeader =~ m|(\w+)\.\w+$|; #remove filename extention my $interfaceName = $1; - includeInterface(\%call_interfaces, $filename, $interfaceName, $interfaceNameToHeaderPath); + includeInterface(\%call_interfaces, $filename, $interfaceName, $headerNameToInfo); } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) { my $codeGearName = $1; + if ($codeGearName =~ /_stub$/) { + $stub{$codeGearName}->{static} = 1; + $stub{$codeGearName}->{wrote} = 1; + $currentCodeGear = undef; + next; + } my $args = $2; - my $cbc_source_path = $searchCbCFromCodeGearAndFilename->($codeGearName, $filename); + my $cbc_source_path = $searchCbCFromCodeGearNameWCurrentFrileName->($codeGearName, $filename); if ($cbc_source_path) { &getCodeGear($cbc_source_path); } @@ -197,17 +203,28 @@ } unless (exists $call_interfaces{$filename}->{$typeName}) { warn "[AUTOINCLUDE] Forget #interface '$typeName' declaration in $filename"; - includeInterface(\%call_interfaces, $filename, $typeName, $interfaceNameToHeaderPath); + includeInterface(\%call_interfaces, $filename, $typeName, $headerNameToInfo); } - my $res = findExistsOutputDataGear($typeName, $method); - if ($res) { - my @parsedArgs = split /,/ , $tmpArgs; + my $nextOutPutArgs = findExistsOutputDataGear($typeName, $method); + my $outputStubElem = { modifyEnumCode => $currentCodeGear, createStubName => $tmpArgs }; + + if ($nextOutPutArgs) { + my $tmpArgHash = {}; + map { $tmpArgHash->{$_} = $typeName } @$nextOutPutArgs; + + $outputStubElem->{args} = $tmpArgHash; + + #We're assuming that $tmpArgs only contains the name of the next CodeGear. + #Eventually we need to parse the contents of the argument. (eg. @parsedArgs) + my @parsedArgs = split /,/ , $tmpArgs; # if (scalar(@parsedArgs) != 1) { warn '[WARN] TBD'; } - #p $res; - $specialyEmitStubCodeGears{$currentCodeGear} = $res; + + $generateHaveOutputStub->{counter}->{$tmpArgs}++; + $outputStubElem->{counter} = $generateHaveOutputStub->{counter}->{$tmpArgs}; + $generateHaveOutputStub->{list}->{$currentCodeGear} = $outputStubElem; } } elsif (/^}$/) { $currentCodeGear = undef; @@ -253,9 +270,9 @@ } sub includeInterface { - my ($call_interfaces, $filename, $interfaceName, $interfaceNameToHeaderPath) = @_; + my ($call_interfaces, $filename, $interfaceName, $headerNameToInfo) = @_; $call_interfaces->{$filename}->{$interfaceName} = 1; - my $interface_path = $interfaceNameToHeaderPath->{$interfaceName}; + my $interface_path = $headerNameToInfo->{$interfaceName}->{path}; if ($interface_path) { getDataGear($interface_path); getCodeGear($interface_path); @@ -451,7 +468,7 @@ sub findExistsOutputDataGear { my ($interfaceName, $method) = @_; - my $interfacePATH = $interfaceNameToHeaderPath->{$interfaceName}; + my $interfacePATH = $headerNameToInfo->{$interfaceName}->{path}; unless ($interfacePATH) { return undef; } @@ -503,7 +520,6 @@ my $hasParGoto = 0; my $inMain = 0 ; my $inCode = 0 ; - my %stub; my $codeGearName; my %localVarType; @@ -525,7 +541,7 @@ } # This process assumes that there are no header files of the same name - my $path = $interfaceNameToHeaderPath->{$headerName}; + my $path = $headerNameToInfo->{$headerName}->{path}; unless ($path) { print $fd $_; next; @@ -544,17 +560,18 @@ if ($codeGearName =~ /_stub$/) { # don't touch already existing stub $inStub = 1; - $stub{$codeGearName} = 1; + $stub{$codeGearName}->{static} = 1; + $stub{$codeGearName}->{wrote} = 1; print $fd $_; next; } if (defined $prevCodeGearName) { # stub is generated just before next CodeGear - if (defined $stub{$prevCodeGearName."_stub"}) { + if (defined $stub{$prevCodeGearName."_stub"}->{wrote}) { undef $prevCodeGearName; } else { &generateStub($fd,$prevCodeGearName,$dataGearName{$prevCodeGearName}); - $stub{$prevCodeGearName."_stub"} = 1; + $stub{$prevCodeGearName."_stub"}->{wrote} = 1; } } # analyzing CodeGear argument @@ -686,20 +703,39 @@ if ($arg =~ /(\w+)\(.*\)/) { print $fd "${indent}Gearef(${context_name}, $ntype)->$pName = $1;\n"; } else { - my $argOrLocalVar = undef; + my $hasGotoArgOrLocalVar = undef; + my $outputStubElem = $generateHaveOutputStub->{list}->{$codeGearName}; + + if ($outputStubElem && !$stub{$outputStubElem->{createStubName}."_stub"}->{static}) { + my $pick_next = "$outputStubElem->{createStubName}_$outputStubElem->{counter}"; + print $fd "${indent}Gearef(${context_name}, $ntype)->$pName = C_$pick_next;\n"; + $i++; + next; + } + + # find __code of argument or local variable for my $localVarType (qw/arg localVar/) { my $foundVarType = $currentCodeGearInfo->{$localVarType}->{$arg}; if ($foundVarType && $foundVarType eq '__code') { - $argOrLocalVar = 1; + $hasGotoArgOrLocalVar = 1; } } - if ($argOrLocalVar) { + # inteface case + + if ($arg =~ /->/) { print $fd "${indent}Gearef(${context_name}, $ntype)->$pName = $arg;\n"; #Gearef->()->next = next; $i++; next; } + if ($hasGotoArgOrLocalVar) { + print $fd "${indent}Gearef(${context_name}, $ntype)->$pName = $arg;\n"; #Gearef->()->next = next; + $i++; + next; + } + + #TODO: goto to special stub print $fd "${indent}Gearef(${context_name}, $ntype)->$pName = C_$arg;\n"; $i++; next; @@ -853,14 +889,39 @@ print $fd $_; } if (defined $prevCodeGearName) { - if (!defined $stub{$prevCodeGearName."_stub"}) { + if (!defined $stub{$prevCodeGearName."_stub"}->{wrote}) { $stub{$prevCodeGearName."_stub"} = &generateStub($fd,$prevCodeGearName,$dataGearName{$codeGearName}); } } + + #Create a stub when the output is a different interface + for my $modifyEnumCodeCodeGear (keys %{$generateHaveOutputStub->{list}}) { + my $outputStubElem = $generateHaveOutputStub->{list}->{$modifyEnumCodeCodeGear}; + my $targetStubName = $outputStubElem->{createStubName}; + my $createStubName = "$outputStubElem->{createStubName}_$outputStubElem->{counter}"; + my $replaceArgs = $outputStubElem->{args}; + + my $replaceStubContents = $dataGearName{$targetStubName}; + + #If the stub was handwritten, skip + if ($stub{"${targetStubName}_stub"}->{static}) { + next; + } + + for my $arg (keys %$replaceArgs) { + my $interface = $replaceArgs->{$arg}; + print "replace $arg $interface\n"; + $replaceStubContents =~ s/,(.*)\)->$arg/,$interface)->$arg/; + } + + generateStub($fd,$createStubName,$replaceStubContents); + + } + } -sub createInterfaceNameToHeaderPath { +sub createHeaderNameToInfo { my $search_root = shift; my $files = Gears::Util->find_headers_from_path($search_root); my $interface_name2headerpath = {}; @@ -869,7 +930,8 @@ for my $file (@{$files}) { if ($file =~ m|/(\w+)\.\w+$|) { my $file_name = $1; - $interface_name2headerpath->{$file_name} = $file; + my $isInterface = Gears::Interface->isThisFileInterface($file); + $interface_name2headerpath->{$file_name} = { path => $file, isInterface => $isInterface }; } } @@ -900,7 +962,10 @@ return $cbc_name2_source_path; } -sub createSearchCbCFileFromCodeGearNameAndFilename { +sub createSearchCbCFromCodeGearNameWCurrentFrileName { + #Find the cbc file that contains CodeGear. + #If there are more than one cbc file, the one whose namespace is the same as the filename has priority. + my $search_root = shift; my $cbc_name2_source_path = create_cbc_name_to_source_path($search_root); @@ -917,7 +982,6 @@ return $cbc_files->[0]; # return "/Users/anatofuz/src/firefly/hg/Gears/Gears/src/parallel_execution/SingleLinkedQueue.cbc" } - my $cbc_dir_name = dirname $filename; for my $cbc_file (@{$cbc_files}) { diff -r 4e80cdea307d -r ed7183a46dca src/parallel_execution/lib/Gears/Interface.pm --- a/src/parallel_execution/lib/Gears/Interface.pm Mon Aug 24 14:51:25 2020 +0900 +++ b/src/parallel_execution/lib/Gears/Interface.pm Mon Aug 24 21:20:34 2020 +0900 @@ -149,4 +149,25 @@ } +sub isThisFileInterface { + my ($class, $filename) = @_; + open my $fh, '<', $filename; + my $line = <$fh>; + unless ($line =~ /typedef struct \w+\s?<.*>([\s\w{]+)/) { + return 0; + } + my $annotation = $1; + return 0 if ($annotation =~ /impl/); + + return 1; +} + + +sub collect_interfaces_from_all_headers { + my ($class, $find_path) = @_; + my $header_files = Gears::Util->find_headers_from_path($find_path); + my @result = sort grep { Gears::Interface->isThisFileInterface($_) } @$header_files; + return \@result; +} + 1; diff -r 4e80cdea307d -r ed7183a46dca src/parallel_execution/lib/Gears/Util.pm --- a/src/parallel_execution/lib/Gears/Util.pm Mon Aug 24 14:51:25 2020 +0900 +++ b/src/parallel_execution/lib/Gears/Util.pm Mon Aug 24 21:20:34 2020 +0900 @@ -5,7 +5,7 @@ use File::Find qw/find/; my $cbc_files; -my $headers_files; +my $header_files; my $cbc_files_analyzed_code_gear; sub uniq { @@ -47,15 +47,16 @@ sub find_headers_from_path { my ($class, $find_path) = @_; $find_path //= "."; - return $headers_files if $headers_files; + return $header_files if $header_files; my @files; find( { wanted => sub { push @files, $_ if /\.(?:h|dg)/ }, no_chdir => 1 }, $find_path); - $headers_files = \@files; - return $headers_files; + $header_files = \@files; + return $header_files; } + sub collect_codegears_from_all_cbc_sources { my ($class, $find_path) = @_; $find_path //= ".";