aardappel / lobster

The Lobster Programming Language
http://strlen.com/lobster
2.24k stars 121 forks source link

Assertion failure with debug lobster after updating to latest. #246

Closed MortimerSnerd closed 1 year ago

MortimerSnerd commented 1 year ago

Updated to commit 192e95e5c942087338da30f273b9930ae5ae6641

After updating, started to get JIT failures. Running with the debug version of lobster netted me this assertion:

Assertion failed: de.sf->subbytecodestart, file C:\src\lobster\dev\src\lobster\codegen.h, line 311

Seems to be happening with a virtual move_to method that's used in a small class hierarchy.

To reproduce, here is chopped down example. This is main.lobster:

import gphysics

let shape = c_capsule{line_seg3{xyz_0, xyz_0}, 1.0}
let new_pos = xyz_0
let face_info = [] :: surfinfo
let phys_obj = physics_object{-1}
shape.move_to(new_pos)
let contacts = [] 
let pos = new_pos
phys_obj.set_pos(pos)

And here is gphysics, that has the class hierarchy:

import vec

struct surfinfo:
   x: int

struct line_seg3:
   start: xyz_f
   extent: xyz_f

class collision_shape:
   def move_to(p: xyz_f):
      pass()

private let po_shape = [] :: collision_shape

struct physics_object:
   h: int

   def set_pos(p: xyz_f) -> physics_object:
      po_shape[h].move_to(p)
      return this

class c_capsule: collision_shape
   center_seg: line_seg3  
   radius: float

   def apply_overlap(ov: xyz_f):
      center_seg = line_seg3{center_seg.start + ov, center_seg.extent}

   def move_to(p: xyz_f):
      center_seg = line_seg3{p + xyz_z*radius, center_seg.extent}

   def set_height(h: float):
      let ext = normalize(center_seg.extent)
      center_seg = line_seg3{center_seg.start, ext*(max(h-2.0*radius, 0.0))}

class extruded_sphere: c_capsule

class csphere: collision_shape
   center: xyz_f 
   radius: float
   resolved_pushes = xyz_0

   def move_to(p: xyz_f):
      center = p + xyz_z*radius
      resolved_pushes = xyz_0

Let me know if you need anything else.

aardappel commented 1 year ago

Fixed here: https://github.com/aardappel/lobster/commit/128669227075a596dd463ddfc11fccca7d5b6bb6

The cause was that it didn't generate a vtable entry for extruded_sphere since the code never constructs one, so it then concludes it 0 vtable entry is ok, but then the backend hits the assert or generates a reference to a fun_0 that doesn't exist. So instead now this case is handled, and it put a ref to a function that just aborts in the vtable. This should make it more resilient against future such cases, but if there's ever a missing vtable entry for the wrong reasons we'll get that abort instead :)

MortimerSnerd commented 1 year ago

Interesting. In the code the reproduction was cut from, extruded_sphere is constructed. But the fix you committed does work, and I tested to make sure all collision_shape types were instantiated and called, and no aborts.

Thanks!

aardappel commented 1 year ago

Ah cool, so maybe the assert you got had a slightly different cause, but the fix appears to apply to both. Like I said this is more robust, and no idea why I didn't do it this way originally.