sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Detect cyclic initialization

Open kasperl opened this issue 10 years ago • 1 comments

We fail to detect cyclic initialization of static fields so instead we just keep on recursing thus overflowing the stack. This causes a couple of tests to crash because of issue 70.

One reasonable way of fixing this is to let the LoadStaticInit bytecode overwrite the function in the initializer object with a function that throws a CyclicInitializationError just before we call the original initializer function the first time.

Maybe we should give all initializer objects two functions pointers and then overwrite the first one with the cycle-detected-function before calling. This allows the cycle-detected-function to contain the static field index necessary for setting the field to null before throwing an error containing the correct static field name.

  OPCODE_BEGIN(LoadStaticInit);
    int index = ReadInt32(1);
    Object* value = process()->statics()->get(index);
    if (value->IsInitializer()) {
      Initializer* initializer = Initializer::cast(value);
      Function* target = initializer->function();
      initializer->set_function(initializer->cycle_detected_function());  // <-----
      PushReturnAddress(kLoadStaticInitLength);
      Goto(target->bytecode_address_for(0));
      if (!StackOverflowCheck(0)) return Interpreter::kInterrupt;
    } else {
      Push(value);
      Advance(kLoadStaticInitLength);
    }
  OPCODE_END();

kasperl avatar Jul 10 '15 11:07 kasperl

There's a mention of this missing feature in a TODO here:

https://github.com/dart-lang/fletch/blob/master/pkg/fletchc/lib/src/lazy_field_initializer_codegen.dart#L40

but I think that might be the wrong place to fix this.

kasperl avatar Jul 10 '15 11:07 kasperl