diff --git a/package-lock.json b/package-lock.json
index 204117ba77..ef2483d612 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -429,8 +429,7 @@
     "arrify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
-      "dev": true
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
     },
     "asn1.js": {
       "version": "4.10.1",
@@ -2791,8 +2790,7 @@
     "make-error": {
       "version": "1.3.6",
       "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
-      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
-      "dev": true
+      "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
     },
     "mamacro": {
       "version": "0.0.3",
@@ -2906,8 +2904,7 @@
     "minimist": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
-      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
-      "dev": true
+      "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
     },
     "mississippi": {
       "version": "3.0.0",
@@ -2952,7 +2949,6 @@
       "version": "0.5.1",
       "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
       "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-      "dev": true,
       "requires": {
         "minimist": "0.0.8"
       },
@@ -2960,8 +2956,7 @@
         "minimist": {
           "version": "0.0.8",
           "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
         }
       }
     },
@@ -4200,7 +4195,6 @@
       "version": "6.2.0",
       "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-6.2.0.tgz",
       "integrity": "sha512-ZNT+OEGfUNVMGkpIaDJJ44Zq3Yr0bkU/ugN1PHbU+/01Z7UV1fsELRiTx1KuQNvQ1A3pGh3y25iYF6jXgxV21A==",
-      "dev": true,
       "requires": {
         "arrify": "^1.0.0",
         "buffer-from": "^1.1.0",
@@ -4215,8 +4209,7 @@
         "diff": {
           "version": "3.5.0",
           "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
-          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
-          "dev": true
+          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
         }
       }
     },
@@ -4750,8 +4743,7 @@
     "yn": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
-      "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
-      "dev": true
+      "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo="
     }
   }
 }
diff --git a/tests/compiler/class-overloading.optimized.wat b/tests/compiler/class-overloading.optimized.wat
index d1ecdc7148..bda4edba98 100644
--- a/tests/compiler/class-overloading.optimized.wat
+++ b/tests/compiler/class-overloading.optimized.wat
@@ -1,6 +1,6 @@
 (module
- (type $i32_=>_i32 (func (param i32) (result i32)))
  (type $none_=>_none (func))
+ (type $i32_=>_i32 (func (param i32) (result i32)))
  (type $i32_i32_i32_i32_=>_none (func (param i32 i32 i32 i32)))
  (import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
  (memory $0 1)
@@ -9,6 +9,7 @@
  (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
  (global $~lib/rt/stub/offset (mut i32) (i32.const 0))
  (global $class-overloading/foo (mut i32) (i32.const 0))
+ (global $class-overloading/afoo (mut i32) (i32.const 0))
  (export "memory" (memory $0))
  (start $~start)
  (func $~lib/rt/stub/__alloc (; 1 ;) (param $0 i32) (result i32)
@@ -87,14 +88,29 @@
   end
   local.get $0
   i32.eqz
-  if (result i32)
+  if
    i32.const 5
    call $~lib/rt/stub/__alloc
-  else
-   local.get $0
+   local.set $0
   end
+  local.get $0
+  i32.eqz
+  if
+   i32.const 6
+   call $~lib/rt/stub/__alloc
+   local.set $0
+  end
+  local.get $0
+ )
+ (func $class-overloading/Foo#a<i32> (; 3 ;)
+  i32.const 0
+  i32.const 1040
+  i32.const 9
+  i32.const 5
+  call $~lib/builtins/abort
+  unreachable
  )
- (func $~start (; 3 ;)
+ (func $start:class-overloading (; 4 ;)
   (local $0 i32)
   i32.const 1088
   global.set $~lib/rt/stub/startOffset
@@ -132,29 +148,76 @@
      global.set $class-overloading/itWorks
      br $__inlined_func$class-overloading/Foo#a<i32>|virtual
     end
-    i32.const 0
-    i32.const 1040
-    i32.const 17
-    i32.const 5
-    call $~lib/builtins/abort
-    unreachable
+    call $class-overloading/Baz#a<i32>
+    br $__inlined_func$class-overloading/Foo#a<i32>|virtual
    end
+   call $class-overloading/Foo#a<i32>
+  end
+  global.get $class-overloading/itWorks
+  i32.eqz
+  if
    i32.const 0
    i32.const 1040
-   i32.const 5
-   i32.const 5
+   i32.const 28
+   i32.const 1
    call $~lib/builtins/abort
    unreachable
   end
+  i32.const 0
+  call $class-overloading/Bar#constructor
+  global.set $class-overloading/afoo
+  block $__inlined_func$class-overloading/AbstractFoo#a<i32>|virtual
+   block $self0
+    block $id31
+     block $id4
+      global.get $class-overloading/afoo
+      i32.const 8
+      i32.sub
+      i32.load
+      local.tee $0
+      i32.const 5
+      i32.ne
+      if
+       block $tablify|0
+        local.get $0
+        i32.const 3
+        i32.sub
+        br_table $id31 $id4 $tablify|0 $self0 $tablify|0
+       end
+       unreachable
+      end
+      call $class-overloading/Foo#a<i32>
+      br $__inlined_func$class-overloading/AbstractFoo#a<i32>|virtual
+     end
+     i32.const 1
+     global.set $class-overloading/itWorks
+     br $__inlined_func$class-overloading/AbstractFoo#a<i32>|virtual
+    end
+    call $class-overloading/Baz#a<i32>
+    br $__inlined_func$class-overloading/AbstractFoo#a<i32>|virtual
+   end
+   unreachable
+  end
   global.get $class-overloading/itWorks
   i32.eqz
   if
    i32.const 0
    i32.const 1040
-   i32.const 24
+   i32.const 32
    i32.const 1
    call $~lib/builtins/abort
    unreachable
   end
  )
+ (func $~start (; 5 ;)
+  call $start:class-overloading
+ )
+ (func $class-overloading/Baz#a<i32> (; 6 ;)
+  i32.const 0
+  i32.const 1040
+  i32.const 21
+  i32.const 5
+  call $~lib/builtins/abort
+  unreachable
+ )
 )
diff --git a/tests/compiler/class-overloading.ts b/tests/compiler/class-overloading.ts
index 4db7811745..f8b2a83e63 100644
--- a/tests/compiler/class-overloading.ts
+++ b/tests/compiler/class-overloading.ts
@@ -1,6 +1,10 @@
 var itWorks = false;
 
-class Foo {
+abstract class AbstractFoo {
+  abstract a<T>(a: T): void;
+}
+
+class Foo extends AbstractFoo{
   a<T>(a: T): void { // called
     assert(false);
   }
@@ -22,3 +26,7 @@ new Baz();
 var foo: Foo = new Bar();
 foo.a<i32>(1);
 assert(itWorks);
+
+const afoo: AbstractFoo = new Bar();
+afoo.a<i32>(1);
+assert(itWorks);
diff --git a/tests/compiler/class-overloading.untouched.wat b/tests/compiler/class-overloading.untouched.wat
index 8d54dcb4cc..acd77d320e 100644
--- a/tests/compiler/class-overloading.untouched.wat
+++ b/tests/compiler/class-overloading.untouched.wat
@@ -13,6 +13,7 @@
  (global $~lib/rt/stub/startOffset (mut i32) (i32.const 0))
  (global $~lib/rt/stub/offset (mut i32) (i32.const 0))
  (global $class-overloading/foo (mut i32) (i32.const 0))
+ (global $class-overloading/afoo (mut i32) (i32.const 0))
  (global $~lib/heap/__heap_base i32 (i32.const 72))
  (export "memory" (memory $0))
  (start $~start)
@@ -126,7 +127,19 @@
  (func $~lib/rt/stub/__retain (; 3 ;) (param $0 i32) (result i32)
   local.get $0
  )
- (func $class-overloading/Foo#constructor (; 4 ;) (param $0 i32) (result i32)
+ (func $class-overloading/AbstractFoo#constructor (; 4 ;) (param $0 i32) (result i32)
+  local.get $0
+  i32.eqz
+  if
+   i32.const 0
+   i32.const 6
+   call $~lib/rt/stub/__alloc
+   call $~lib/rt/stub/__retain
+   local.set $0
+  end
+  local.get $0
+ )
+ (func $class-overloading/Foo#constructor (; 5 ;) (param $0 i32) (result i32)
   local.get $0
   i32.eqz
   if
@@ -137,8 +150,11 @@
    local.set $0
   end
   local.get $0
+  call $class-overloading/AbstractFoo#constructor
+  local.set $0
+  local.get $0
  )
- (func $class-overloading/Bar#constructor (; 5 ;) (param $0 i32) (result i32)
+ (func $class-overloading/Bar#constructor (; 6 ;) (param $0 i32) (result i32)
   local.get $0
   i32.eqz
   if
@@ -153,7 +169,7 @@
   local.set $0
   local.get $0
  )
- (func $class-overloading/Baz#constructor (; 6 ;) (param $0 i32) (result i32)
+ (func $class-overloading/Baz#constructor (; 7 ;) (param $0 i32) (result i32)
   local.get $0
   i32.eqz
   if
@@ -168,22 +184,25 @@
   local.set $0
   local.get $0
  )
- (func $~lib/rt/stub/__release (; 7 ;) (param $0 i32)
+ (func $~lib/rt/stub/__release (; 8 ;) (param $0 i32)
   nop
  )
- (func $class-overloading/Foo#a<i32> (; 8 ;) (param $0 i32) (param $1 i32)
+ (func $class-overloading/Foo#a<i32> (; 9 ;) (param $0 i32) (param $1 i32)
   i32.const 0
   i32.eqz
   if
    i32.const 0
    i32.const 32
-   i32.const 5
+   i32.const 9
    i32.const 5
    call $~lib/builtins/abort
    unreachable
   end
  )
- (func $start:class-overloading (; 9 ;)
+ (func $class-overloading/AbstractFoo#a<i32> (; 10 ;) (param $0 i32) (param $1 i32)
+  unreachable
+ )
+ (func $start:class-overloading (; 11 ;)
   global.get $~lib/heap/__heap_base
   i32.const 15
   i32.add
@@ -208,32 +227,48 @@
   if
    i32.const 0
    i32.const 32
-   i32.const 24
+   i32.const 28
+   i32.const 1
+   call $~lib/builtins/abort
+   unreachable
+  end
+  i32.const 0
+  call $class-overloading/Bar#constructor
+  global.set $class-overloading/afoo
+  global.get $class-overloading/afoo
+  i32.const 1
+  call $class-overloading/AbstractFoo#a<i32>|virtual
+  global.get $class-overloading/itWorks
+  i32.eqz
+  if
+   i32.const 0
+   i32.const 32
+   i32.const 32
    i32.const 1
    call $~lib/builtins/abort
    unreachable
   end
  )
- (func $~start (; 10 ;)
+ (func $~start (; 12 ;)
   call $start:class-overloading
  )
- (func $class-overloading/Bar#a<i32> (; 11 ;) (param $0 i32) (param $1 i32)
+ (func $class-overloading/Bar#a<i32> (; 13 ;) (param $0 i32) (param $1 i32)
   i32.const 1
   global.set $class-overloading/itWorks
  )
- (func $class-overloading/Baz#a<i32> (; 12 ;) (param $0 i32) (param $1 i32)
+ (func $class-overloading/Baz#a<i32> (; 14 ;) (param $0 i32) (param $1 i32)
   i32.const 0
   i32.eqz
   if
    i32.const 0
    i32.const 32
-   i32.const 17
+   i32.const 21
    i32.const 5
    call $~lib/builtins/abort
    unreachable
   end
  )
- (func $class-overloading/Foo#a<i32>|virtual (; 13 ;) (param $0 i32) (param $1 i32)
+ (func $class-overloading/Foo#a<i32>|virtual (; 15 ;) (param $0 i32) (param $1 i32)
   (local $2 i32)
   block $self
    block $id3
@@ -271,4 +306,52 @@
   local.get $1
   call $class-overloading/Foo#a<i32>
  )
+ (func $class-overloading/AbstractFoo#a<i32>|virtual (; 16 ;) (param $0 i32) (param $1 i32)
+  (local $2 i32)
+  block $self
+   block $id3
+    block $id4
+     block $id5
+      local.get $0
+      i32.const 8
+      i32.sub
+      i32.load
+      local.set $2
+      local.get $2
+      i32.const 5
+      i32.eq
+      br_if $id5
+      local.get $2
+      i32.const 4
+      i32.eq
+      br_if $id4
+      local.get $2
+      i32.const 3
+      i32.eq
+      br_if $id3
+      local.get $2
+      i32.const 6
+      i32.eq
+      br_if $self
+      unreachable
+     end
+     local.get $0
+     local.get $1
+     call $class-overloading/Foo#a<i32>
+     return
+    end
+    local.get $0
+    local.get $1
+    call $class-overloading/Bar#a<i32>
+    return
+   end
+   local.get $0
+   local.get $1
+   call $class-overloading/Baz#a<i32>
+   return
+  end
+  local.get $0
+  local.get $1
+  call $class-overloading/AbstractFoo#a<i32>
+ )
 )