kyleect / locks

A toy language branched from Lox to learn language implementation and tooling. Forked from loxcraft
https://kyleect.github.io/locks/#/docs
MIT License
0 stars 0 forks source link

Segfault running `res/benchmarks/method_call.locks` #155

Open kyleect opened 5 months ago

kyleect commented 5 months ago

Code

This is simplified code from the benchmark to make debugging easier.

class Toggle {
  let state;

  fn init(startState) {
    this.state = startState;
  }

  fn value() { return this.state; }

  fn activate() {
    this.state = !this.state;
    return this;
  }
}

class NthToggle extends Toggle {
  let countMax;
  let count;

  fn init(startState, maxCounter) {
    super.init(startState);
    this.countMax = maxCounter;
    this.count = 0;
  }

  fn activate() {
    this.count = this.count + 1;
    if (this.count >= this.countMax) {
      super.activate();
      this.count = 0;
    }

    return this;
  }
}

let start = clock();
let n = 1;
let val = true;
let toggle = Toggle(val);

for (let i = 0; i < n; i = i + 1) {
  val = toggle.activate().value();
}

println(toggle.value());

val = true;
let ntoggle = NthToggle(val, 3);

for (let i = 0; i < n; i = i + 1) {
  val = ntoggle.activate().value();
}

println(ntoggle.value());
println(clock() - start);

Trace

allocate string: init
allocate string: clock
allocate native: <native clock>
allocate string: len
allocate native: <native len>
allocate string: print
allocate native: <native print>
allocate string: println
allocate native: <native println>
allocate string: typeof
allocate native: <native typeof>
allocate string: 
allocate function: <script>
allocate string: Toggle
allocate string: state
allocate function: <fn init arity=1>
allocate string: value
allocate function: <fn value arity=0>
allocate string: activate
allocate function: <fn activate arity=0>
allocate string: NthToggle
allocate string: countMax
allocate string: count
allocate function: <fn init arity=2>
allocate function: <fn activate arity=0>
allocate string: start
allocate string: n
allocate string: val
allocate string: toggle
allocate string: ntoggle
allocate function: <script>
0000 OP_CLASS            0 == 'Toggle'

allocate class: <class Toggle>
     [ <class Toggle> ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ <class Toggle> ]
0006 OP_NIL

     [ <class Toggle> ][ nil ]
0007 OP_FIELD            1 == 'state'

     [ <class Toggle> ]
0009 OP_POP

0010 OP_GET_GLOBAL       0 == 'Toggle'

     [ <class Toggle> ]
0012 OP_CLOSURE          2 == '<fn init arity=1>'
| 0000 OP_GET_LOCAL        1
| 0002 OP_GET_LOCAL        0
| 0004 OP_SET_PROPERTY     0 == 'state'
| 0006 OP_POP
| 0007 OP_GET_LOCAL        0
| 0009 OP_RETURN

allocate function: <fn init arity=1>
     [ <class Toggle> ][ <fn init arity=1> ]
0014 OP_METHOD           3 == 'init'

     [ <class Toggle> ]
0016 OP_CLOSURE          4 == '<fn value arity=0>'
| 0000 OP_GET_LOCAL        0
| 0002 OP_GET_PROPERTY     0 == 'state'
| 0004 OP_RETURN

allocate function: <fn value arity=0>
     [ <class Toggle> ][ <fn value arity=0> ]
0018 OP_METHOD           5 == 'value'

     [ <class Toggle> ]
0020 OP_CLOSURE          6 == '<fn activate arity=0>'
| 0000 OP_GET_LOCAL        0
| 0002 OP_GET_PROPERTY     0 == 'state'
| 0004 OP_NOT
| 0005 OP_GET_LOCAL        0
| 0007 OP_SET_PROPERTY     0 == 'state'
| 0009 OP_POP
| 0010 OP_GET_LOCAL        0
| 0012 OP_RETURN

allocate function: <fn activate arity=0>
     [ <class Toggle> ][ <fn activate arity=0> ]
0022 OP_METHOD           7 == 'activate'

     [ <class Toggle> ]
0024 OP_POP

0025 OP_CLASS            8 == 'NthToggle'

allocate class: <class NthToggle>
     [ <class NthToggle> ]
0027 OP_DEFINE_GLOBAL    8 == 'NthToggle'

0029 OP_GET_GLOBAL       0 == 'Toggle'

     [ <class Toggle> ]
0031 OP_GET_GLOBAL       8 == 'NthToggle'

     [ <class Toggle> ][ <class NthToggle> ]
0033 OP_INHERIT

     [ <class Toggle> ]
0034 OP_GET_GLOBAL       8 == 'NthToggle'

     [ <class Toggle> ][ <class NthToggle> ]
0036 OP_NIL

     [ <class Toggle> ][ <class NthToggle> ][ nil ]
0037 OP_FIELD            9 == 'countMax'

     [ <class Toggle> ][ <class NthToggle> ]
0039 OP_NIL

     [ <class Toggle> ][ <class NthToggle> ][ nil ]
0040 OP_FIELD           10 == 'count'

     [ <class Toggle> ][ <class NthToggle> ]
0042 OP_POP

     [ <class Toggle> ]
0043 OP_GET_GLOBAL       8 == 'NthToggle'

     [ <class Toggle> ][ <class NthToggle> ]
0045 OP_CLOSURE         11 == '<fn init arity=2>'
0046 CAPTURE [local -> 0]
| 0000 OP_GET_LOCAL        0
| 0002 OP_GET_UPVALUE      0
| 0004 OP_GET_SUPER        0 == 'init'
| 0006 OP_GET_LOCAL        1
| 0008 OP_CALL             1
| 0010 OP_POP
| 0011 OP_GET_LOCAL        2
| 0013 OP_GET_LOCAL        0
| 0015 OP_SET_PROPERTY     1 == 'countMax'
| 0017 OP_POP
| 0018 OP_CONSTANT         2 == '0'
| 0020 OP_GET_LOCAL        0
| 0022 OP_SET_PROPERTY     3 == 'count'
| 0024 OP_POP
| 0025 OP_GET_LOCAL        0
| 0027 OP_RETURN

allocate upvalue: <upvalue>
allocate function: <fn init arity=2>
     [ <class Toggle> ][ <class NthToggle> ][ <fn init arity=2> ]
0049 OP_METHOD           3 == 'init'

     [ <class Toggle> ][ <class NthToggle> ]
0051 OP_CLOSURE         12 == '<fn activate arity=0>'
0052 CAPTURE [local -> 0]
| 0000 OP_GET_LOCAL        0
| 0002 OP_GET_PROPERTY     0 == 'count'
| 0004 OP_CONSTANT         1 == '1'
| 0006 OP_ADD
| 0007 OP_GET_LOCAL        0
| 0009 OP_SET_PROPERTY     0 == 'count'
| 0011 OP_POP
| 0012 OP_GET_LOCAL        0
| 0014 OP_GET_PROPERTY     0 == 'count'
| 0016 OP_GET_LOCAL        0
| 0018 OP_GET_PROPERTY     2 == 'countMax'
| 0020 OP_GREATER_EQUAL
| 0021 OP_JUMP_IF_FALSE   21 -> 44
| 0024 OP_POP
| 0025 OP_GET_LOCAL        0
| 0027 OP_GET_UPVALUE      0
| 0029 OP_GET_SUPER        3 == 'activate'
| 0031 OP_CALL             0
| 0033 OP_POP
| 0034 OP_CONSTANT         4 == '0'
| 0036 OP_GET_LOCAL        0
| 0038 OP_SET_PROPERTY     0 == 'count'
| 0040 OP_POP
| 0041 OP_JUMP            41 -> 45
| 0044 OP_POP
| 0045 OP_GET_LOCAL        0
| 0047 OP_RETURN

allocate function: <fn activate arity=0>
     [ <class Toggle> ][ <class NthToggle> ][ <fn activate arity=0> ]
0055 OP_METHOD           7 == 'activate'

     [ <class Toggle> ][ <class NthToggle> ]
0057 OP_POP

     [ <class Toggle> ]
0058 OP_CLOSE_UPVALUE

0059 OP_GET_GLOBAL      13 == 'clock'

     [ <native clock> ]
0061 OP_CALL             0

     [ 1704682448.7113574 ]
0063 OP_DEFINE_GLOBAL   14 == 'start'

0065 OP_CONSTANT        15 == '1'

     [ 1 ]
0067 OP_DEFINE_GLOBAL   16 == 'n'

0069 OP_TRUE

     [ true ]
0070 OP_DEFINE_GLOBAL   17 == 'val'

0072 OP_GET_GLOBAL       0 == 'Toggle'

     [ <class Toggle> ]
0074 OP_GET_GLOBAL      17 == 'val'

     [ <class Toggle> ][ true ]
0076 OP_CALL             1

allocate instance: <object Toggle>
     [ <object Toggle> ][ true ]

0000 OP_CLASS            0 == 'Toggle'

     [ <object Toggle> ][ true ][ true ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object Toggle> ][ true ][ true ][ <object Toggle> ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ <object Toggle> ][ true ][ true ]
0006 OP_NIL

     [ <object Toggle> ][ true ]
0007 OP_FIELD            1 == 'state'

     [ <object Toggle> ][ true ][ <object Toggle> ]
0009 OP_POP

     [ <object Toggle> ]
0078 OP_DEFINE_GLOBAL   18 == 'toggle'

0080 OP_CONSTANT        19 == '0'

     [ 0 ]
0082 OP_GET_LOCAL        0

     [ 0 ][ 0 ]
0084 OP_GET_GLOBAL      16 == 'n'

     [ 0 ][ 0 ][ 1 ]
0086 OP_LESS

     [ 0 ][ true ]
0087 OP_JUMP_IF_FALSE   87 -> 115

     [ 0 ][ true ]
0090 OP_POP

     [ 0 ]
0091 OP_GET_GLOBAL      18 == 'toggle'

     [ 0 ][ <object Toggle> ]
0093 OP_GET_PROPERTY     7 == 'activate'

allocate bound method: <bound method activate>
     [ 0 ][ <bound method activate> ]
0095 OP_CALL             0

     [ <object Toggle> ]
0000 OP_CLASS            0 == 'Toggle'

     [ <object Toggle> ][ <object Toggle> ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object Toggle> ][ true ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ <object Toggle> ][ false ]
0005 OP_CONSTANT         1 == 'state'

     [ <object Toggle> ][ false ][ <object Toggle> ]
0007 OP_FIELD            1 == 'state'

     [ <object Toggle> ][ false ]
0009 OP_POP

     [ <object Toggle> ]
0010 OP_GET_GLOBAL       0 == 'Toggle'

     [ <object Toggle> ][ <object Toggle> ]
0012 OP_CLOSURE          2 == '<fn init arity=1>'
| 0000 OP_GET_LOCAL        1
| 0002 OP_GET_LOCAL        0
| 0004 OP_SET_PROPERTY     0 == 'state'
| 0006 OP_POP
| 0007 OP_GET_LOCAL        0
| 0009 OP_RETURN

     [ 0 ][ <object Toggle> ]
0097 OP_GET_PROPERTY     5 == 'value'

allocate bound method: <bound method value>
     [ 0 ][ <bound method value> ]
0099 OP_CALL             0

     [ <object Toggle> ]
0000 OP_CLASS            0 == 'Toggle'

     [ <object Toggle> ][ <object Toggle> ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object Toggle> ][ false ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ 0 ][ false ]
0101 OP_SET_GLOBAL      17 == 'val'

     [ 0 ][ false ]
0103 OP_POP

     [ 0 ]
0104 OP_GET_LOCAL        0

     [ 0 ][ 0 ]
0106 OP_CONSTANT        15 == '1'

     [ 0 ][ 0 ][ 1 ]
0108 OP_ADD

     [ 0 ][ 1 ]
0109 OP_SET_LOCAL        0

     [ 1 ][ 1 ]
0111 OP_POP

     [ 1 ]
0112 OP_LOOP           112 -> 82

     [ 1 ]
0082 OP_GET_LOCAL        0

     [ 1 ][ 1 ]
0084 OP_GET_GLOBAL      16 == 'n'

     [ 1 ][ 1 ][ 1 ]
0086 OP_LESS

     [ 1 ][ false ]
0087 OP_JUMP_IF_FALSE   87 -> 115

     [ 1 ][ false ]
0115 OP_POP

     [ 1 ]
0116 OP_POP

0117 OP_GET_GLOBAL      20 == 'println'

     [ <native println> ]
0119 OP_GET_GLOBAL      18 == 'toggle'

     [ <native println> ][ <object Toggle> ]
0121 OP_GET_PROPERTY     5 == 'value'

allocate bound method: <bound method value>
     [ <native println> ][ <bound method value> ]
0123 OP_CALL             0

     [ <object Toggle> ]
0000 OP_CLASS            0 == 'Toggle'

     [ <object Toggle> ][ <object Toggle> ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object Toggle> ][ false ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ <native println> ][ false ]
0125 OP_CALL             1

false
     [ nil ]
0127 OP_POP

0128 OP_TRUE

     [ true ]
0129 OP_SET_GLOBAL      17 == 'val'

     [ true ]
0131 OP_POP

0132 OP_GET_GLOBAL       8 == 'NthToggle'

     [ <class NthToggle> ]
0134 OP_GET_GLOBAL      17 == 'val'

     [ <class NthToggle> ][ true ]
0136 OP_CONSTANT        21 == '3'

     [ <class NthToggle> ][ true ][ 3 ]
0138 OP_CALL             2

allocate instance: <object NthToggle>
     [ <object NthToggle> ][ true ][ 3 ]
0000 OP_CLASS            0 == 'Toggle'

     [ <object NthToggle> ][ true ][ 3 ][ <object NthToggle> ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object NthToggle> ][ true ][ 3 ][ <object NthToggle> ][ <class Toggle> ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

allocate bound method: <bound method init>
     [ <object NthToggle> ][ true ][ 3 ][ <bound method init> ]
0006 OP_NIL

     [ <object NthToggle> ][ true ][ 3 ][ <bound method init> ][ true ]
0008 OP_NIL

     [ <object NthToggle> ][ true ]
0000 OP_CLASS            0 == 'Toggle'

     [ <object NthToggle> ][ true ][ true ]
0002 OP_DEFINE_GLOBAL    0 == 'Toggle'

     [ <object NthToggle> ][ true ][ true ][ <object NthToggle> ]
0004 OP_GET_GLOBAL       0 == 'Toggle'

     [ <object NthToggle> ][ true ][ true ]
0006 OP_NIL

     [ <object NthToggle> ][ true ]
0007 OP_FIELD            1 == 'state'

     [ <object NthToggle> ][ true ][ <object NthToggle> ]
0009 OP_POP

     [ <object NthToggle> ][ true ][ 3 ][ <object NthToggle> ]
0010 OP_GET_GLOBAL       0 == 'Toggle'

     [ <object NthToggle> ][ true ][ 3 ]
thread 'main' panicked at src\vm\disassembler.rs:153:25:
index out of bounds: the len is 23 but the index is 34
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

I confirmed this works in the original implementation so it's a change that was made since then.