changeset 323:6d96bba13d5d

merged
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Fri, 07 Feb 2020 14:58:30 +0900
parents 7d77c5005cb6 (current diff) 793a266bf3c7 (diff)
children b4e3629ca798
files src/CMakeLists.txt src/gearsTools/generate_stub.pl src/gearsTools/lib/Gears/Context/Template/XV6.pm
diffstat 31 files changed, 744 insertions(+), 522 deletions(-) [+]
line wrap: on
line diff
--- a/src/CMakeLists.txt	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/CMakeLists.txt	Fri Feb 07 14:58:30 2020 +0900
@@ -129,7 +129,7 @@
 	string.c arm.c asm.S bio.c buddy.c console.cbc exec.c file.cbc fs.c log.c main.c memide.c pipe.cbc proc.cbc spinlock.cbc 
 	start.c swtch.S syscall.cbc sysfile.cbc sysproc.c trap_asm.S trap.c vm.c device/picirq.c device/timer.c device/uart.c 
   SingleLinkedStack.cbc entry.S impl/vm_impl.cbc impl/vm_impl_private.cbc
-impl/fs_impl.cbc impl/fs_impl_private.cbc
+  impl/fs_impl.cbc impl/fs_impl_private.cbc impl/KernelError.cbc
 )
 
 # sys_read_impl.cbc
--- a/src/buddy.c	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/buddy.c	Fri Feb 07 14:58:30 2020 +0900
@@ -6,6 +6,7 @@
 #include "mmu.h"
 #include "spinlock.h"
 #include "arm.h"
+#include "ln.h"
 
 
 // this file implement the buddy memory allocator. Each order divides
--- a/src/console.cbc	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/console.cbc	Fri Feb 07 14:58:30 2020 +0900
@@ -20,9 +20,9 @@
 
 static void consputc (int);
 
-static int panicked = 0;
+int panicked = 0;
 
-static struct {
+struct {
     struct spinlock lock;
     int locking;
 } cons;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gearsTools/check_convert_context_struct.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,15 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+use Gears::Util;
+
+
+my $interface_file = shift or die "require itnerface file";
+my $h2context = Gears::Util->parse_interface($interface_file);
+my $context = Gears::Util->h2context_str($h2context);
+
+print "$context";
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gearsTools/gen_Stub.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,19 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/lib";
+use Gears::Util;
+use Gears::Stub;
+
+use Getopt::Std;
+use File::Spec;
+
+use DDP {deparse => 1};
+
+my $target_cbc_file = shift;
+my $stubManager = Gears::Stub->new(file_name => File::Spec->rel2abs($target_cbc_file));
+
+my $interface_w_impl = $stubManager->findInterfacewImpl(File::Spec->rel2abs($target_cbc_file));
+
--- a/src/gearsTools/generate_context.pl	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/generate_context.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -81,7 +81,7 @@
   my @cbc_files;
   map { push(@cbc_files,File::Spec->rel2abs($_)); }  @ARGV;
   my $gears      = Gears::Context->new(compile_sources => \@cbc_files, find_root => "$FindBin::Bin/../", output => $output);
-  my $data_gears = $gears->extraction_dg_compile_sources();
+  my $data_gears = $gears->extraction_dg_compile_sources($gears->{compile_sources});
   my $g          = $gears->set_data_gear_header_path(keys %{$data_gears->{impl}},keys %{$data_gears->{interfaces}});
 
   my $dg2path    = $gears->update_dg_each_header_path($data_gears,$g);
--- a/src/gearsTools/generate_stub.pl	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/generate_stub.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -75,7 +75,7 @@
 
 sub getDataGear {
     my ($filename) = @_;
-    my ($codeGearName, $name, $inTypedef);
+    my ($codeGearName, $name, $inTypedef,$described_data_gear);
     open my $fd,"<",$filename or die("can't open $filename $!");
     while (<$fd>) {
         if (! $inTypedef) {
@@ -110,7 +110,7 @@
                 if ( -f "$codeGearName.cbc") {
                     &getCodeGear("$codeGearName.cbc");
                 }
-			} elsif(/^#interface "(.*)"/) {
+            } elsif(/^#interface "(.*)"/) {
                 # use interface
                 my $interfaceHeader = $1;
                 next if ($interfaceHeader =~ /context.h/);
@@ -141,8 +141,25 @@
                     $ttype = "const $2";
                 }
             }
+            $described_data_gear = 1;
             $var{$name}->{$tname} = $ttype;
         }
+        if (/__code (\w+)/) {
+            next if $described_data_gear;
+            my $args = $';
+            while ($args =~ /\s*(struct|union|const)?\s*([\w\[\]_]+)\*?\s*(\w+),?/g) {
+              #$args eq  (Impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...));
+              my $const_type = $1;
+              my $ttype = $2;
+              my $tname = $3;
+
+              $ttype =~ s/(Impl|Isa|Type)/Data/;
+              if ($const_type eq 'const') {
+                $ttype = "const $ttype";
+              }
+              $var{$name}->{$tname} = $ttype;
+            }
+        }
         if (/^}/) {
             $inTypedef = 0;
         }
--- a/src/gearsTools/lib/Gears/Context.pm	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/lib/Gears/Context.pm	Fri Feb 07 14:58:30 2020 +0900
@@ -25,125 +25,15 @@
 
 
 sub extraction_dg_compile_sources {
-  my $self = shift;
-  my %counter;
-  my %include_pool = ();
-  for my $cbc_file (@{$self->{compile_sources}}) {
-    open my $fh , '<', $cbc_file;
-    while (my $line = <$fh>) {
-        if ($line =~ m|//\s*:skip|) {
-         next;
-        }
-
-       if ($line =~ /#interface\s*"(.*)\.h"/) {
-          push(@{$counter{interfaces}->{$1}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ /^\/\/\s*data_gear\s*"(.*)\.(?:h|dg)?"/) {
-          push(@{$include_pool{$1}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ m|//\s*Skip:\s*generate_context|) {
-         $line = <$fh>;
-         next;
-       }
-
-
-       #if ($line =~ /^(\w+)(\*)+  *create(\w+)\(([^]]*)\)/) {
-       #   my $interface = $1;
-       #   my $implementation = $3;
-       #   $self->{data_gears_with_count}->{$interface}->{caller}->{$cbc_file}++;
-       #   $self->{data_gears_with_count}->{$implementation}->{caller}->{$cbc_file}++;
-       #   $counter{interfaces}->{$interface}++;
-       #   $counter{impl}->{$implementation}++;
-       #   next;
-       #}
-
-       if ($line =~ /Gearef\(context,\s*(\w+)\)/) {
-          my $implementation = $1;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          next;
-       }
-
-    #Element* element = &ALLOCATE(cbc_context, Element)->Element;
-       if ($line =~ /ALLOCATE\w*\((?:cbc_)?context,\s*(\w+)\)/) {
-          my $implementation = $1;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ /ALLOCATE_(?:PTR_)?ARRAY\((?:cbc_)?context,\s*(\w+),[\s\w]+\)/) {
-          my $implementation = $1;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ /new\s+(\w+?)\([\w\s]*\);/) {
-          my $implementation = $1;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ /ALLOCATE_DATA_GEAR\((\w+),\s*(\w+)\)/) {
-          my $implementation = $2;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          next;
-       }
-
-       #TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
-       if ($line =~ /\((\w+)\*\)GearImpl\(context,\s*(\w+),\s*(\w+)\)/) {
-          my $interface = $2;
-          my $implementation = $1;
-          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
-          push(@{$counter{interfaces}->{$interface}->{$cbc_file}},$.);
-          next;
-       }
-
-       if ($line =~ /^__code/) {
-         while ($line =~ /struct (\w+)\s*\*/g) {
-           next if $1 eq "Context";
-           next if (exists $counter{interfaces}->{$1});
-           push(@{$counter{impl}->{$1}->{$cbc_file}},$.);
-         }
-       }
-    }
-    close $fh;
-  }
-  use Data::Dumper;
-
-  for my $cg_name (keys %include_pool) {
-    my @tmp_cbc_file_names  = keys %{$include_pool{$cg_name}};
-    my $tmp_cbc_file_name  = shift @tmp_cbc_file_names;
-    if (exists $counter{interfaces}->{$cg_name}){
-      push(@{$counter{interfaces}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
-      delete $include_pool{$cg_name};
-      next;
-    }
-
-    if (exists $counter{impl}->{$cg_name}){
-      push(@{$counter{impl}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
-      delete $include_pool{$cg_name};
-      next;
-    }
-    push(@{$counter{interfaces}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
-    delete $include_pool{$cg_name};
-  }
-
-  $counter{interfaces}->{Meta}++;
-  $counter{interfaces}->{TaskManager}++;
-  print "-----------\n";
-  print Dumper \%counter;
-  print "-----------\n";
-  return \%counter;
+  my ($self, $compile_sources) = @_;
+  return Gears::Util->extraction_dg_compile_sources($compile_sources);
 }
 
 sub set_data_gear_header_path {
   my $self = shift;
   my @data_gears_name;
   map { push (@data_gears_name,$_) if $_ ne "Context" } @_;
-  return _find_headers($self->{find_root},\@data_gears_name);
+  return Gears::Util->docking_header_name_to_path($self->{find_root},\@data_gears_name);
 }
 
 sub update_dg_each_header_path {
@@ -158,6 +48,14 @@
       }
     }
   }
+
+  for my $kind (keys %$dgs) {
+    map {
+      if ($new_dgs->{$kind}->{$_} =~ /^\d+$/) {
+        croak "failed: not found $_.(h|dg)\n";
+      }
+    } keys %{$new_dgs->{$kind}};
+  }
   return $new_dgs;
 }
 
@@ -186,19 +84,6 @@
 sub tree2data_struct_str {
   my ($self, $dg_str) = @_;
   my $data_struct_str  = "";
-
-  # 定義順で大変なのでオミット
-  ##もとのxv6に登録されているものはcontext.hには定義を書かない
-  #my $alread_defined_str = _already_defined_struct();
-  #for my $str (sort keys %$dg_str) {
-  #  if (defined $alread_defined_str->{$str}) {
-  #    my $str_name = $alread_defined_str->{$str};
-  #    $data_struct_str .= "struct $str_name $str_name;\n";
-  #    delete $dg_str->{$str_name};
-  #  }
-  #}
-
-  #定義されてないものはcontext.hに書くフォーマットに合わせておく
   for my $interface (sort keys %$dg_str) {
     $data_struct_str .= Gears::Util->h2context_str($dg_str->{$interface}->{elem});
     next unless ($dg_str->{$interface}->{impl});
@@ -233,52 +118,4 @@
   return \%dg_str;
 }
 
-sub _find_headers {
-  my ($search_bash_path, $targets) = @_;
-  my %res;
-  map { $res{$_}++ } @$targets;
-
-  my $header_paths = Gears::Util->find_headers_path($search_bash_path);
-  map {
-    if (/(\w+)\.(?:h|dg)$/) {
-        my $header_file = $1;
-        if (exists $res{$header_file}) {
-          if ($res{$header_file} =~ /^\d+$/){
-            $res{$header_file} = $_;
-          } elsif (($_ =~ /\.dg$/) && ($res{$header_file} =~ /\.h$/)) {
-            $res{$header_file} = $_;
-          }
-        }
-    }
-  } sort @$header_paths;
-  return \%res;
-}
-
-sub _already_defined_struct {
-  my @struct_list = qw/
-__jmp_buf_tag
-buf
-cbc_devsw
-context
-cpu
-devsw
-dinode
-dirent
-elfhdr
-file
-inode
-pipe
-proc
-proghdr
-spinlock
-stat
-superblock
-trapframe
-/;
-
-  my %def_hash;
-  map { $def_hash{$_} = $_} @struct_list;
-  return \%def_hash;
-}
-
 1;
--- a/src/gearsTools/lib/Gears/Context/Template/XV6.pm	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/lib/Gears/Context/Template/XV6.pm	Fri Feb 07 14:58:30 2020 +0900
@@ -30,9 +30,10 @@
 # endif
 #endif
 
+#include "ln.h"
 #ifdef XV6KERNEL
 extern void*           kmalloc (int order);
-#define calloc(a,b)  kmalloc((a)*(b))
+#define calloc(a,b)  kmalloc(ln((a)*(b)))
 #define free(a)  kfree(a)
 #else
 extern void* malloc(unsigned int sz);
@@ -40,7 +41,7 @@
 #define free(a)  free(a)
 #endif
 
-#define ALLOCATE_SIZE 20000000
+#define ALLOCATE_SIZE 20000 
 #define NEW(type) (type*)(calloc(1, sizeof(type)))
 #define NEWN(n, type) (type*)(calloc(n, sizeof(type)))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gearsTools/lib/Gears/Stub.pm	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,39 @@
+package Gears::Stub;
+use strict;
+use warnings;
+use Carp qw/croak/;
+use File::Find;
+use Gears::Util;
+
+use DDP {deparse => 1};
+
+sub new {
+  my ($class, %args) = @_;
+
+  my $self = {};
+  $self->{file_name} = $args{file_name} || croak 'invalid file_name!'; 
+
+  return bless $self, $class;
+}
+
+
+
+sub findInterfacewImpl {
+  my $self     = shift;
+  my $cbc_file = shift // $self->{file_name};
+  my $findInterfaces = Gears::Util->extraction_dg_compile_sources([$cbc_file]);
+  my $edgcs = Gears::Util->extraction_dg_compile_sources([$cbc_file]);
+  my $findInterfaces = {};
+
+  my %ifs = ();
+  map { $ifs{$_}++ } keys %{$edgcs->{interfaces}};
+  delete $ifs{Meta};
+  delete $ifs{TaskManager};
+
+  push(@{$findInterfaces->{interfaces}}, keys %ifs);
+  push(@{$findInterfaces->{impls}}, keys %{$edgcs->{impl}});
+
+  return $findInterfaces;
+}
+
+1;
--- a/src/gearsTools/lib/Gears/Util.pm	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/lib/Gears/Util.pm	Fri Feb 07 14:58:30 2020 +0900
@@ -10,11 +10,6 @@
   return $ir;
 }
 
-sub parse_code_verbose {
-  my ($class, $file_name) = @_;
-  my $ir = _parse_base($file_name,1);
-  return $ir;
-}
 
 sub parse_interface {
   my ($class, $file_name) = @_;
@@ -27,16 +22,6 @@
 }
 
 
-sub parse_impl {
-  my ($class, $file_name) = @_;
-  my $ir = _parse_base($file_name);
-
-  unless ($ir->{isa} && $ir->{name}) {
-    croak 'invalid struct name';
-  }
-  return $ir;
-}
-
 sub _parse_base {
   my ($file,$code_verbose) = @_;
   my $ir  = {};
@@ -55,6 +40,7 @@
     }
   }
 
+  my @tmp_args;
   while ($line = <$fh>) {
     if ($line =~ m|\s*/\*|) {
       while ( $line !~ m|\*/|) {
@@ -67,17 +53,36 @@
     next if ($line =~ m[^\s*//]);
     next if ($line =~ m[^\}\s*$ir->{name};]);
 
-    if ($line =~ m|__code (\w+)\(([()\.\*\s\w,_]+)\)|) {
-      $line = "enum Code $1;\n";
+    if ($line =~ m|__code (\w+)|) {
+      push(@tmp_args,"enum Code $1;\n");
+      my $args = $';
+      #$args eq  (Impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...));
+      while ($args =~ /\s*(struct|union|const)?\s*([\w*\[\]_]+)\s*(\w+),?/g) {
+        my $const_type = $1;
+        my $type = $2;
+        my $vname = $3;
+        next if ($type eq '__code');
+        $type =~ s/(?:Impl|Type|Isa)/union Data/;
+        my $val = "$type $vname;\n";
+        push(@tmp_args, $const_type ?  "$const_type $val" : $val);
+      }
+      next;
     }
 
-    push(@{$ir->{content}},$line);
+    $line =~ s/^\s+//;
+    push(@tmp_args,$line);
   }
 
+  push(@{$ir->{content}}, _uniq(@tmp_args));
   return $ir;
 }
 
-sub parse_with_rewrite {
+sub _uniq {
+  my %seen;
+  return grep { !$seen{$_}++ } @_;
+}
+
+sub parse_with_separate_code_data_gears{
   my ($class, $file)  = @_;
   my $ir = _parse_base($file);
 
@@ -118,7 +123,7 @@
   return $f;
 }
 
-sub find_header {
+sub find_using_interface_header {
   my $class = shift;
   my $header_name = shift;
 
@@ -128,7 +133,7 @@
   find(
     {
       wanted => sub {
-        if ($_ =~ /\/$header_name\.(h|dg)/) {
+        if ($_ =~ /\/$header_name\.(h|dg)$/) {
           push(@header_list,$_);
         }
       },
@@ -159,8 +164,20 @@
   my $context = "${space}//$h2context->{file_name}\n";
   $context .=  "${space}struct $h2context->{name} {\n";
   my $content_space;
-  if (exists $h2context->{content}){
-    my @chars = split //, $h2context->{content}->[0];
+
+  my @enumCodes;
+  my @var;
+
+  for my $c (@{$h2context->{content}}) {
+    if ($c =~ /\A\s*enum Code/) {
+      push(@enumCodes,$c);
+    } else  {
+      push(@var,$c);
+    }
+  }
+
+  if (@var){
+    my @chars = split //, $var[0];
     for my $w (@chars) {
       last if ($w !~ /\s/);
       $content_space .= $w;
@@ -171,13 +188,152 @@
     $content_space = "";
   }
 
-  for my $c (@{$h2context->{content}}) {
+  for my $c (@var) {
     $c =~ s/$content_space//;
     $context .= "${space}${space}$c";
   }
+
+  for my $c (@enumCodes) {
+    $c =~ s/$content_space//;
+    $context .= "${space}${space}$c";
+  }
+
   $context .= "${space}} $h2context->{name};\n";
   return $context;
 }
 
+sub extraction_dg_compile_sources {
+  my ($class, $compile_sources) = @_;
+  my %counter;
+  my %include_pool = ();
+  for my $cbc_file (@{$compile_sources}) {
+    open my $fh , '<', $cbc_file;
+    while (my $line = <$fh>) {
+        if ($line =~ m|//\s*:skip|) {
+         next;
+        }
+
+       if ($line =~ /#interface\s*"(.*)\.h"/) {
+          push(@{$counter{interfaces}->{$1}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /^\/\/\s*data_gear\s*"(.*)\.(?:h|dg)?"/) {
+          push(@{$include_pool{$1}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ m|//\s*Skip:\s*generate_context|) {
+         $line = <$fh>;
+         next;
+       }
+
+
+       if ($line =~ /^(\w+)\*\s*create(\w+)\(/) {
+          my $interface = $1;
+          my $implementation = $2;
+          push(@{$counter{interfaces}->{$interface}->{$cbc_file}},$.);
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /Gearef\(context,\s*(\w+)\)/) {
+          my $implementation = $1;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+    #Element* element = &ALLOCATE(cbc_context, Element)->Element;
+       if ($line =~ /ALLOCATE\w*\((?:cbc_)?context,\s*(\w+)\)/) {
+          my $implementation = $1;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /ALLOCATE_(?:PTR_)?ARRAY\((?:cbc_)?context,\s*(\w+),[\s\w]+\)/) {
+          my $implementation = $1;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /new\s+(\w+?)\([\w\s]*\);/) {
+          my $implementation = $1;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /ALLOCATE_DATA_GEAR\((\w+),\s*(\w+)\)/) {
+          my $implementation = $2;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          next;
+       }
+
+       #TaskManagerImpl* taskManager = (TaskManagerImpl*)GearImpl(context, TaskManager, taskManager);
+       if ($line =~ /\((\w+)\*\)GearImpl\(context,\s*(\w+),\s*(\w+)\)/) {
+          my $interface = $2;
+          my $implementation = $1;
+          push(@{$counter{impl}->{$implementation}->{$cbc_file}},$.);
+          push(@{$counter{interfaces}->{$interface}->{$cbc_file}},$.);
+          next;
+       }
+
+       if ($line =~ /^__code/) {
+         while ($line =~ /struct (\w+)\s*\*/g) {
+           next if $1 eq "Context";
+           next if (exists $counter{interfaces}->{$1});
+           push(@{$counter{impl}->{$1}->{$cbc_file}},$.);
+         }
+       }
+    }
+    close $fh;
+  }
+  use Data::Dumper;
+
+  for my $cg_name (keys %include_pool) {
+    my @tmp_cbc_file_names  = keys %{$include_pool{$cg_name}};
+    my $tmp_cbc_file_name  = shift @tmp_cbc_file_names;
+    if (exists $counter{interfaces}->{$cg_name}){
+      push(@{$counter{interfaces}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
+      delete $include_pool{$cg_name};
+      next;
+    }
+
+    if (exists $counter{impl}->{$cg_name}){
+      push(@{$counter{impl}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
+      delete $include_pool{$cg_name};
+      next;
+    }
+    push(@{$counter{interfaces}->{$cg_name}->{$tmp_cbc_file_name}},$include_pool{$cg_name}->{$tmp_cbc_file_name});
+    delete $include_pool{$cg_name};
+  }
+
+  $counter{interfaces}->{Meta}++;
+  $counter{interfaces}->{TaskManager}++;
+  print "-----------\n";
+  print Dumper \%counter;
+  print "-----------\n";
+  return \%counter;
+}
+
+sub docking_header_name_to_path {
+  my ($class, $search_bash_path, $targets) = @_;
+  my %res;
+  map { $res{$_}++ } @$targets;
+
+  my $header_paths = Gears::Util->find_headers_path($search_bash_path);
+  map {
+    if (/(\w+)\.(?:h|dg)$/) {
+        my $header_file = $1;
+        if (exists $res{$header_file}) {
+          if ($res{$header_file} =~ /^\d+$/){
+            $res{$header_file} = $_;
+          } elsif (($_ =~ /\.dg$/) && ($res{$header_file} =~ /\.h$/)) {
+            $res{$header_file} = $_;
+          }
+        }
+    }
+  } sort @$header_paths;
+  return \%res;
+}
 
 1;
--- a/src/gearsTools/pmake.pl	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/pmake.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -10,7 +10,7 @@
 my $curdir = getcwd;
 
 if (@ARGV) {
-  if ($ARGV[0] =~ /--delete/) {
+  if ($ARGV[0] =~ /--del/) {
     my @current_dir_file = glob "*";
     map { print "$_\n";} @current_dir_file;
     print "delete all files? > [y/n]\n";
--- a/src/gearsTools/trans_impl.pl	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/gearsTools/trans_impl.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -13,23 +13,29 @@
 getopts("wo:" => \%opt);
 
 my $impl_file = shift or die 'require impl file';
-my $impl_ir         = Gears::Util->parse_with_rewrite(File::Spec->rel2abs($impl_file));
-my $interface_file  = Gears::Util->find_header($impl_ir->{isa},"$FindBin::Bin/..");
+my $impl_ir         = Gears::Util->parse_with_separate_code_data_gears(File::Spec->rel2abs($impl_file));
+my $interface_file  = Gears::Util->find_using_interface_header($impl_ir->{isa},"$FindBin::Bin/..");
 
-my $inter_ir        = Gears::Util->parse_with_rewrite($interface_file);
-
+my $inter_ir        = Gears::Util->parse_with_separate_code_data_gears($interface_file);
 
 my $output_file = $impl_file;
 $output_file =~ s/\.h/.cbc/;
 my $stdout    = *STDOUT;
 
 if ($opt{w}) {
+    if(-f $output_file) {
+      update_file($output_file, $inter_ir, $impl_ir, $impl_file);
+      exit 0;
+    }
     open $stdout, '>', $output_file;
 } elsif ($opt{o}) {
+    if(-f $opt{o}) {
+      update_file($opt{o}, $inter_ir, $impl_ir, $impl_file);
+      exit 0;
+    }
     open $stdout, '>', $opt{o};
 }
 
-
 emit_include_part($stdout, $inter_ir->{name});
 emit_impl_header_in_comment($stdout, $impl_file);
 emit_constracutor($stdout,$impl_ir,$inter_ir);
@@ -99,36 +105,10 @@
         }
   }
 
-  #for my $datum (@inter_data) {
-  #      # remove macro, comment block
-  #      $datum =~ s|//[\s\w]+||;
-  #      if ($datum =~ /^\s+#/) {
-  #        next;
-  #      }
-
-  #      if ($datum =~ /\w+\s\w+\*\s(\w+)/) {
-  #          print $out "    ${instance_inter}->$1 = NULL;\n";
-  #          next;
-  #      }
-  #      if ($datum =~ /\w+\s\w+\s(\w+)/) {
-  #          print $out "    ${instance_inter}->$1 = 0;\n";
-  #          next;
-  #      }
-  #      if ($datum =~ /\w+(\*)?\s(\w+)/) {
-  #          my $is_pointer = $1;
-  #          my $var_name = $2;
-  #          if ($1) {
-  #              print $out "    ${instance_inter}->$var_name = NULL;\n";
-  #          } else {
-  #              print $out "    ${instance_inter}->$var_name  = 0;\n";
-  #          }
-  #      }
-  #}
-
 
   for my $code (@{$impl_ir->{codes}}) {
       my $code_gear = $code->{name};
-      print $out "    ${instance_impl}->$code_gear = C_$code_gear$impl_ir->{name};\n"
+      print $out "    ${instance_impl}->$code_gear = C_$code_gear;\n"
   }
 
   for my $code (@{$inter_ir->{codes}}) {
@@ -167,24 +147,8 @@
       }
       print $out "__code $cg->{name}$impl(";
       print $out "$data_gears) {\n\n";
-
-      #__code next(...), __code whenEmpty(...)
-      my @cg = ();
-      while ($data_gears =~ /__code ([\w(\.)\*\s,]+?\)),?/g) {
-        push(@cg, $1);
-      }
+      _emit_cg($out,$data_gears);
 
-      if (@cg) {
-        if (@cg == 2) {
-          print $out "    if (:TODO:) {\n";
-          print $out "         goto ",shift(@cg),";\n";
-          print $out "    }\n";
-          print $out "    goto ",shift(@cg),";\n";
-        } else {
-          print $out "    goto ",shift(@cg),";\n";
-        }
-      }
-      print $out "}\n\n";
     }
   }
 
@@ -198,23 +162,51 @@
 
     print $out "__code $code_ir->{name}$impl(";
     print $out "$data_gears) {\n\n";
-
-    #__code next(...), __code whenEmpty(...)
-    my @cg = ();
-    while ($data_gears =~ /__code ([\w(\.)\*\s,]+?\)),?/g) {
-      push(@cg, $1);
-    }
-
-    if (@cg) {
-      if (@cg == 2) {
-        print $out "    if (:TODO:) {\n";
-        print $out "         goto ",shift(@cg),";\n";
-        print $out "    }\n";
-        print $out "    goto ",shift(@cg),";\n";
-      } else {
-        print $out "    goto ",shift(@cg),";\n";
-      }
-    }
-    print $out "}\n\n";
+    _emit_cg($out,$data_gears);
   }
 }
+
+sub _emit_cg {
+  my ($out, $data_gears) = @_;
+  my @cg = ();
+  while ($data_gears =~ /__code ([\w(\.)\*\s,]+?\)),?/g) {
+    push(@cg, $1);
+  }
+  if (@cg) {
+    if (@cg == 2) {
+      print $out "    if (:TODO:) {\n";
+      print $out "         goto ",shift(@cg),";\n";
+      print $out "    }\n";
+      print $out "    goto ",shift(@cg),";\n";
+    } else {
+      print $out "    goto ",shift(@cg),";\n";
+    }
+  }
+  print $out "}\n\n";
+}
+
+sub update_file {
+    my ($output_file, $inter_ir, $impl_ir, $impl_file) = @_;
+    my $under_code = collection_save_code_gears($output_file,$inter_ir->{name});
+    open my $fh, '>', $output_file;
+    emit_include_part($fh, $inter_ir->{name});
+    emit_impl_header_in_comment($fh, $impl_file);
+    emit_constracutor($fh,$impl_ir,$inter_ir);
+    map { print $fh $_ } @{$under_code};
+    close $fh;
+}
+
+sub collection_save_code_gears {
+  my ($output_file,$interface_name) = @_;
+  open my $fh, '<', $output_file;
+  while (my $line = <$fh>) {
+    if ($line =~ /\s*return $interface_name;\s*/) {
+      $line = <$fh>; # } skip...
+      last;
+    }
+  }
+
+  my @res;
+  push(@res, <$fh>);
+  return \@res;
+}
--- a/src/gearsTools/update_context.pl	Fri Feb 07 14:48:24 2020 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#!/usr/bin/env perl
-use strict;
-use warnings;
-use Getopt::Std;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-use Gears::Util;
-
-my %opt;
-getopts("wc" => \%opt);
-
-my $interface_file = shift or die "require itnerface file";
-my $h2context = Gears::Util->parse_interface($interface_file);
-my $context = Gears::Util->h2context_str($h2context);
-
-if ($opt{c}) {
-  print "$context";
-  exit 0;
-}
-
-my ($first,$last) = slup_context_h($h2context->{name});
-
-if ($opt{w}) {
-  context_write(@{$first},$context,@{$last});
-} else {
-  context_dump(@{$first},$context,@{$last});
-}
-
-
-sub slup_context_h {
-  open my $fh, '<', 'context.h';
-  
-  my $data_gear_name = shift;
-
-  my @first_context_headers = ();
-  my @last_context_headers = ();
-  
-  while (my $line = <$fh>) {
-    if ( $line =~ /union Data end/) {
-      push(@last_context_headers, $line);
-      push(@last_context_headers, <$fh>);
-      last;
-    }
-    if ( $line =~ /struct $data_gear_name/) {
-      print "WARN! $data_gear_name struct already exists\n";
-      exit 1;
-    }
-    push(@first_context_headers, $line);
-  }
-
-  close $fh;
-  
-  #print "@first_context_headers\n";
-  #print "@last_context_headers\n";
-  return (\@first_context_headers,\@last_context_headers);
-}
-
-sub context_dump {
-  for my $line (@_) {
-    print "$line";
-  }
-}
-
-sub context_write {
-  open my $fh, '>', "context.h";
-  for my $line (@_) {
-    print $fh "$line";
-  }
-  close $fh;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gearsTools/update_implheader.pl	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,102 @@
+#!/usr/bibn/env perl
+use strict;
+use warnings;
+
+use Carp qw/croak/;
+
+my $header_file = shift // croak 'require header file!';
+my ($header_con,$interface_name) = search_slurp_header_file($header_file);
+
+my %cbc_code_names = ( order => 0, codes => {});
+
+while (@ARGV) {
+  find_codes_from_cbc(shift @ARGV, $interface_name, \%cbc_code_names);
+}
+
+map  { push(@{$cbc_code_names{order_list}}, $_)}
+        sort { $cbc_code_names{codes}->{$a}->{order} <=> $cbc_code_names{codes}->{$b}->{order} } keys %{$cbc_code_names{codes}};
+
+my $write_codes = create_new_header_codes($header_con,\%cbc_code_names);
+exit unless $write_codes;
+update_header($header_file,$write_codes);
+
+sub search_slurp_header_file {
+  my $header_file = shift;
+
+  my %contents;
+  my %order;
+  my $i = 0;
+  my $interface_name;
+
+  open my $fh, '<', $header_file;
+
+  if (<$fh> =~ /struct (\w+)\s*</) {
+    $interface_name = $1;
+  }
+  while (my $line = <$fh>) {
+    chomp $line;
+    if ($line =~ /\A\s*__code (\w+)\(/) {
+      $contents{$1} = $line;
+      $order{$1} = $i;
+      $i++;
+    }
+  }
+  close $fh;
+  my @order_code_names;
+  map  { push(@order_code_names, $_)}  sort { $order{$a} <=> $order{$b} } keys %order;
+  return { codes => \%contents, order => \@order_code_names }, $interface_name;
+}
+
+sub find_codes_from_cbc {
+  my ($cbc_file, $inter_name, $ccn) = @_;
+
+  open my $fh, '<', $cbc_file;
+  while (my $line = <$fh>) {
+    chomp $line;
+    if ($line =~ /\A\s*__code (\w+)\(/) {
+      my $cg_name = $1;
+      $line =~ s/\s*{\s*[\w\/\:]*/;/;
+      $line =~ s/struct $inter_name/Type/g;
+      $ccn->{codes}->{$cg_name} = { line =>$line, file => $cbc_file, order => $ccn->{order} };
+      $ccn->{order}++;
+    }
+  }
+  close $fh;
+}
+
+sub create_new_header_codes {
+  my ($header_con, $cbc_con) = @_;
+  return 0 if (@{$header_con->{order}} == $cbc_con->{order});
+
+  my @res;
+  my @hcodes = @{$header_con->{order}};
+  my %cbc_codes = %{$cbc_con->{codes}};
+  for my $hc (@hcodes) {
+    if (exists $cbc_codes{$hc}) {
+      push(@res, $cbc_codes{$hc}->{line});
+      delete $cbc_codes{$hc};
+    }
+  }
+
+  push(@res, "");
+  if (%cbc_codes) {
+    map { push(@res, $cbc_codes{$_}->{line})} sort { $cbc_codes{$a}->{order} <=> $cbc_codes{$b}->{order}} keys %cbc_codes;
+  }
+  return \@res;
+}
+
+sub update_header {
+  my ($header_file,$write_codes) = @_;
+  open my $fh, '+<', $header_file;
+  my $def_impl = <$fh>;
+  my ($impl, $interface);
+  if ($def_impl =~ /typedef\s*struct\s*(\w+)\s*<[\w\s,]+>\s*impl\s*(\w+)\s*{/) {
+    $impl = $1;
+    $interface = $2;
+  }
+
+  map { print $fh "    $_\n"}  @$write_codes;
+  print $fh "    __code next(...);\n";
+  print $fh "} $impl;\n";
+  close $fh;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/impl/KernelError.cbc	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,47 @@
+#include "param.h"
+#include "proc.h"
+#interface "Err.h"
+
+// ----
+// typedef struct KernelError <Type, Isa> impl Error {
+//   __code infinity_loop(Type* error, next(...));
+// } KernelError;
+// ----
+
+Err* createKernelError(struct Context* cbc_context) {
+    struct Err* err  = new Err();
+    struct KernelError* kernel_error = new KernelError();
+    err->err = (union Data*)kernel_error;
+    kernel_error->err = (union Data*)kernel_error;
+    kernel_error->infinity_loop = C_infinity_loopKernelError;
+    err->error = C_errorKernelError;
+    err->panic = C_panicKernelError;
+    return err;
+}
+
+__code infinity_loopKernelError(struct KernelError* err, __code next(...)) {
+
+}
+
+__code errorKernelError(struct KernelError* err, int err_code, __code next(...)) {
+
+    goto next(...);
+}
+
+__code panicKernelError(struct KernelError* err, char* msg) {
+    extern struct cpu* cpu;
+    extern struct { struct spinlock lock; int locking; } cons;
+    extern int panicked;
+
+    cli();
+    cons.locking = 0;
+
+    cprintf("cpu%d: panic: ", cpu->id);
+
+    show_callstk(msg);
+    panicked = 1; // freeze other CPU
+
+    goto infinity_loopKernelError(err, err->inifinity_loop);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/impl/KernelError.h	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,4 @@
+typedef struct KernelError <Type, Isa> impl Err {
+  __code infinity_loop(Type* err, __code next(...));
+  __code next(...);
+} KernelError;
--- a/src/impl/kernel_error.cbc	Fri Feb 07 14:48:24 2020 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-#include "../context.h"
-#interface "ErrorGear.h"
-
-// ----
-// typedef struct KernelError <Type, Isa> impl ErrorGear {
-// } KernelError;
-// ----
-
-ErrorGear* createKernelError(struct Context* cbc_context) {
-    struct ErrorGear* error_gear  = new ErrorGear();
-    struct KernelError* kernel_error = new KernelError();
-    error_gear->error_gear = (union Data*)kernel_error;
-    error_gear->err_code  = 0;
-    error_gear->msg = NULL;
-    error_gear->error = C_errorKernelError;
-    error_gear->panic = C_panicKernelError;
-    return error_gear;
-}
-__code errorKernelError(int err_code,...) {
-
-}
-
-__code panicKernelError(char* msg) {
-
-}
-
--- a/src/impl/kernel_error.h	Fri Feb 07 14:48:24 2020 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-typedef struct KernelError <Type, Isa> impl ErrorGear {
-} KernelError;
--- a/src/impl/pipe.h	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/impl/pipe.h	Fri Feb 07 14:58:30 2020 +0900
@@ -9,8 +9,10 @@
     int writeopen;  // write fd is still open
 
     int ref;   // reference count
+    /*
     char readable;
     char writable;
+    */
     unsigned int off;
 
     // interface field
--- a/src/impl/vm_impl.cbc	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/impl/vm_impl.cbc	Fri Feb 07 14:58:30 2020 +0900
@@ -3,16 +3,31 @@
 
 // ----
 // typedef struct vm_impl<Impl, Isa> impl vm{
-//     union Data* vm_impl;
-//     uint i;
-//     pte_t* pte;
-//     uint sz;
-//  
-//     __code loaduvm_ptesize_check(Type* vm_impl, __code next(...));
-//     __code loaduvm_loop(Type* vm_impl, uint i, pte_t* pte, uint sz, __code next(...));
-//     __code next(...);
-//  
-// 
+//     __code kpt_alloc_check_impl(Type* vm_impl, __code next(...));
+//     __code loaduvm_ptesize_checkvm_impl(Type* vm_impl, __code next(int ret, ...));
+//     __code loaduvm_check_PTE_SZ(Type* vm_impl, __code next(int ret, ...));
+//     __code copyout_loop_check_n(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, char* buf, __code next(...));
+//     __code clearpteu_check_ptevm_impl(Type* vm_impl, pde_t* pgdir, char* uva, __code next(int ret, ...));
+//     __code uva2ka_check_pe_types(Type* vm, pde_t* pgdir, char* uva, __code next(int ret, ...));
+//     __code copyout_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0,  __code next(int ret, ...));
+//     __code switchuvm_check_pgdirvm_impl(Type* vm_impl, proc_struct* p, __code next(...));
+//     __code init_inituvm_check_sz(Type* vm_impl, pde_t* pgdir, char* init, uint sz, __code next(...));
+//
+//     __code loaduvm_loopvm_impl(Type* vm_impl, __code next(int ret, ...));
+//     __code loaduvm_check_pgdir(Type* vm_impl, __code next(int ret, ...));
+//     __code loaduvm_exit(Type* vm_impl, __code next(int ret, ...));
+//     __code allocuvm_check_newszvm_impl(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(int ret, ...));
+//     __code allocuvm_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, char* mem, uint a, __code next(int ret, ...));
+//     __code copyuvm_check_nullvm_impl(Type* vm_impl, pde_t* pgdir, uint sz, __code next(int ret, ...));
+//     __code copyuvm_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+//     __code copyuvm_loop_check_walkpgdir(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+//     __code copyuvm_loop_check_pte(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+//     __code copyuvm_loop_check_mem(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+//     __code copyuvm_loop_check_mappages(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+//     __code copyuvm_loop_bad(Type* vm_impl, pde_t* d, __code next(int ret, ...));
+//     __code uva2ka_check_pte_ap(Type* vm, pde_t* pgdir, char* uva, pte_t* pte, __code next(int ret, ...));
+//     __code paging_intvmvm_impl(Type* vm_impl, uint phy_low, uint phy_hi, __code next(...));
+//     __code copyout_loop_check_pa0(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, __code next(int ret, ...));
 // } vm_impl;
 // ----
 
@@ -21,20 +36,55 @@
     struct vm_impl* vm_impl = new vm_impl();
     vm->vm = (union Data*)vm_impl;
     vm_impl->vm_impl = NULL;
-    vm_impl->i  = 0;
-    vm_impl->pte = NULL;
+    vm_impl->ret  = 0;
+    vm_impl->pgdir = NULL;
+    vm_impl->va  = 0;
+    vm_impl->pp = NULL;
+    vm_impl->len  = 0;
+    vm_impl->va0  = 0;
+    vm_impl->pa0 = NULL;
+    vm_impl->n  = 0;
+    vm_impl->buf = NULL;
+    vm_impl->uva = NULL;
+    vm_impl->vm = NULL;
+    vm_impl->p = NULL;
+    vm_impl->init = NULL;
     vm_impl->sz  = 0;
-    vm_impl->loaduvm_ptesize_check = C_loaduvm_ptesize_checkvm_impl;
-    vm_impl->loaduvm_loop = C_loaduvm_loopvm_impl;
-    vm_impl->allocuvm_check_newsz = C_allocuvm_check_newszvm_impl;
-    vm_impl->allocuvm_loop = C_allocuvm_loopvm_impl;
-    vm_impl->copyuvm_check_null = C_copyuvm_check_nullvm_impl;
-    vm_impl->copyuvm_loop = C_copyuvm_loopvm_impl;
+    vm_impl->oldsz  = 0;
+    vm_impl->newsz  = 0;
+    vm_impl->mem = NULL;
+    vm_impl->a  = 0;
+    vm_impl->d = NULL;
+    vm_impl->pte = NULL;
+    vm_impl->pa  = 0;
+    vm_impl->i  = 0;
+    vm_impl->ap  = 0;
+    vm_impl->phy_low  = 0;
+    vm_impl->phy_hi  = 0;
+    vm_impl->kpt_alloc_check_impl = C_kpt_alloc_check_impl;
+    vm_impl->loaduvm_ptesize_checkvm_impl = C_loaduvm_ptesize_checkvm_impl;
+    vm_impl->loaduvm_check_PTE_SZ = C_loaduvm_check_PTE_SZ;
+    vm_impl->copyout_loop_check_n = C_copyout_loop_check_n;
+    vm_impl->clearpteu_check_ptevm_impl = C_clearpteu_check_ptevm_impl;
     vm_impl->uva2ka_check_pe_types = C_uva2ka_check_pe_types;
-    vm_impl->paging_intvm_impl = C_paging_intvmvm_impl;
     vm_impl->copyout_loopvm_impl = C_copyout_loopvm_impl;
     vm_impl->switchuvm_check_pgdirvm_impl = C_switchuvm_check_pgdirvm_impl;
     vm_impl->init_inituvm_check_sz = C_init_inituvm_check_sz;
+    vm_impl->loaduvm_loopvm_impl = C_loaduvm_loopvm_impl;
+    vm_impl->loaduvm_check_pgdir = C_loaduvm_check_pgdir;
+    vm_impl->loaduvm_exit = C_loaduvm_exit;
+    vm_impl->allocuvm_check_newszvm_impl = C_allocuvm_check_newszvm_impl;
+    vm_impl->allocuvm_loopvm_impl = C_allocuvm_loopvm_impl;
+    vm_impl->copyuvm_check_nullvm_impl = C_copyuvm_check_nullvm_impl;
+    vm_impl->copyuvm_loopvm_impl = C_copyuvm_loopvm_impl;
+    vm_impl->copyuvm_loop_check_walkpgdir = C_copyuvm_loop_check_walkpgdir;
+    vm_impl->copyuvm_loop_check_pte = C_copyuvm_loop_check_pte;
+    vm_impl->copyuvm_loop_check_mem = C_copyuvm_loop_check_mem;
+    vm_impl->copyuvm_loop_check_mappages = C_copyuvm_loop_check_mappages;
+    vm_impl->copyuvm_loop_bad = C_copyuvm_loop_bad;
+    vm_impl->uva2ka_check_pte_ap = C_uva2ka_check_pte_ap;
+    vm_impl->paging_intvmvm_impl = C_paging_intvmvm_impl;
+    vm_impl->copyout_loop_check_pa0 = C_copyout_loop_check_pa0;
     vm->init_vmm = C_init_vmmvm_impl;
     vm->kpt_freerange = C_kpt_freerangevm_impl;
     vm->kpt_alloc = C_kpt_allocvm_impl;
@@ -47,15 +97,17 @@
     vm->uva2ka = C_uva2kavm_impl;
     vm->copyout = C_copyoutvm_impl;
     vm->paging_int = C_paging_intvm_impl;
+    vm->void_ret = C_vm_void_ret;
     return vm;
 }
 
+
 extern struct {
     struct spinlock lock;
     struct run *freelist;
 } kpt_mem;
 
-__code init_vmmvm_impl(struct vm_impl* vm, __code next(...)) {
+__code init_vmmvm_impl(struct vm_impl* vm,__code next(...)) {
     initlock(&kpt_mem.lock, "vm");
     kpt_mem.freelist = NULL;
     
@@ -92,22 +144,28 @@
 
 typedef struct proc proc;
 __code switchuvmvm_impl(struct vm_impl* vm , struct proc* p, __code next(...)) { //:skip
-
-    goto switchuvm_check_pgdirvm_impl(...);
+    Gearef(cbc_context, vm_impl)->p = p;
+    Gearef(cbc_context, vm_impl)->next = next;
+    goto switchuvm_check_pgdirvm_impl(vm, p, next(...));
 }
 
 __code init_inituvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...)) { 
 
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->init = init;
+    Gearef(cbc_context, vm_impl)->sz = sz;
+    Gearef(cbc_context, vm_impl)->next = next;
     goto init_inituvm_check_sz(vm, pgdir, init, sz, next(...));
 }
 
 __code loaduvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz,  __code next(...)) {
-    vm->pgdir = pgdir;
-    vm->addr = addr;
-    vm->ip = ip;
-    vm->offset = offset;
-    vm->sz = sz;
-    
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->addr = addr;
+    Gearef(cbc_context, vm_impl)->ip = ip;
+    Gearef(cbc_context, vm_impl)->offset = offset;
+    Gearef(cbc_context, vm_impl)->sz = sz;
+    Gearef(cbc_context, vm_impl)->next = next;
+
     goto loaduvm_ptesize_checkvm_impl(vm, next(...));
 }
 
@@ -143,3 +201,6 @@
     goto paging_intvmvm_impl(vm, phy_low, phy_hi, next(...));
 }
 
+__code vm_void_ret(struct vm_impl* vm) {
+    return;
+}
--- a/src/impl/vm_impl.h	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/impl/vm_impl.h	Fri Feb 07 14:58:30 2020 +0900
@@ -1,47 +1,27 @@
 typedef struct vm_impl<Impl, Isa> impl vm{
-    union Data* vm_impl;
-    uint i;
-    pte_t* pte;
-    uint sz;
-    pde_t* pgdir;
-    char* addr;
-    struct inode* ip;
-    uint offset;
-    uint pa;
-    uint n;
-    uint oldsz;
-    uint newsz;
-    uint a;
-    int ret;
-    char* mem;
-    char* uva;
-    pde_t* d;
-    uint ap;
-    uint phy_low;
-    uint phy_hi;
-    uint va;
-    void* pp;
-    uint len;
-    char* buf;
-    char* pa0;
-    uint va0;
-    proc_struct* p;
-    char* init;
-
     __code kpt_alloc_check_impl(Type* vm_impl, __code next(...));
-    __code loaduvm_ptesize_check(Type* vm_impl, __code next(int ret, ...));
-    __code loaduvm_loop(Type* vm_impl, uint i, pte_t* pte, uint sz, __code next(int ret, ...));
-    __code allocuvm_check_newsz(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(...));
-    __code allocuvm_loop(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, uint a, __code next(...));
-    __code copyuvm_check_null(Type* vm_impl, pde_t* pgdir, uint sz, __code next(...));
-    __code copyuvm_loop(Type* vm_impl,pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
-    __code clearpteu_check_ptevm_impl(Type* vm_impl, pde_t* pgdir, char* uva,  __code next(...));
-    __code uva2ka_check_pe_types(Type* vm_impl, pde_t* pgdir, char* uva, __code next(...));
-    __code paging_intvm_impl(Type* vm_impl, uint phy_low, uint phy_hi, __code next(...));
-    __code copyout_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, __code next(...));
-    __code switchuvm_check_pgdirvm_impl(struct vm_impl* vm_impl, struct proc* p, __code next(...));
-    __code init_inituvm_check_sz(struct vm_impl* vm_impl, pde_t* pgdir, char* init, uint sz, __code next(...));
+    __code loaduvm_ptesize_checkvm_impl(Type* vm_impl,char* addr,  __code next(int ret, ...));
+    __code loaduvm_check_PTE_SZ(Type* vm_impl, uint sz, uint i, uint n, struct inode* ip, uint pa, uint offset, __code next(int ret, ...));
+    __code copyout_loop_check_n(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, char* buf, __code next(...));
+    __code clearpteu_check_ptevm_impl(Type* vm_impl, pde_t* pgdir, char* uva, __code next(int ret, ...));
+    __code uva2ka_check_pe_types(Type* vm, pde_t* pgdir, char* uva, __code next(int ret, ...));
+    __code copyout_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0,  __code next(int ret, ...));
+    __code switchuvm_check_pgdirvm_impl(Type* vm_impl, proc_struct* p, __code next(...));
+    __code init_inituvm_check_sz(Type* vm_impl, pde_t* pgdir, char* init, uint sz, __code next(...));
+    __code loaduvm_loopvm_impl(Type* vm_impl, uint i, uint sz,__code next(int ret, ...));
+    __code loaduvm_check_pgdir(Type* vm_impl, pte_t* pte, pde_t* pgdir, uint i, char* addr, uint pa, __code next(int ret, ...));
+    __code loaduvm_exit(Type* vm_impl, __code next(int ret, ...));
+    __code allocuvm_check_newszvm_impl(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(int ret, ...));
+    __code allocuvm_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, char* mem, uint a, __code next(int ret, ...));
+    __code copyuvm_check_nullvm_impl(Type* vm_impl, pde_t* pgdir, uint sz, __code next(int ret, ...));
+    __code copyuvm_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+    __code copyuvm_loop_check_walkpgdir(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+    __code copyuvm_loop_check_pte(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+    __code copyuvm_loop_check_mem(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+    __code copyuvm_loop_check_mappages(Type* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
+    __code copyuvm_loop_bad(Type* vm_impl, pde_t* d, __code next(int ret, ...));
+    __code uva2ka_check_pte_ap(Type* vm, pde_t* pgdir, char* uva, pte_t* pte, __code next(int ret, ...));
+    __code paging_intvmvm_impl(Type* vm_impl, uint phy_low, uint phy_hi, __code next(...));
+    __code copyout_loop_check_pa0(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, uint va0, char* pa0, uint n, __code next(int ret, ...));
     __code next(...);
 } vm_impl;
-
-
--- a/src/impl/vm_impl_private.cbc	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/impl/vm_impl_private.cbc	Fri Feb 07 14:58:30 2020 +0900
@@ -4,25 +4,24 @@
 #include "defs.h"
 #include "memlayout.h"
 #interface "vm_impl.h"
+#interface "Err.h"
 
 /*
-vm_impl* createvm_impl2();
+vm_impl* createvm_impl2(); //:skip
 */
 
-__code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    char* addr = vm_impl->addr;
-
+__code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl,char* addr,  __code next(int ret, ...)) {
     if ((uint) addr %PTE_SZ != 0) {
-       // goto panic 
+       char* msg = "addr % PTE_SZ != 0";
+       struct Err* err = createKernelError(&proc->cbc_context);
+       Gearef(cbc_context, Err)->msg = msg;
+       goto meta(cbc_context, err->panic);
     }
 
     goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
 }
 
-__code loaduvm_loopvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    uint i = vm_impl->i;
-    uint sz = vm_impl->sz;
-
+__code loaduvm_loopvm_impl(struct vm_impl* vm_impl, uint i, uint sz,__code next(int ret, ...)) {
     if (i < sz) {
         goto loaduvm_check_pgdir(vm_impl, next(ret, ...));  
     } 
@@ -60,33 +59,24 @@
 }
 
 
-__code loaduvm_check_pgdir(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    pte_t* pte = vm_impl->pte;
-    pde_t* pgdir = vm_impl->pgdir;
-    uint i = vm_impl->i;
-    char* addr = vm_impl->addr;
-    uint pa = vm_impl->pa;
-
+__code loaduvm_check_pgdir(struct vm_impl* vm_impl, pte_t* pte, pde_t* pgdir, uint i, char* addr, uint pa, __code next(int ret, ...)) {
     if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
-        // goto panic
+       char* msg = "pte != walkpgdir...";
+       struct Err* err = createKernelError(&proc->cbc_context);
+       Gearef(cbc_context, Err)->msg = msg;
+       goto meta(cbc_context, err->panic);
     } 
     pa = PTE_ADDR(*pte);
 
-    vm_impl->pte = pte; 
-    vm_impl->pgdir = pgdir; 
-    vm_impl->addr = addr; 
-    vm_impl->pa = pa; 
+    Gearef(cbc_context, vm_impl)->pte   = pte;
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->addr  = addr;
+    Gearef(cbc_context, vm_impl)->pa    = pa;
 
     goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
 }
 
-__code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    uint sz = vm_impl->sz;
-    uint i = vm_impl->i;
-    uint n = vm_impl->n;
-    struct inode* ip = vm_impl->ip;
-    uint pa = vm_impl->pa;
-    uint offset = vm_impl->offset;
+__code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, uint sz, uint i, uint n, struct inode* ip, uint pa, uint offset, __code next(int ret, ...)) {
     
     if (sz - i < PTE_SZ) {
         n = sz - i;
@@ -99,7 +89,7 @@
         goto next(ret, ...);
     }
 
-    vm_impl->n = n;
+    Gearef(cbc_context, vm_impl)->n = n;
  
     goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
 }
@@ -157,8 +147,10 @@
     release(&kpt_mem.lock);
 
     if ((r == NULL) && ((r = kmalloc (PT_ORDER)) == NULL)) {
-        // panic("oom: kpt_alloc");
-        // goto panic
+         char* msg = "oom: kpt_alloc";
+         struct Err* err = createKernelError(&proc->cbc_context);
+         Gearef(cbc_context, Err)->msg = msg;
+         goto meta(cbc_context, err->panic);
     }
 
     memset(r, 0, PT_SZ);
@@ -206,8 +198,10 @@
 
     pte = walkpgdir(pgdir, uva, 0);
     if (pte == 0) {
-        // panic("clearpteu");
-        // goto panic;
+         char* msg = "clearpteu";
+         struct Err* err = createKernelError(&proc->cbc_context);
+         Gearef(cbc_context, Err)->msg = msg;
+         goto meta(cbc_context, err->panic);
     }
 
     // in ARM, we change the AP field (ap & 0x3) << 4)
@@ -245,8 +239,10 @@
 
 __code copyuvm_loop_check_walkpgdir(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
         if ((pte = walkpgdir(pgdir, (void *) i, 0)) == 0) {
-            // panic("copyuvm: pte should exist");
-            // goto panic();
+           char* msg = "copyuvm: pte should exist";
+           struct Err* err = createKernelError(&proc->cbc_context);
+           Gearef(cbc_context, Err)->msg = msg;
+           goto meta(cbc_context, err->panic);
         }
     goto copyuvm_loop_check_pte(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
 }
@@ -254,8 +250,10 @@
 __code copyuvm_loop_check_pte(struct vm_impl* vm_impl, pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...)) {
 
         if (!(*pte & PE_TYPES)) {
-            // panic("copyuvm: page not present");
-            // goto panic();
+           char* msg = "copyuvm: page not present";
+           struct Err* err = createKernelError(&proc->cbc_context);
+           Gearef(cbc_context, Err)->msg = msg;
+           goto meta(cbc_context, err->panic);
         }
 
     goto copyuvm_loop_check_mem(vm_impl, pgdir, sz, d, pte, pa, i, ap, mem, __code next(int ret, ...));
@@ -359,6 +357,11 @@
     len -= n;
     buf += n;
     va = va0 + PTE_SZ;
+    Gearef(cbc_context, vm_impl)->n = n;
+    Gearef(cbc_context, vm_impl)->len = len;
+    Gearef(cbc_context, vm_impl)->buf = buf;
+    Gearef(cbc_context, vm_impl)->va = va;
+
     goto copyout_loopvm_impl(vm_impl, pgdir, va, pp, len, va0, pa0, next(...));
 }
 
@@ -369,7 +372,10 @@
     pushcli();
 
     if (p->pgdir == 0) {
-        panic("switchuvm: no pgdir");
+        char* msg = "switchuvm: no pgdir";
+        struct Err* err = createKernelError(&proc->cbc_context);
+        Gearef(cbc_context, Err)->msg = msg;
+        goto meta(cbc_context, err->panic);
     }
 
     val = (uint) V2P(p->pgdir) | 0x00;
@@ -386,8 +392,10 @@
     char* mem;
 
     if (sz >= PTE_SZ) {
-        // goto panic;
-        // panic("inituvm: more than a page");
+       char* msg = "inituvm: more than a page";
+       struct Err* err = createKernelError(&proc->cbc_context);
+       Gearef(cbc_context, Err)->msg = msg;
+       goto meta(cbc_context, err->panic);
     }
 
     mem = alloc_page();
@@ -397,3 +405,4 @@
 
     goto next(...);
 }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/interface/Err.h	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,5 @@
+typedef struct Err <Type, Impl> {
+  __code error(Impl* err, int err_code, __code next(...));
+  __code panic(Impl* err, char* msg);
+  __code next(...);
+} Err;
--- a/src/interface/ErrorGear.h	Fri Feb 07 14:48:24 2020 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-typedef struct ErrorGear <Type, Impl> {
-  union Data* error_gear;
-  int err_code;
-  char* msg;
-
-  __code error(int err_code,...);
-  __code panic(char* msg);
-} ErrorGear;
--- a/src/interface/Stack.h	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/interface/Stack.h	Fri Feb 07 14:58:30 2020 +0900
@@ -1,10 +1,4 @@
 typedef struct Stack<Type, Impl>{
-        union Data* stack;
-        union Data* data;
-        union Data* data1;
-        /* Type* stack; */
-        /* Type* data; */
-        /* Type* data1; */
         __code whenEmpty(...);
         __code clear(Impl* stack,__code next(...));
         __code push(Impl* stack,Type* data, __code next(...));
--- a/src/interface/TaskManager.h	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/interface/TaskManager.h	Fri Feb 07 14:58:30 2020 +0900
@@ -1,7 +1,4 @@
 typedef struct TaskManager<Impl>{
-    union Data* taskManager;
-    struct Context* task;
-    struct Element* taskList;
     __code spawn(Impl* taskManager, struct Context* task, __code next(...));
     __code spawnTasks(Impl* taskManagerImpl, struct Element* taskList, __code next1(...));
     __code setWaitTask(Impl* taskManagerImpl, struct Context* task, __code next(...));
--- a/src/interface/vm.h	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/interface/vm.h	Fri Feb 07 14:58:30 2020 +0900
@@ -1,22 +1,4 @@
 typedef struct vm<Type,Impl> {
-    union Data* vm;
-    uint low;
-    uint hi;
-    struct proc* p;
-    pde_t* pgdir;
-    char* init;
-    uint sz;
-    char* addr;
-    struct inode* ip;
-    uint offset;
-    uint oldsz;
-    uint newsz;
-    char* uva;
-    uint va;
-    void* pp;
-    uint len;
-    uint phy_low;
-    uint phy_hi;
     __code init_vmm(Impl* vm, __code next(...));
     __code kpt_freerange(Impl* vm, uint low, uint hi, __code next(...));
     __code kpt_alloc(Impl* vm ,__code next(...));
@@ -29,5 +11,6 @@
     __code uva2ka(Impl* vm, pde_t* pgdir, char* uva, __code next(...));
     __code copyout(Impl* vm, pde_t* pgdir, uint va, void* pp, uint len, __code next(...));
     __code paging_int(Impl* vm, uint phy_low, uint phy_hi, __code next(...));
+    __code void_ret(Impl* vm);
     __code next(...);
 } vm;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ln.h	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,9 @@
+static inline int ln(int sz) {
+    int j = 1 << 6;
+    for (int i = 6; i < 12; i++) {
+        if (sz < j) return i;
+        j <<= 1;
+    }
+    return 12;
+} 
+
--- a/src/proc.cbc	Fri Feb 07 14:48:24 2020 +0900
+++ b/src/proc.cbc	Fri Feb 07 14:58:30 2020 +0900
@@ -6,6 +6,7 @@
 #include "arm.h"
 #include "proc.h"
 #include "spinlock.h"
+#interface "vm.h"
 
 #define __ncode __code
 
@@ -116,19 +117,42 @@
 //PAGEBREAK: 32
 // hand-craft the first user process. We link initcode.S into the kernel
 // as a binary, the linker will generate __binary_initcode_start/_size
+void dummy(struct proc *p, char _binary_initcode_start[], char _binary_initcode_size[])
+{
+    // inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+    goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+
+}
+
+
+
+__ncode cbc_init_vmm_dummy(struct Context* cbc_context, struct proc* p, pde_t* pgdir, char* init, uint sz){//:skip
+
+    struct vm* vm = createvm_impl(cbc_context);
+    // goto vm->init_vmm(vm, pgdir, init, sz , vm->void_ret);
+        Gearef(cbc_context, vm)->vm = (union Data*) vm;
+        Gearef(cbc_context, vm)->pgdir = pgdir;
+        Gearef(cbc_context, vm)->init = init;
+        Gearef(cbc_context, vm)->sz = sz ;
+        Gearef(cbc_context, vm)->next = C_vm_void_ret ;
+    goto meta(cbc_context, vm->init_inituvm);
+}
+
 void userinit(void)
 {
-    struct proc *p;
+    struct proc* p;
     extern char _binary_initcode_start[], _binary_initcode_size[];
 
     p = allocproc();
+    initContext(&p->cbc_context);
+
     initproc = p;
 
     if((p->pgdir = kpt_alloc()) == NULL) {
         panic("userinit: out of memory?");
     }
 
-    inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+    dummy(p, _binary_initcode_start, _binary_initcode_size);
 
     p->sz = PTE_SZ;
 
@@ -150,6 +174,21 @@
     p->state = RUNNABLE;
 }
 
+
+void switchuvm_dummy(struct proc* proc)
+{
+    goto cbc_switchuvm_dummy(&proc->cbc_context, proc);
+}
+
+__ncode cbc_switchuvm_dummy(struct Context* cbc_context, struct proc* proc){
+
+    struct vm* vm = createvm_impl(cbc_context);
+    //Gearef(cbc_context, vm)->vm = (union Data*) vm;
+    Gearef(cbc_context, vm)->p = proc;
+    Gearef(cbc_context, vm)->next = C_vm_void_ret ;
+    goto meta(cbc_context, vm->switchuvm);
+}
+
 // Grow current process's memory by n bytes.
 // Return 0 on success, -1 on failure.
 int growproc(int n)
@@ -170,7 +209,8 @@
     }
 
     proc->sz = sz;
-    switchuvm(proc);
+    // switchuvm(proc);
+    switchuvm_dummy(proc);
 
     return 0;
 }
@@ -187,6 +227,7 @@
     if((np = allocproc()) == 0) {
         return -1;
     }
+    initContext(&np->cbc_context);
 
     // Copy process state from p.
     if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/main_log.c	Fri Feb 07 14:58:30 2020 +0900
@@ -0,0 +1,18 @@
+#include "../ln.h"
+#include "stdio.h"
+
+void print_ln(int n) {
+    printf("n = %d, ln = %d\n",n,ln(n));
+}
+
+int main() {
+   int n = 2; 
+   print_ln(1);
+   print_ln(10);
+   print_ln(100);
+   print_ln(1000);
+   print_ln(10000);
+   print_ln(100000);
+   return 0;
+}
+