package TestCase::Extension {
  use TestCase;
  
  sub spvm_extension_add_int_array : int () {
    my $nums1 = new int[] {1, 2, 3};
    my $nums2 = new int[] {4, 5, 6};
    
    my $nums3 = add_int_array($nums1, $nums2);
    
    if ($nums3->[0] == 5) {
      if ($nums3->[1] == 7) {
        if ($nums3->[2] == 9) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub spvm_extension : int () {
    my $total = sum(2, 3);
    
    if ($total == 5) {
      return 1;
    }
    
    return 0;
  }

  native sub native_api_get_byte_field : byte ($test_case : TestCase);
  native sub native_api_get_short_field : short ($test_case : TestCase);
  native sub native_api_get_int_field : int ($test_case : TestCase);
  native sub native_api_get_long_field : long ($test_case : TestCase);
  native sub native_api_get_float_field : float ($test_case : TestCase);
  native sub native_api_get_double_field : double ($test_case : TestCase);
  native sub native_api_get_object_field : TestCase::Minimal ($test_case : TestCase);
  
  sub native_api_get_set_field : int () {
    
    my $test_case = TestCase->new();
    
    $test_case->{x_byte} = (byte)1;
    $test_case->{x_short} = (short)2;
    $test_case->{x_int} = 3;
    $test_case->{x_long} = 4L;
    $test_case->{x_float} = 0.5f;
    $test_case->{x_double} = 0.025;
    my $minimal1 = TestCase::Minimal->new();
    $test_case->{minimal} = $minimal1;
    
    my $x_byte1 = native_api_get_byte_field($test_case);
    my $x_short1 = native_api_get_short_field($test_case);
    my $x_int1 = native_api_get_int_field($test_case);
    my $x_long1 = native_api_get_long_field($test_case);
    my $x_float1 = native_api_get_float_field($test_case);
    my $x_double1 = native_api_get_double_field($test_case);
    my $minimal2 = native_api_get_object_field($test_case);
    
    if ((int)$x_byte1 == (int)(byte)1) {
      if ((int)$x_short1 == (int)(short)2) {
        if ($x_int1 == 3) {
          if ($x_long1 == 4L) {
            if ($x_float1 == 0.5f) {
              if ($x_double1 == 0.025) {
                if ($minimal1 == $minimal2) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
  }

  native sub sum : int ($num1 : int, $num2 : int);
  
  native sub add_int_array : int[] ($nums1 : int[], $nums2 : int[]);

  sub call_void_sub_exception : int () {
    eval {
      call_void_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_byte_sub_exception : int () {
    eval {
      call_byte_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_short_sub_exception : int () {
    eval {
      call_short_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_int_sub_exception : int () {
    eval {
      call_int_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_long_sub_exception : int () {
    eval {
      call_long_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_float_sub_exception : int () {
    eval {
      call_float_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }

  sub call_double_sub_exception : int () {
    eval {
      call_double_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }
  
  sub call_object_sub_exception : int () {
    eval {
      call_object_sub_exception_native();
    };
    
    if ($@) {
      return 1;
    }
    
    return 0;
  }
  
  native sub call_void_sub_exception_native : void ();
  native sub call_byte_sub_exception_native : byte ();
  native sub call_short_sub_exception_native : short ();
  native sub call_int_sub_exception_native : int ();
  native sub call_long_sub_exception_native : long ();
  native sub call_float_sub_exception_native : float ();
  native sub call_double_sub_exception_native : double ();
  native sub call_object_sub_exception_native : double ();
}