/**
 * Copyright (c) 2012-2013 André Bargull
 * Alle Rechte vorbehalten / All Rights Reserved.  Use is subject to license terms.
 *
 * <https://github.com/anba/es6draft>
 */
package com.github.anba.es6draft.runtime.internal;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * {@link Thread} subclass used for Generators and Generator Comprehensions
 */
public class GeneratorThread extends Thread {
    private final Thread parent;

    private GeneratorThread(Thread parent, Runnable target, String name) {
        super(target, name);
        this.parent = parent;
    }

    /**
     * Returns the calling thread which instantiated this thread
     */
    public Thread getParent() {
        return parent;
    }

    /**
     * Creates a new {@link ThreadFactory} to create {@link GeneratorThread} objects
     */
    public static ThreadFactory newGeneratorThreadFactory() {
        return new GeneratorThreadFactory();
    }

    private static final class GeneratorThreadFactory implements ThreadFactory {
        private static final AtomicInteger threads = new AtomicInteger(0);

        @Override
        public Thread newThread(Runnable r) {
            // save caller thread to be able to restore stacktraces
            Thread parent = Thread.currentThread();
            String name = "generator-thread-" + threads.incrementAndGet();
            Thread newThread = new GeneratorThread(parent, r, name);
            if (newThread.isDaemon()) {
                newThread.setDaemon(false);
            }
            if (newThread.getPriority() != Thread.NORM_PRIORITY) {
                newThread.setPriority(Thread.NORM_PRIORITY);
            }
            return newThread;
        }
    }
}

@@ -459,27 +459,114 @@
 ate 
-final Thread parent
+static final int MAX_STACK_DEPTH = 1000;%0A    private final Thread parent;%0A    private final int stackDepth
 ;%0A%0A 
@@ -606,16 +606,32 @@
  parent,
+ int stackDepth,
  Runnabl
@@ -706,32 +706,70 @@
 arent = parent;%0A
+        this.stackDepth = stackDepth;%0A
     %7D%0A%0A    /**%0A 
@@ -1454,24 +1454,75 @@
 ntThread();%0A
+            int depth = stackDepthOrThrow(parent);%0A
             
@@ -1642,16 +1642,23 @@
 (parent,
+ depth,
  r, name
@@ -1935,21 +1935,437 @@
 d;%0A        %7D
+%0A%0A        static int stackDepthOrThrow(Thread parent) %7B%0A            if (parent instanceof GeneratorThread) %7B%0A                int parentDepth = ((GeneratorThread) parent).stackDepth;%0A                if (parentDepth %3E= MAX_STACK_DEPTH) %7B%0A                    throw new StackOverflowError();%0A                %7D%0A                return parentDepth + 1;%0A            %7D else %7B%0A                return 1;%0A            %7D%0A        %7D
 %0A    %7D%0A%7D%0A

Add stack overflow detection to generator threads