/*
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/

 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.

 * The Original Code is Rhino code, released
 * May 6, 1999.

 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
 * Rights Reserved.

 * Contributor(s): 

 * Alternatively, the contents of this file may be used under the
 * terms of the GNU Public License (the "GPL"), in which case the
 * provisions of the GPL are applicable instead of those above.
 * If you wish to allow use of your version of this file only
 * under the terms of the GPL and not to allow others to use your
 * version of this file under the NPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL.  If you do not delete
 * the provisions above, a recipient may use your version of this
 * file under either the NPL or the GPL.
 */
/* Header file */
#include "js-interpretedfunction.h"
#include "js-runtimeexception.h"
#include "js-exceptionhandler.h"
#include "js-interpreterdata.h"
#if 0
#include "ewb-sys.h"
#include "ewb-sys-if.h"
#endif

/* Procedures */
void JSInterpreterData::mark(JSContext * cx)
{
    JSGCHeap *gcHeap = &cx->runtime->gcHeap;

    if (gcHeap->isMarkObj(this))
        return;

    gcHeap->markObj(this);
    if (itsVariableTable != NULL) {
        itsVariableTable->mark(cx);
    }
    if (itsName != NULL) {
        gcHeap->markObj(itsName);
    }
    if (itsSource != NULL) {
        gcHeap->markObj(itsSource);
    }
    if (itsSourceFile != NULL) {
        gcHeap->markObj(itsSourceFile);
    }
    if (itsStringTable != NULL) {
/* itsStringTable is allocated from runtime memory to avoid gc fragmentation
        gcHeap->markObj(itsStringTable);
*/
        for (int i = 0; i < itsStringTableIndex; ++i) {
            if (itsStringTable[i] != NULL) {
                gcHeap->markObj(itsStringTable[i]);
            }
        }
    }
    if (itsNumberTable != NULL) {
        gcHeap->markObj(itsNumberTable);
    }
    if (itsNestedFunctions != NULL) {
        gcHeap->markObj(itsNestedFunctions);
        for (int i = 0; i < itsNestedFunctionsLength; ++i) {
            itsNestedFunctions[i]->mark(cx);
        }
    }
    if (itsRegExpLiterals != NULL) {
        gcHeap->markObj(itsRegExpLiterals);
        for (int i = 0; i < itsRegExpLiteralsLength; ++i) {
            JS_MarkVal(cx, itsRegExpLiterals[i]);
        }
    }
/* itsICode is allocated from runtime memory to avoid gc fragmentation
    if (itsICode != NULL) {
	gcHeap->markObj(itsICode);
    }
*/
}

/* itsICode is allocated from runtime memory to avoid gc fragmentation */
void JSInterpreterData::finalize(JSContext * cx)
{
    if (itsICode != NULL) {
        JS_DeleteRuntimeObj(cx->runtime, itsICode);
    }
    if (itsStringTable != NULL) {
        JS_DeleteRuntimeObj(cx->runtime, itsStringTable);
    }
}

JSInterpreterData::JSInterpreterData(JSContext * cx, int lastICodeTop, int lastStringTableIndex, int lastNumberTableIndex, jsBool_t useDynamicScope)
{
    itsVariableTable = NULL;
    itsName = NULL;
    itsSource = NULL;
    itsSourceLength = 0;
    itsSourceFile = NULL;
    itsNeedsActivation = FALSE;
    itsFromEvalCode = FALSE;
    itsFunctionType = 0;

    itsStringTable = NULL;
    itsStringTableIndex = 0;
    itsNumberTable = NULL;
    itsNumberTableIndex = 0;
    itsNestedFunctionsLength = 0;
    itsNestedFunctions = NULL;
    itsRegExpLiterals = NULL;
    itsRegExpLiteralsLength = 0;

    itsICode = NULL;
    itsICodeTop = 0;
#ifdef REUSE_LOCAL
    itsLocalTop = 0;
#endif
    itsMaxLocals = 0;
    itsMaxArgs = 0;
    itsMaxStack = 0;
    itsMaxTryDepth = 0;
    itsMaxEnums = 0;

    itsICodeTop = lastICodeTop == 0 ? INITIAL_MAX_ICODE_LENGTH : lastICodeTop * 2;
    itsICodeLength = itsICodeTop;
/* itsICode is allocated from runtime memory to avoid gc fragmentation
    itsICode = (int8_t *) JS_NewGCObj(cx, sizeof (*itsICode) * itsICodeTop);
*/
    itsICode = (int8_t *) JS_NewRuntimeObj(cx->runtime, sizeof(*itsICode) * itsICodeTop);

    itsStringTableLength = lastStringTableIndex == 0 ? INITIAL_STRINGTABLE_SIZE : lastStringTableIndex * 2;
/* itsStringTable is allocated from runtime memory to avoid gc fragmentation
    itsStringTable = (jsString_t *) JS_NewGCObj(cx, sizeof (*itsStringTable)
							* itsStringTableLength);
*/
    itsStringTable = (jsString_t *) JS_NewRuntimeObj(cx->runtime, sizeof(*itsStringTable)
            * itsStringTableLength);

    if (itsStringTable) {
        memset(itsStringTable, 0, sizeof(*itsStringTable) * itsStringTableLength);
    }

    itsNumberTableLength = lastNumberTableIndex == 0 ? INITIAL_NUMBERTABLE_SIZE : lastNumberTableIndex * 2;
    itsNumberTable = (double *)JS_NewGCObj(cx, sizeof(*itsNumberTable)
            * itsNumberTableLength);

    itsUseDynamicScope = useDynamicScope;
}
