fix cr/lfs and remove trailing whitespaces...
[supertux.git] / src / squirrel / squirrel / sqcompiler.cpp
index 40c8d49..a6bab09 100644 (file)
@@ -3,11 +3,12 @@
 */
 #include "sqpcheader.h"
 #include <stdarg.h>
+#include <setjmp.h>
 #include "sqopcodes.h"
 #include "sqstring.h"
 #include "sqfuncproto.h"
-#include "sqfuncstate.h"
 #include "sqcompiler.h"
+#include "sqfuncstate.h"
 #include "sqlexer.h"
 #include "sqvm.h"
 
@@ -26,15 +27,15 @@ struct ExpState
        bool _class_or_delete;
        bool _funcarg;
        bool _freevar;
-       int _deref;
+       SQInteger _deref;
 };
 
 typedef sqvector<ExpState> ExpStateVec;
 
 #define _exst (_expstates.top())
 
-#define BEGIN_BREAKBLE_BLOCK() int __nbreaks__=_fs->_unresolvedbreaks.size(); \
-                                                       int __ncontinues__=_fs->_unresolvedcontinues.size(); \
+#define BEGIN_BREAKBLE_BLOCK() SQInteger __nbreaks__=_fs->_unresolvedbreaks.size(); \
+                                                       SQInteger __ncontinues__=_fs->_unresolvedcontinues.size(); \
                                                        _fs->_breaktargets.push_back(0);_fs->_continuetargets.push_back(0);
 
 #define END_BREAKBLE_BLOCK(continue_target) {__nbreaks__=_fs->_unresolvedbreaks.size()-__nbreaks__; \
@@ -49,9 +50,14 @@ public:
        SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo)
        {
                _vm=v;
-               _lex.Init(_ss(v), rg, up);
+               _lex.Init(_ss(v), rg, up,ThrowError,this);
                _sourcename = SQString::Create(_ss(v), sourcename);
                _lineinfo = lineinfo;_raiseerror = raiseerror;
+               compilererror = NULL;
+       }
+       static void ThrowError(void *ud, const SQChar *s) {
+               SQCompiler *c = (SQCompiler *)ud;
+               c->Error(s);
        }
        void Error(const SQChar *s, ...)
        {
@@ -60,11 +66,12 @@ public:
                va_start(vl, s);
                scvsprintf(temp, s, vl);
                va_end(vl);
-               throw ParserException(temp);
+               compilererror = temp;
+               longjmp(_errorjmp,1);
        }
        void Lex(){     _token = _lex.Lex();}
        void PushExpState(){ _expstates.push_back(ExpState()); }
-       bool IsDerefToken(int tok)
+       bool IsDerefToken(SQInteger tok)
        {
                switch(tok){
                case _SC('='): case _SC('('): case TK_NEWSLOT:
@@ -78,51 +85,53 @@ public:
                _expstates.pop_back();
                return ret;
        }
-       SQObjectPtr Expect(int tok)
+       SQObject Expect(SQInteger tok)
        {
-               SQObjectPtr ret;
+
                if(_token != tok) {
                        if(_token == TK_CONSTRUCTOR && tok == TK_IDENTIFIER) {
                                //ret = SQString::Create(_ss(_vm),_SC("constructor"));
                                //do nothing
                        }
                        else {
+                               const SQChar *etypename;
                                if(tok > 255) {
                                        switch(tok)
                                        {
                                        case TK_IDENTIFIER:
-                                               ret = SQString::Create(_ss(_vm), _SC("IDENTIFIER"));
+                                               etypename = _SC("IDENTIFIER");
                                                break;
                                        case TK_STRING_LITERAL:
-                                               ret = SQString::Create(_ss(_vm), _SC("STRING_LITERAL"));
+                                               etypename = _SC("STRING_LITERAL");
                                                break;
                                        case TK_INTEGER:
-                                               ret = SQString::Create(_ss(_vm), _SC("INTEGER"));
+                                               etypename = _SC("INTEGER");
                                                break;
                                        case TK_FLOAT:
-                                               ret = SQString::Create(_ss(_vm), _SC("FLOAT"));
+                                               etypename = _SC("FLOAT");
                                                break;
                                        default:
-                                               ret = _lex.Tok2Str(tok);
+                                               etypename = _lex.Tok2Str(tok);
                                        }
-                                       Error(_SC("expected '%s'"), _stringval(ret));
+                                       Error(_SC("expected '%s'"), etypename);
                                }
                                Error(_SC("expected '%c'"), tok);
                        }
                }
+               SQObjectPtr ret;
                switch(tok)
                {
                case TK_IDENTIFIER:
-                       ret = SQString::Create(_ss(_vm), _lex._svalue);
+                       ret = _fs->CreateString(_lex._svalue);
                        break;
                case TK_STRING_LITERAL:
-                       ret = SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1);
+                       ret = _fs->CreateString(_lex._svalue,_lex._longstr.size()-1);
                        break;
                case TK_INTEGER:
-                       ret = _lex._nvalue;
+                       ret = SQObjectPtr(_lex._nvalue);
                        break;
                case TK_FLOAT:
-                       ret = _lex._fvalue;
+                       ret = SQObjectPtr(_lex._fvalue);
                        break;
                }
                Lex();
@@ -137,7 +146,7 @@ public:
                }
        }
        void MoveIfCurrentTargetIsLocal() {
-               int trg = _fs->TopTarget();
+               SQInteger trg = _fs->TopTarget();
                if(_fs->IsLocal(trg)) {
                        trg = _fs->PopTarget(); //no pops the target and move it
                        _fs->AddInstruction(_OP_MOVE, _fs->PushTarget(), trg);
@@ -145,16 +154,17 @@ public:
        }
        bool Compile(SQObjectPtr &o)
        {
-               SQ_TRY {
-                       _debugline = 1;
-                       _debugop = 0;
+               _debugline = 1;
+               _debugop = 0;
+
+               SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
+               funcstate._name = SQString::Create(_ss(_vm), _SC("main"));
+               _fs = &funcstate;
+               _fs->AddParameter(_fs->CreateString(_SC("this")));
+               _fs->_sourcename = _sourcename;
+               SQInteger stacksize = _fs->GetStackSize();
+               if(setjmp(_errorjmp) == 0) {
                        Lex();
-                       SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), NULL);
-                       _funcproto(funcstate._func)->_name = SQString::Create(_ss(_vm), _SC("main"));
-                       _fs = &funcstate;
-                       _fs->AddParameter(SQString::Create(_ss(_vm), _SC("this")));
-                       _funcproto(_fs->_func)->_sourcename = _sourcename;
-                       int stacksize = _fs->GetStackSize();
                        while(_token > 0){
                                Statement();
                                if(_lex._prevtoken != _SC('}')) OptionalSemicolon();
@@ -162,21 +172,18 @@ public:
                        CleanStack(stacksize);
                        _fs->AddLineInfos(_lex._currentline, _lineinfo, true);
                        _fs->AddInstruction(_OP_RETURN, 0xFF);
-                       _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;
                        _fs->SetStackSize(0);
-                       _fs->Finalize();
-                       o = _fs->_func;
+                       o =_fs->BuildProto();
 #ifdef _DEBUG_DUMP
-                       _fs->Dump();
+                       _fs->Dump(_funcproto(o));
 #endif
                }
-               SQ_CATCH(ParserException,ex){
-                       if(_raiseerror && _ss(_vm)->_compilererrorhandler){
-                               SQObjectPtr ret;
-                               _ss(_vm)->_compilererrorhandler(_vm, ex.desc, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
+               else {
+                       if(_raiseerror && _ss(_vm)->_compilererrorhandler) {
+                               _ss(_vm)->_compilererrorhandler(_vm, compilererror, type(_sourcename) == OT_STRING?_stringval(_sourcename):_SC("unknown"),
                                        _lex._currentline, _lex._currentcolumn);
                        }
-                       _vm->_lasterror = SQString::Create(_ss(_vm), ex.desc, -1);
+                       _vm->_lasterror = SQString::Create(_ss(_vm), compilererror, -1);
                        return false;
                }
                return true;
@@ -205,26 +212,26 @@ public:
                        SQOpcode op;
                        if(_token == TK_RETURN) {
                                op = _OP_RETURN;
-                               
+
                        }
                        else {
                                op = _OP_YIELD;
-                               _funcproto(_fs->_func)->_bgenerator = true;
+                               _fs->_bgenerator = true;
                        }
                        Lex();
                        if(!IsEndOfStatement()) {
-                               int retexp = _fs->GetCurrentPos()+1;
+                               SQInteger retexp = _fs->GetCurrentPos()+1;
                                CommaExpr();
                                if(op == _OP_RETURN && _fs->_traps > 0)
                                        _fs->AddInstruction(_OP_POPTRAP, _fs->_traps, 0);
                                _fs->_returnexp = retexp;
                                _fs->AddInstruction(op, 1, _fs->PopTarget());
                        }
-                       else{ 
+                       else{
                                if(op == _OP_RETURN && _fs->_traps > 0)
                                        _fs->AddInstruction(_OP_POPTRAP, _fs->_traps ,0);
                                _fs->_returnexp = -1;
-                               _fs->AddInstruction(op, 0xFF); 
+                               _fs->AddInstruction(op, 0xFF);
                        }
                        break;}
                case TK_BREAK:
@@ -252,7 +259,7 @@ public:
                        ClassStatement();
                        break;
                case _SC('{'):{
-                               int stacksize = _fs->GetStackSize();
+                               SQInteger stacksize = _fs->GetStackSize();
                                Lex();
                                Statements();
                                Expect(_SC('}'));
@@ -276,32 +283,33 @@ public:
        }
        void EmitDerefOp(SQOpcode op)
        {
-               int val = _fs->PopTarget();
-               int key = _fs->PopTarget();
-               int src = _fs->PopTarget();
+               SQInteger val = _fs->PopTarget();
+               SQInteger key = _fs->PopTarget();
+               SQInteger src = _fs->PopTarget();
         _fs->AddInstruction(op,_fs->PushTarget(),src,key,val);
        }
-       void Emit2ArgsOP(SQOpcode op, int p3 = 0)
+       void Emit2ArgsOP(SQOpcode op, SQInteger p3 = 0)
        {
-               int p2 = _fs->PopTarget(); //src in OP_GET
-               int p1 = _fs->PopTarget(); //key in OP_GET
+               SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+               SQInteger p1 = _fs->PopTarget(); //key in OP_GET
                _fs->AddInstruction(op,_fs->PushTarget(), p1, p2, p3);
        }
-       void EmitCompoundArith(int tok,bool deref)
+       void EmitCompoundArith(SQInteger tok,bool deref)
        {
-               int oper;
+               SQInteger oper;
                switch(tok){
                case TK_MINUSEQ: oper = '-'; break;
                case TK_PLUSEQ: oper = '+'; break;
                case TK_MULEQ: oper = '*'; break;
                case TK_DIVEQ: oper = '/'; break;
                case TK_MODEQ: oper = '%'; break;
-               default: oper = 0; assert(0); break;
+               default: oper = 0; //shut up compiler
+                       assert(0); break;
                };
                if(deref) {
-                       int val = _fs->PopTarget();
-                       int key = _fs->PopTarget();
-                       int src = _fs->PopTarget();
+                       SQInteger val = _fs->PopTarget();
+                       SQInteger key = _fs->PopTarget();
+                       SQInteger src = _fs->PopTarget();
                        //mixes dest obj and source val in the arg1(hack?)
                        _fs->AddInstruction(_OP_COMPARITH,_fs->PushTarget(),(src<<16)|val,key,oper);
                }
@@ -328,8 +336,8 @@ public:
                case TK_DIVEQ:
                case TK_MODEQ:
                {
-                               int op = _token;
-                               int ds = _exst._deref;
+                               SQInteger op = _token;
+                               SQInteger ds = _exst._deref;
                                bool freevar = _exst._freevar;
                                if(ds == DEREF_NO_DEREF) Error(_SC("can't assign expression"));
                                Lex(); Expression();
@@ -347,8 +355,8 @@ public:
                                        if(ds == DEREF_FIELD)
                                                EmitDerefOp(_OP_SET);
                                        else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
-                                               int p2 = _fs->PopTarget(); //src in OP_GET
-                                               int p1 = _fs->TopTarget(); //key in OP_GET
+                                               SQInteger p2 = _fs->PopTarget(); //src in OP_GET
+                                               SQInteger p1 = _fs->TopTarget(); //key in OP_GET
                                                _fs->AddInstruction(_OP_MOVE, p1, p2);
                                        }
                                        break;
@@ -365,17 +373,17 @@ public:
                case _SC('?'): {
                        Lex();
                        _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
-                       int jzpos = _fs->GetCurrentPos();
-                       int trg = _fs->PushTarget();
+                       SQInteger jzpos = _fs->GetCurrentPos();
+                       SQInteger trg = _fs->PushTarget();
                        Expression();
-                       int first_exp = _fs->PopTarget();
+                       SQInteger first_exp = _fs->PopTarget();
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
-                       int endfirstexp = _fs->GetCurrentPos();
+                       SQInteger endfirstexp = _fs->GetCurrentPos();
                        _fs->AddInstruction(_OP_JMP, 0, 0);
                        Expect(_SC(':'));
-                       int jmppos = _fs->GetCurrentPos();
+                       SQInteger jmppos = _fs->GetCurrentPos();
                        Expression();
-                       int second_exp = _fs->PopTarget();
+                       SQInteger second_exp = _fs->PopTarget();
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
                        _fs->SetIntructionParam(jmppos, 1, _fs->GetCurrentPos() - jmppos);
                        _fs->SetIntructionParam(jzpos, 1, endfirstexp - jzpos + 1);
@@ -385,24 +393,24 @@ public:
                }
                return PopExpState();
        }
-       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),int op3 = 0)
+       void BIN_EXP(SQOpcode op, void (SQCompiler::*f)(void),SQInteger op3 = 0)
        {
                Lex(); (this->*f)();
-               int op1 = _fs->PopTarget();int op2 = _fs->PopTarget();
+               SQInteger op1 = _fs->PopTarget();SQInteger op2 = _fs->PopTarget();
                _fs->AddInstruction(op, _fs->PushTarget(), op1, op2, op3);
        }
        void LogicalOrExp()
        {
                LogicalAndExp();
                for(;;) if(_token == TK_OR) {
-                       int first_exp = _fs->PopTarget();
-                       int trg = _fs->PushTarget();
+                       SQInteger first_exp = _fs->PopTarget();
+                       SQInteger trg = _fs->PushTarget();
                        _fs->AddInstruction(_OP_OR, trg, 0, first_exp, 0);
-                       int jpos = _fs->GetCurrentPos();
+                       SQInteger jpos = _fs->GetCurrentPos();
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
                        Lex(); LogicalOrExp();
                        _fs->SnoozeOpt();
-                       int second_exp = _fs->PopTarget();
+                       SQInteger second_exp = _fs->PopTarget();
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
                        _fs->SnoozeOpt();
                        _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
@@ -414,14 +422,14 @@ public:
                BitwiseOrExp();
                for(;;) switch(_token) {
                case TK_AND: {
-                       int first_exp = _fs->PopTarget();
-                       int trg = _fs->PushTarget();
+                       SQInteger first_exp = _fs->PopTarget();
+                       SQInteger trg = _fs->PushTarget();
                        _fs->AddInstruction(_OP_AND, trg, 0, first_exp, 0);
-                       int jpos = _fs->GetCurrentPos();
+                       SQInteger jpos = _fs->GetCurrentPos();
                        if(trg != first_exp) _fs->AddInstruction(_OP_MOVE, trg, first_exp);
                        Lex(); LogicalAndExp();
                        _fs->SnoozeOpt();
-                       int second_exp = _fs->PopTarget();
+                       SQInteger second_exp = _fs->PopTarget();
                        if(trg != second_exp) _fs->AddInstruction(_OP_MOVE, trg, second_exp);
                        _fs->SnoozeOpt();
                        _fs->SetIntructionParam(jpos, 1, (_fs->GetCurrentPos() - jpos));
@@ -464,7 +472,7 @@ public:
                case TK_GE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_GE); break;
                case TK_LE: BIN_EXP(_OP_CMP, &SQCompiler::ShiftExp,CMP_LE); break;
                case TK_NE: BIN_EXP(_OP_NE, &SQCompiler::ShiftExp); break;
-               default: return;        
+               default: return;
                }
        }
        void ShiftExp()
@@ -474,7 +482,7 @@ public:
                case TK_USHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_USHIFTR); break;
                case TK_SHIFTL: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTL); break;
                case TK_SHIFTR: BIN_EXP(_OP_BITW, &SQCompiler::PlusExp,BW_SHIFTR); break;
-               default: return;        
+               default: return;
                }
        }
        void PlusExp()
@@ -486,7 +494,7 @@ public:
                default: return;
                }
        }
-       
+
        void MultExp()
        {
                PrefixedExpr();
@@ -499,23 +507,21 @@ public:
        //if 'pos' != -1 the previous variable is a local variable
        void PrefixedExpr()
        {
-               int pos = Factor();
+               SQInteger pos = Factor();
                for(;;) {
                        switch(_token) {
                        case _SC('.'): {
                                pos = -1;
-                               SQObjectPtr idx;
-                               Lex(); 
+                               Lex();
                                if(_token == TK_PARENT) {
                                        Lex();
                                        if(!NeedGet())
                                                Error(_SC("parent cannot be set"));
-                                       int src = _fs->PopTarget();
+                                       SQInteger src = _fs->PopTarget();
                                        _fs->AddInstruction(_OP_GETPARENT, _fs->PushTarget(), src);
                                }
                                else {
-                                       idx = Expect(TK_IDENTIFIER); 
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(idx)));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
                                        if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                }
                                _exst._deref = DEREF_FIELD;
@@ -524,7 +530,7 @@ public:
                                break;
                        case _SC('['):
                                if(_lex._prevtoken == _SC('\n')) Error(_SC("cannot brake deref/or comma needed after [exp]=exp slot declaration"));
-                               Lex(); Expression(); Expect(_SC(']')); 
+                               Lex(); Expression(); Expect(_SC(']'));
                                pos = -1;
                                if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                _exst._deref = DEREF_FIELD;
@@ -532,26 +538,26 @@ public:
                                break;
                        case TK_MINUSMINUS:
                        case TK_PLUSPLUS:
-                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) { 
-                               int tok = _token; Lex();
+                       if(_exst._deref != DEREF_NO_DEREF && !IsEndOfStatement()) {
+                               SQInteger tok = _token; Lex();
                                if(pos < 0)
                                        Emit2ArgsOP(_OP_PINC,tok == TK_MINUSMINUS?-1:1);
                                else {//if _derefstate != DEREF_NO_DEREF && DEREF_FIELD so is the index of a local
-                                       int src = _fs->PopTarget();
+                                       SQInteger src = _fs->PopTarget();
                                        _fs->AddInstruction(_OP_PINCL, _fs->PushTarget(), src, 0, tok == TK_MINUSMINUS?-1:1);
                                }
-                               
+
                        }
                        return;
-                       break;  
-                       case _SC('('): 
+                       break;
+                       case _SC('('):
                                {
                                if(_exst._deref != DEREF_NO_DEREF) {
                                        if(pos<0) {
-                                               int key = _fs->PopTarget(); //key
-                                               int table = _fs->PopTarget(); //table etc...
-                                               int closure = _fs->PushTarget();
-                                               int ttarget = _fs->PushTarget();
+                                               SQInteger key = _fs->PopTarget(); //key
+                                               SQInteger table = _fs->PopTarget(); //table etc...
+                                               SQInteger closure = _fs->PushTarget();
+                                               SQInteger ttarget = _fs->PushTarget();
                                                _fs->AddInstruction(_OP_PREPCALL, closure, key, table, ttarget);
                                        }
                                        else{
@@ -569,14 +575,14 @@ public:
                        }
                }
        }
-       int Factor()
+       SQInteger Factor()
        {
                switch(_token)
                {
                case TK_STRING_LITERAL: {
-                               SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
-                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
-                               Lex(); 
+                               //SQObjectPtr id(SQString::Create(_ss(_vm), _lex._svalue,_lex._longstr.size()-1));
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(_fs->CreateString(_lex._svalue,_lex._longstr.size()-1)));
+                               Lex();
                        }
                        break;
                case TK_VARGC: Lex(); _fs->AddInstruction(_OP_VARGC, _fs->PushTarget()); break;
@@ -584,7 +590,7 @@ public:
                        Expect(_SC('['));
                        Expression();
                        Expect(_SC(']'));
-                       int src = _fs->PopTarget();
+                       SQInteger src = _fs->PopTarget();
                        _fs->AddInstruction(_OP_GETVARGV, _fs->PushTarget(), src);
                                           }
                        break;
@@ -592,23 +598,23 @@ public:
                case TK_CONSTRUCTOR:
                case TK_THIS:{
                        _exst._freevar = false;
-                       SQObjectPtr id;
+                       SQObject id;
                                switch(_token) {
-                                       case TK_IDENTIFIER: id = SQString::Create(_ss(_vm), _lex._svalue); break;
-                                       case TK_THIS: id = SQString::Create(_ss(_vm), _SC("this")); break;
-                                       case TK_CONSTRUCTOR: id = SQString::Create(_ss(_vm), _SC("constructor")); break;
+                                       case TK_IDENTIFIER: id = _fs->CreateString(_lex._svalue); break;
+                                       case TK_THIS: id = _fs->CreateString(_SC("this")); break;
+                                       case TK_CONSTRUCTOR: id = _fs->CreateString(_SC("constructor")); break;
                                }
-                               int pos = -1;
+                               SQInteger pos = -1;
                                Lex();
                                if((pos = _fs->GetLocalVariable(id)) == -1) {
                                        //checks if is a free variable
                                        if((pos = _fs->GetOuterVariable(id)) != -1) {
                                                _exst._deref = _fs->PushTarget();
-                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);        
+                                               _fs->AddInstruction(_OP_LOADFREEVAR, _exst._deref ,pos);
                                                _exst._freevar = true;
                                        } else {
                                                _fs->PushTarget(0);
-                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                                                if(NeedGet()) Emit2ArgsOP(_OP_GET);
                                                _exst._deref = DEREF_FIELD;
                                        }
@@ -627,15 +633,21 @@ public:
                        _token = _SC('.'); //hack
                        return -1;
                        break;
-               case TK_NULL: 
+               case TK_NULL:
                        _fs->AddInstruction(_OP_LOADNULLS, _fs->PushTarget(),1);
                        Lex();
                        break;
-               case TK_INTEGER: 
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
+               case TK_INTEGER: {
+                       if((_lex._nvalue & (~0x7FFFFFFF)) == 0) { //does it fit in 32 bits?
+                               _fs->AddInstruction(_OP_LOADINT, _fs->PushTarget(),_lex._nvalue);
+                       }
+                       else {
+                               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._nvalue));
+                       }
                        Lex();
+                                                }
                        break;
-               case TK_FLOAT: 
+               case TK_FLOAT:
                        _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetNumericConstant(_lex._fvalue));
                        Lex();
                        break;
@@ -645,13 +657,13 @@ public:
                        break;
                case _SC('['): {
                                _fs->AddInstruction(_OP_NEWARRAY, _fs->PushTarget());
-                               int apos = _fs->GetCurrentPos(),key = 0;
+                               SQInteger apos = _fs->GetCurrentPos(),key = 0;
                                Lex();
                                while(_token != _SC(']')) {
-                    Expression(); 
+                    Expression();
                                        if(_token == _SC(',')) Lex();
-                                       int val = _fs->PopTarget();
-                                       int array = _fs->TopTarget();
+                                       SQInteger val = _fs->PopTarget();
+                                       SQInteger array = _fs->TopTarget();
                                        _fs->AddInstruction(_OP_APPENDARRAY, array, val);
                                        key++;
                                }
@@ -672,7 +684,7 @@ public:
                case TK_TYPEOF : UnaryOP(_OP_TYPEOF); break;
                case TK_RESUME : UnaryOP(_OP_RESUME); break;
                case TK_CLONE : UnaryOP(_OP_CLONE); break;
-               case TK_MINUSMINUS : 
+               case TK_MINUSMINUS :
                case TK_PLUSPLUS :PrefixIncDec(_token); break;
                case TK_DELETE : DeleteExpr(); break;
                case TK_DELEGATE : DelegateExpr(); break;
@@ -685,7 +697,7 @@ public:
        void UnaryOP(SQOpcode op)
        {
                Lex(); PrefixedExpr();
-               int src = _fs->PopTarget();
+               SQInteger src = _fs->PopTarget();
                _fs->AddInstruction(op, _fs->PushTarget(), src);
        }
        bool NeedGet()
@@ -697,45 +709,52 @@ public:
                }
                return (!_exst._class_or_delete) || (_exst._class_or_delete && (_token == _SC('.') || _token == _SC('[')));
        }
-       
+
        void FunctionCallArgs()
        {
-               int nargs = 1;//this
+               SQInteger nargs = 1;//this
                 while(_token != _SC(')')) {
                         Expression(true);
                         MoveIfCurrentTargetIsLocal();
-                        nargs++; 
-                        if(_token == _SC(',')){ 
-                                Lex(); 
+                        nargs++;
+                        if(_token == _SC(',')){
+                                Lex();
                                 if(_token == ')') Error(_SC("expression expected, found ')'"));
                         }
                 }
                 Lex();
-                for(int i = 0; i < (nargs - 1); i++) _fs->PopTarget();
-                int stackbase = _fs->PopTarget();
-                int closure = _fs->PopTarget();
+                for(SQInteger i = 0; i < (nargs - 1); i++) _fs->PopTarget();
+                SQInteger stackbase = _fs->PopTarget();
+                SQInteger closure = _fs->PopTarget();
          _fs->AddInstruction(_OP_CALL, _fs->PushTarget(), closure, stackbase, nargs);
        }
-       void ParseTableOrClass(int separator,int terminator = '}')
+       void ParseTableOrClass(SQInteger separator,SQInteger terminator = '}')
        {
-               int tpos = _fs->GetCurrentPos(),nkeys = 0;
-               
+               SQInteger tpos = _fs->GetCurrentPos(),nkeys = 0;
+
                while(_token != terminator) {
                        bool hasattrs = false;
+                       bool isstatic = false;
                        //check if is an attribute
-                       if(separator == ';' && _token == TK_ATTR_OPEN) {
-                               _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
-                               ParseTableOrClass(',',TK_ATTR_CLOSE);
-                               hasattrs = true;
+                       if(separator == ';') {
+                               if(_token == TK_ATTR_OPEN) {
+                                       _fs->AddInstruction(_OP_NEWTABLE, _fs->PushTarget()); Lex();
+                                       ParseTableOrClass(',',TK_ATTR_CLOSE);
+                                       hasattrs = true;
+                               }
+                               if(_token == TK_STATIC) {
+                                       isstatic = true;
+                                       Lex();
+                               }
                        }
                        switch(_token) {
                                case TK_FUNCTION:
                                case TK_CONSTRUCTOR:{
-                                       int tk = _token;
+                                       SQInteger tk = _token;
                                        Lex();
-                                       SQObjectPtr id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : SQString::Create(_ss(_vm),_SC("constructor"));
+                                       SQObject id = tk == TK_FUNCTION ? Expect(TK_IDENTIFIER) : _fs->CreateString(_SC("constructor"));
                                        Expect(_SC('('));
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                                        CreateFunction(id);
                                        _fs->AddInstruction(_OP_CLOSURE, _fs->PushTarget(), _fs->_functions.size() - 1, 0);
                                                                  }
@@ -745,19 +764,20 @@ public:
                                        Expect(_SC('=')); Expression();
                                        break;
                                default :
-                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(Expect(TK_IDENTIFIER))));
+                                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(Expect(TK_IDENTIFIER)));
                                        Expect(_SC('=')); Expression();
                        }
 
                        if(_token == separator) Lex();//optional comma/semicolon
                        nkeys++;
-                       int val = _fs->PopTarget();
-                       int key = _fs->PopTarget();
-                       int attrs = hasattrs ? _fs->PopTarget():-1;
+                       SQInteger val = _fs->PopTarget();
+                       SQInteger key = _fs->PopTarget();
+                       SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
                        assert(hasattrs && attrs == key-1 || !hasattrs);
-                       int table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
-                       _fs->AddInstruction(hasattrs?_OP_NEWSLOTA:_OP_NEWSLOT, _fs->PushTarget(), table, key, val);
-                       _fs->PopTarget();
+                       unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
+                       SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE
+                       _fs->AddInstruction(_OP_NEWSLOTA, flags, table, key, val);
+                       //_fs->PopTarget();
                }
                if(separator == _SC(',')) //hack recognizes a table from the separator
                        _fs->SetIntructionParam(tpos, 1, nkeys);
@@ -765,13 +785,13 @@ public:
        }
        void LocalDeclStatement()
        {
-               SQObjectPtr varname;
+               SQObject varname;
                do {
                        Lex(); varname = Expect(TK_IDENTIFIER);
                        if(_token == _SC('=')) {
                                Lex(); Expression();
-                               int src = _fs->PopTarget();
-                               int dest = _fs->PushTarget();
+                               SQInteger src = _fs->PopTarget();
+                               SQInteger dest = _fs->PushTarget();
                                if(dest != src) _fs->AddInstruction(_OP_MOVE, dest, src);
                        }
                        else{
@@ -779,24 +799,24 @@ public:
                        }
                        _fs->PopTarget();
                        _fs->PushLocalVariable(varname);
-               
+
                } while(_token == _SC(','));
        }
        void IfStatement()
        {
-               int jmppos;
+               SQInteger jmppos;
                bool haselse = false;
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
                _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
-               int jnepos = _fs->GetCurrentPos();
-               int stacksize = _fs->GetStackSize();
-               
+               SQInteger jnepos = _fs->GetCurrentPos();
+               SQInteger stacksize = _fs->GetStackSize();
+
                Statement();
                //
                if(_token != _SC('}') && _token != TK_ELSE) OptionalSemicolon();
-               
+
                CleanStack(stacksize);
-               int endifblock = _fs->GetCurrentPos();
+               SQInteger endifblock = _fs->GetCurrentPos();
                if(_token == TK_ELSE){
                        haselse = true;
                        stacksize = _fs->GetStackSize();
@@ -811,34 +831,34 @@ public:
        }
        void WhileStatement()
        {
-               int jzpos, jmppos;
-               int stacksize = _fs->GetStackSize();
+               SQInteger jzpos, jmppos;
+               SQInteger stacksize = _fs->GetStackSize();
                jmppos = _fs->GetCurrentPos();
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
-               
+
                BEGIN_BREAKBLE_BLOCK();
                _fs->AddInstruction(_OP_JZ, _fs->PopTarget());
                jzpos = _fs->GetCurrentPos();
                stacksize = _fs->GetStackSize();
-               
+
                Statement();
-               
+
                CleanStack(stacksize);
                _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1);
                _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
-               
+
                END_BREAKBLE_BLOCK(jmppos);
        }
        void DoWhileStatement()
        {
                Lex();
-               int jzpos = _fs->GetCurrentPos();
-               int stacksize = _fs->GetStackSize();
+               SQInteger jzpos = _fs->GetCurrentPos();
+               SQInteger stacksize = _fs->GetStackSize();
                BEGIN_BREAKBLE_BLOCK()
                Statement();
                CleanStack(stacksize);
                Expect(TK_WHILE);
-               int continuetrg = _fs->GetCurrentPos();
+               SQInteger continuetrg = _fs->GetCurrentPos();
                Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
                _fs->AddInstruction(_OP_JNZ, _fs->PopTarget(), jzpos - _fs->GetCurrentPos() - 1);
                END_BREAKBLE_BLOCK(continuetrg);
@@ -846,7 +866,7 @@ public:
        void ForStatement()
        {
                Lex();
-               int stacksize = _fs->GetStackSize();
+               SQInteger stacksize = _fs->GetStackSize();
                Expect(_SC('('));
                if(_token == TK_LOCAL) LocalDeclStatement();
                else if(_token != _SC(';')){
@@ -855,69 +875,69 @@ public:
                }
                Expect(_SC(';'));
                _fs->SnoozeOpt();
-               int jmppos = _fs->GetCurrentPos();
-               int jzpos = -1;
+               SQInteger jmppos = _fs->GetCurrentPos();
+               SQInteger jzpos = -1;
                if(_token != _SC(';')) { CommaExpr(); _fs->AddInstruction(_OP_JZ, _fs->PopTarget()); jzpos = _fs->GetCurrentPos(); }
                Expect(_SC(';'));
                _fs->SnoozeOpt();
-               int expstart = _fs->GetCurrentPos() + 1;
+               SQInteger expstart = _fs->GetCurrentPos() + 1;
                if(_token != _SC(')')) {
                        CommaExpr();
                        _fs->PopTarget();
                }
                Expect(_SC(')'));
                _fs->SnoozeOpt();
-               int expend = _fs->GetCurrentPos();
-               int expsize = (expend - expstart) + 1;
+               SQInteger expend = _fs->GetCurrentPos();
+               SQInteger expsize = (expend - expstart) + 1;
                SQInstructionVec exp;
                if(expsize > 0) {
-                       for(int i = 0; i < expsize; i++)
+                       for(SQInteger i = 0; i < expsize; i++)
                                exp.push_back(_fs->GetInstruction(expstart + i));
                        _fs->PopInstructions(expsize);
                }
                BEGIN_BREAKBLE_BLOCK()
                Statement();
-               int continuetrg = _fs->GetCurrentPos();
+               SQInteger continuetrg = _fs->GetCurrentPos();
                if(expsize > 0) {
-                       for(int i = 0; i < expsize; i++)
+                       for(SQInteger i = 0; i < expsize; i++)
                                _fs->AddInstruction(exp[i]);
                }
                _fs->AddInstruction(_OP_JMP, 0, jmppos - _fs->GetCurrentPos() - 1, 0);
                if(jzpos>  0) _fs->SetIntructionParam(jzpos, 1, _fs->GetCurrentPos() - jzpos);
                CleanStack(stacksize);
-               
+
                END_BREAKBLE_BLOCK(continuetrg);
        }
        void ForEachStatement()
        {
-               SQObjectPtr idxname, valname;
+               SQObject idxname, valname;
                Lex(); Expect(_SC('(')); valname = Expect(TK_IDENTIFIER);
                if(_token == _SC(',')) {
                        idxname = valname;
                        Lex(); valname = Expect(TK_IDENTIFIER);
                }
                else{
-                       idxname = SQString::Create(_ss(_vm), _SC("@INDEX@"));
+                       idxname = _fs->CreateString(_SC("@INDEX@"));
                }
                Expect(TK_IN);
-               
+
                //save the stack size
-               int stacksize = _fs->GetStackSize();
+               SQInteger stacksize = _fs->GetStackSize();
                //put the table in the stack(evaluate the table expression)
                Expression(); Expect(_SC(')'));
-               int container = _fs->TopTarget();
+               SQInteger container = _fs->TopTarget();
                //push the index local var
-               int indexpos = _fs->PushLocalVariable(idxname);
+               SQInteger indexpos = _fs->PushLocalVariable(idxname);
                _fs->AddInstruction(_OP_LOADNULLS, indexpos,1);
                //push the value local var
-               int valuepos = _fs->PushLocalVariable(valname);
+               SQInteger valuepos = _fs->PushLocalVariable(valname);
                _fs->AddInstruction(_OP_LOADNULLS, valuepos,1);
                //push reference index
-               int itrpos = _fs->PushLocalVariable(SQString::Create(_ss(_vm), _SC("@ITERATOR@"))); //use invalid id to make it inaccessible
+               SQInteger itrpos = _fs->PushLocalVariable(_fs->CreateString(_SC("@ITERATOR@"))); //use invalid id to make it inaccessible
                _fs->AddInstruction(_OP_LOADNULLS, itrpos,1);
-               int jmppos = _fs->GetCurrentPos();
+               SQInteger jmppos = _fs->GetCurrentPos();
                _fs->AddInstruction(_OP_FOREACH, container, 0, indexpos);
-               int foreachpos = _fs->GetCurrentPos();
+               SQInteger foreachpos = _fs->GetCurrentPos();
                //generate the statement code
                BEGIN_BREAKBLE_BLOCK()
                Statement();
@@ -931,13 +951,14 @@ public:
        {
                Lex(); Expect(_SC('(')); CommaExpr(); Expect(_SC(')'));
                Expect(_SC('{'));
-               int expr = _fs->TopTarget();
+               SQInteger expr = _fs->TopTarget();
                bool bfirst = true;
-               int tonextcondjmp = -1;
-               int skipcondjmp = -1;
-               int __nbreaks__ = _fs->_unresolvedbreaks.size();
+               SQInteger tonextcondjmp = -1;
+               SQInteger skipcondjmp = -1;
+               SQInteger __nbreaks__ = _fs->_unresolvedbreaks.size();
                _fs->_breaktargets.push_back(0);
                while(_token == TK_CASE) {
+                       //_fs->AddLineInfos(_lex._currentline, _lineinfo); think about this one
                        if(!bfirst) {
                                _fs->AddInstruction(_OP_JMP, 0, 0);
                                skipcondjmp = _fs->GetCurrentPos();
@@ -945,7 +966,7 @@ public:
                        }
                        //condition
                        Lex(); Expression(); Expect(_SC(':'));
-                       int trg = _fs->PopTarget();
+                       SQInteger trg = _fs->PopTarget();
                        _fs->AddInstruction(_OP_EQ, trg, trg, expr);
                        _fs->AddInstruction(_OP_JZ, trg, 0);
                        //end condition
@@ -953,7 +974,7 @@ public:
                                _fs->SetIntructionParam(skipcondjmp, 1, (_fs->GetCurrentPos() - skipcondjmp));
                        }
                        tonextcondjmp = _fs->GetCurrentPos();
-                       int stacksize = _fs->GetStackSize();
+                       SQInteger stacksize = _fs->GetStackSize();
                        Statements();
                        _fs->SetStackSize(stacksize);
                        bfirst = false;
@@ -961,8 +982,9 @@ public:
                if(tonextcondjmp != -1)
                        _fs->SetIntructionParam(tonextcondjmp, 1, _fs->GetCurrentPos() - tonextcondjmp);
                if(_token == TK_DEFAULT) {
+               //      _fs->AddLineInfos(_lex._currentline, _lineinfo);
                        Lex(); Expect(_SC(':'));
-                       int stacksize = _fs->GetStackSize();
+                       SQInteger stacksize = _fs->GetStackSize();
                        Statements();
                        _fs->SetStackSize(stacksize);
                }
@@ -971,20 +993,20 @@ public:
                __nbreaks__ = _fs->_unresolvedbreaks.size() - __nbreaks__;
                if(__nbreaks__ > 0)ResolveBreaks(_fs, __nbreaks__);
                _fs->_breaktargets.pop_back();
-               
+
        }
        void FunctionStatement()
        {
-               SQObjectPtr id;
+               SQObject id;
                Lex(); id = Expect(TK_IDENTIFIER);
                _fs->PushTarget(0);
-               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+               _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
-               
+
                while(_token == TK_DOUBLE_COLON) {
                        Lex();
                        id = Expect(TK_IDENTIFIER);
-                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetStringConstant(_stringval(id)));
+                       _fs->AddInstruction(_OP_LOAD, _fs->PushTarget(), _fs->GetConstant(id));
                        if(_token == TK_DOUBLE_COLON) Emit2ArgsOP(_OP_GET);
                }
                Expect(_SC('('));
@@ -1011,30 +1033,30 @@ public:
        }
        void TryCatchStatement()
        {
-               SQObjectPtr exid;
+               SQObject exid;
                Lex();
                _fs->AddInstruction(_OP_PUSHTRAP,0,0);
                _fs->_traps++;
                if(_fs->_breaktargets.size()) _fs->_breaktargets.top()++;
                if(_fs->_continuetargets.size()) _fs->_continuetargets.top()++;
-               int trappos = _fs->GetCurrentPos();
+               SQInteger trappos = _fs->GetCurrentPos();
                Statement();
                _fs->_traps--;
                _fs->AddInstruction(_OP_POPTRAP, 1, 0);
                if(_fs->_breaktargets.size()) _fs->_breaktargets.top()--;
                if(_fs->_continuetargets.size()) _fs->_continuetargets.top()--;
                _fs->AddInstruction(_OP_JMP, 0, 0);
-               int jmppos = _fs->GetCurrentPos();
+               SQInteger jmppos = _fs->GetCurrentPos();
                _fs->SetIntructionParam(trappos, 1, (_fs->GetCurrentPos() - trappos));
                Expect(TK_CATCH); Expect(_SC('(')); exid = Expect(TK_IDENTIFIER); Expect(_SC(')'));
-               int stacksize = _fs->GetStackSize();
-               int ex_target = _fs->PushLocalVariable(exid);
+               SQInteger stacksize = _fs->GetStackSize();
+               SQInteger ex_target = _fs->PushLocalVariable(exid);
                _fs->SetIntructionParam(trappos, 0, ex_target);
                Statement();
                _fs->SetIntructionParams(jmppos, 0, (_fs->GetCurrentPos() - jmppos), 0);
                CleanStack(stacksize);
        }
-       void FunctionExp(int ftype)
+       void FunctionExp(SQInteger ftype)
        {
                Lex(); Expect(_SC('('));
                CreateFunction(_null_);
@@ -1042,8 +1064,8 @@ public:
        }
        void ClassExp()
        {
-               int base = -1;
-               int attrs = -1;
+               SQInteger base = -1;
+               SQInteger attrs = -1;
                if(_token == TK_EXTENDS) {
                        Lex(); Expression();
                        base = _fs->TopTarget();
@@ -1065,7 +1087,7 @@ public:
                Lex(); CommaExpr();
                Expect(_SC(':'));
                CommaExpr();
-               int table = _fs->PopTarget(), delegate = _fs->PopTarget();
+               SQInteger table = _fs->PopTarget(), delegate = _fs->PopTarget();
                _fs->AddInstruction(_OP_DELEGATE, _fs->PushTarget(), table, delegate);
        }
        void DeleteExpr()
@@ -1080,7 +1102,7 @@ public:
                if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_DELETE);
                else Error(_SC("cannot delete a local"));
        }
-       void PrefixIncDec(int token)
+       void PrefixIncDec(SQInteger token)
        {
                ExpState es;
                Lex(); PushExpState();
@@ -1090,27 +1112,28 @@ public:
                es = PopExpState();
                if(es._deref == DEREF_FIELD) Emit2ArgsOP(_OP_INC,token == TK_MINUSMINUS?-1:1);
                else {
-                       int src = _fs->PopTarget();
+                       SQInteger src = _fs->PopTarget();
                        _fs->AddInstruction(_OP_INCL, _fs->PushTarget(), src, 0, token == TK_MINUSMINUS?-1:1);
                }
        }
-       void CreateFunction(SQObjectPtr name)
+       void CreateFunction(SQObject &name)
        {
-               SQFuncState funcstate(_ss(_vm), SQFunctionProto::Create(), _fs);
-               _funcproto(funcstate._func)->_name = name;
-               SQObjectPtr paramname;
-               funcstate.AddParameter(SQString::Create(_ss(_vm), _SC("this")));
-               _funcproto(funcstate._func)->_sourcename = _sourcename;
+
+               SQFuncState *funcstate = _fs->PushChildState(_ss(_vm));
+               funcstate->_name = name;
+               SQObject paramname;
+               funcstate->AddParameter(_fs->CreateString(_SC("this")));
+               funcstate->_sourcename = _sourcename;
                while(_token!=_SC(')')) {
                        if(_token == TK_VARPARAMS) {
-                               funcstate._varparams = true;
+                               funcstate->_varparams = true;
                                Lex();
                                if(_token != _SC(')')) Error(_SC("expected ')'"));
                                break;
                        }
                        else {
                                paramname = Expect(TK_IDENTIFIER);
-                               funcstate.AddParameter(paramname);
+                               funcstate->AddParameter(paramname);
                                if(_token == _SC(',')) Lex();
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
                        }
@@ -1122,46 +1145,47 @@ public:
                        while(_token != _SC(')')) {
                                paramname = Expect(TK_IDENTIFIER);
                                //outers are treated as implicit local variables
-                               funcstate.AddOuterValue(paramname);
+                               funcstate->AddOuterValue(paramname);
                                if(_token == _SC(',')) Lex();
                                else if(_token != _SC(')')) Error(_SC("expected ')' or ','"));
                        }
                        Lex();
                }
-               
+
                SQFuncState *currchunk = _fs;
-               _fs = &funcstate;
+               _fs = funcstate;
                Statement();
-               funcstate.AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
-        funcstate.AddInstruction(_OP_RETURN, -1);
-               funcstate.SetStackSize(0);
-               _funcproto(_fs->_func)->_stacksize = _fs->_stacksize;
-               funcstate.Finalize();
+               funcstate->AddLineInfos(_lex._prevtoken == _SC('\n')?_lex._lasttokenline:_lex._currentline, _lineinfo, true);
+        funcstate->AddInstruction(_OP_RETURN, -1);
+               funcstate->SetStackSize(0);
+               //_fs->->_stacksize = _fs->_stacksize;
+               SQFunctionProto *func = funcstate->BuildProto();
 #ifdef _DEBUG_DUMP
-               funcstate.Dump();
+               funcstate->Dump(func);
 #endif
                _fs = currchunk;
-               _fs->_functions.push_back(funcstate._func);
+               _fs->_functions.push_back(func);
+               _fs->PopChildState();
        }
-       void CleanStack(int stacksize)
+       void CleanStack(SQInteger stacksize)
        {
                if(_fs->GetStackSize() != stacksize)
                        _fs->SetStackSize(stacksize);
        }
-       void ResolveBreaks(SQFuncState *funcstate, int ntoresolve)
+       void ResolveBreaks(SQFuncState *funcstate, SQInteger ntoresolve)
        {
                while(ntoresolve > 0) {
-                       int pos = funcstate->_unresolvedbreaks.back();
+                       SQInteger pos = funcstate->_unresolvedbreaks.back();
                        funcstate->_unresolvedbreaks.pop_back();
                        //set the jmp instruction
                        funcstate->SetIntructionParams(pos, 0, funcstate->GetCurrentPos() - pos, 0);
                        ntoresolve--;
                }
        }
-       void ResolveContinues(SQFuncState *funcstate, int ntoresolve, int targetpos)
+       void ResolveContinues(SQFuncState *funcstate, SQInteger ntoresolve, SQInteger targetpos)
        {
                while(ntoresolve > 0) {
-                       int pos = funcstate->_unresolvedcontinues.back();
+                       SQInteger pos = funcstate->_unresolvedcontinues.back();
                        funcstate->_unresolvedcontinues.pop_back();
                        //set the jmp instruction
                        funcstate->SetIntructionParams(pos, 0, targetpos - pos, 0);
@@ -1169,15 +1193,17 @@ public:
                }
        }
 private:
-       int _token;
+       SQInteger _token;
        SQFuncState *_fs;
        SQObjectPtr _sourcename;
        SQLexer _lex;
        bool _lineinfo;
        bool _raiseerror;
-       int _debugline;
-       int _debugop;
+       SQInteger _debugline;
+       SQInteger _debugop;
        ExpStateVec _expstates;
+       SQChar *compilererror;
+       jmp_buf _errorjmp;
        SQVM *_vm;
 };