AvmCore.h

Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is [Open Source Virtual Machine.].
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Adobe System Incorporated.
00018  * Portions created by the Initial Developer are Copyright (C) 2004-2006
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *   Adobe AS3 Team
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #ifndef __avmplus_AvmCore__
00039 #define __avmplus_AvmCore__
00040 
00041 namespace avmplus
00042 {
00043 
00044 #define DECLARE_NATIVE_SCRIPTS() static const NativeScriptInfo scriptEntries[];
00045 
00046 #define BEGIN_NATIVE_SCRIPTS(_Class) /*static*/ const  NativeScriptInfo _Class::scriptEntries[] = {
00047 
00048 #define NATIVE_SCRIPT(script_id, _Script) { (NativeScriptInfo::Handler)_Script::createGlobalObject, _Script::natives, script_id, sizeof(_Script) },
00049 
00050 #define END_NATIVE_SCRIPTS() { NULL, NULL, -1, 0 } };
00051 
00052 #define DECLARE_NATIVE_CLASSES() static const NativeClassInfo classEntries[];
00053 
00054 #define BEGIN_NATIVE_CLASSES(_Class) /*static*/ const NativeClassInfo _Class::classEntries[] = {
00055 
00056 #define NATIVE_CLASS(class_id, _Class, _Instance) { (NativeClassInfo::Handler)_Class::createClassClosure, _Class::natives, avmplus::NativeID::class_id, sizeof(_Class), sizeof(_Instance) },
00057 
00058 #define END_NATIVE_CLASSES() { NULL, NULL, -1, 0, 0 } };
00059 
00060 #define OBJECT_TYPE     (core->traits.object_itraits)
00061 #define CLASS_TYPE      (core->traits.class_itraits)
00062 #define FUNCTION_TYPE   (core->traits.function_itraits)
00063 #define ARRAY_TYPE      (core->traits.array_itraits)
00064 #define STRING_TYPE     (core->traits.string_itraits)
00065 #define NUMBER_TYPE     (core->traits.number_itraits)
00066 #define INT_TYPE        (core->traits.int_itraits)
00067 #define UINT_TYPE       (core->traits.uint_itraits)
00068 #define BOOLEAN_TYPE    (core->traits.boolean_itraits)
00069 #define VOID_TYPE       (core->traits.void_itraits)
00070 #define NULL_TYPE       (core->traits.null_itraits)
00071 #define NAMESPACE_TYPE  (core->traits.namespace_itraits)
00072 #define VECTORINT_TYPE  (core->traits.vectorint_itraits)
00073 #define VECTORUINT_TYPE (core->traits.vectoruint_itraits)
00074 #define VECTORDOUBLE_TYPE       (core->traits.vectordouble_itraits)
00075 #define VECTOROBJ_TYPE  (core->traits.vectorobj_itraits)
00076 
00077 const int kBufferPadding = 16;
00078 
00079     struct Config
00080     {
00081         #ifdef AVMPLUS_VERBOSE
00082 
00088         bool verbose;
00089         bool verbose_addrs;
00090         #endif /* AVMPLUS_VERBOSE */
00091 
00103         bool turbo;
00104 
00105         #ifdef AVMPLUS_MIR
00106         bool dceopt;
00111         #ifdef AVMPLUS_VERBOSE
00112         bool bbgraph;
00113         #endif //AVMPLUS_VERBOSE
00114         #endif
00115 
00116         #if defined AVMPLUS_MIR || defined FEATURE_NANOJIT
00117 
00125         bool jit;
00126         bool cseopt;
00127 
00128         #if defined (AVMPLUS_IA32) || defined(AVMPLUS_AMD64)
00129         bool sse2;
00130         #endif
00131 
00132         #endif // AVMPLUS_MIR || FEATURE_NANOJIT
00133 
00139         bool interrupts;
00140 
00141 #ifdef AVMPLUS_VERIFYALL
00142         bool verifyall;
00143 #endif
00144 
00145 #ifdef FEATURE_NANOJIT
00146         bool show_stats;
00147         bool tree_opt;
00148         bool verbose_live;
00149         bool verbose_exits;
00150 #endif
00151     };
00152 
00157     class AvmCore : public MMgc::GCRoot
00158     {
00159     public:
00171         PrintWriter console;
00172 
00173 #ifdef VTUNE
00174         iJIT_IsProfilingActiveFlags VTuneStatus;
00175 
00176         iJIT_IsProfilingActiveFlags CheckVTuneStatus() 
00177         {
00178             iJIT_IsProfilingActiveFlags profiler = iJIT_IsProfilingActive();    
00179             return profiler;
00180         }
00181 #endif // VTUNE
00182 
00186         MMgc::GC * const gc;
00187 
00188         #ifdef DEBUGGER
00189 
00193         Debugger *debugger;
00194         Profiler *profiler;
00195         #endif
00196 
00197         void branchCheck(MethodEnv *env, bool interruptable, int go)
00198         {
00199             if(go < 0)
00200             {
00201 #ifdef DEBUGGER
00202                 sampleCheck();
00203 #endif
00204                 if (interruptable && interrupted)
00205                         interrupt(env);
00206             }
00207         }
00208 
00209         #ifdef AVMPLUS_MIR
00210         // MIR intermediate buffer pool
00211         List<GrowableBuffer*> mirBuffers; // mir buffer pool
00212         GrowableBuffer* requestNewMirBuffer();   // create a new buffer
00213         GrowableBuffer* requestMirBuffer();      // get next buffer in list or a create a new one
00214         void releaseMirBuffer(GrowableBuffer* buffer);
00215         //GCSpinLock mirBufferLock;
00216 
00217         #ifdef AVMPLUS_VERBOSE
00218         MMgc::GCHashtable* codegenMethodNames;
00219         #endif /* AVMPLUS_VERBOSE */
00220         #endif /* MIR */
00221 
00222         #if defined AVMPLUS_MIR || defined FEATURE_NANOJIT
00223         void initMultinameLate(Multiname& name, Atom index);
00224         #endif
00225 
00232         void setConsoleStream(OutputStream *stream);
00233 
00237         virtual void presweep();
00238         virtual void postsweep();
00239         
00240         Config config;
00241         
00242         #ifdef FEATURE_NANOJIT // accessors
00243             bool quiet_opt() { return false; } 
00244             bool use_sse2() { return config.sse2; }
00245             #ifdef AVMPLUS_VERBOSE
00246                 bool verbose() { return config.verbose; }
00247                 bool verbose_exits() { return config.verbose_exits; }
00248                 bool verbose_live() { return config.verbose_live; }
00249             #endif
00250         #endif
00251 
00252         inline void SetMIREnabled(bool isEnabled)
00253         {
00254             config.turbo = isEnabled;
00255         }
00256 
00257         inline bool IsMIREnabled() const
00258         {
00259             return config.turbo;
00260         }
00261 
00267         uintptr minstack;
00268 
00274         virtual void setStackBase() {}
00275 
00277         DRC(Stringp) booleanStrings[2];
00278 
00280         BuiltinTraits traits;
00281 
00283         PoolObject* builtinPool;
00284 
00286         Domain* builtinDomain;
00287         
00289         Namespace *const*dxnsAddr;
00290 
00296         int interrupted;
00297         
00302         DRC(Namespace*) publicNamespace;
00303         VTable* namespaceVTable;
00304 
00305         #ifdef FEATURE_JNI
00306         Java* java;     /* java vm control */
00307         #endif
00308 
00325         Atom handleActionPool(PoolObject* pool,
00326                                    DomainEnv* domainEnv,
00327                                    Toplevel* &toplevel,
00328                                    CodeContext *codeContext);
00329 
00330         ScriptEnv* prepareActionPool(PoolObject* pool,
00331                                      DomainEnv* domainEnv,
00332                                      Toplevel*& toplevel,
00333                                      CodeContext *codeContext);
00334         
00335         void exportDefs(Traits* traits, ScriptEnv* scriptEnv);
00336 
00353         PoolObject* parseActionBlock(ScriptBuffer code,
00354                                      int start,
00355                                      Toplevel* toplevel,
00356                                      Domain* domain,
00357                                      AbstractFunction *nativeMethods[],
00358                                      NativeClassInfop nativeClasses[],
00359                                      NativeScriptInfop nativeScripts[],
00360                                      List<Stringp>* include_versions = NULL);
00361         
00378         Atom handleActionBlock(ScriptBuffer code,
00379                                     int start,
00380                                     DomainEnv* domainEnv,
00381                                     Toplevel* &toplevel,
00382                                     AbstractFunction *nativeMethods[],
00383                                     NativeClassInfop nativeClasses[],
00384                                     NativeScriptInfop nativeScripts[],
00385                                     CodeContext *codeContext);
00386 
00387                 
00392         void initNativeTables(NativeClassInfop classEntries,
00393                              NativeScriptInfop scriptEntries,
00394                              AbstractFunction *nativeMethods[],
00395                              NativeClassInfop nativeClasses[],
00396                              NativeScriptInfop nativeScripts[]);
00397 
00402         Traits* makeParameterizedITraits(Stringp name, Namespace* ns, Traits* t );
00403         Traits* makeParameterizedCTraits(Stringp name, Namespace* ns, Traits* t );
00404 
00405 
00407         Atom equals(Atom lhs, Atom rhs);
00408         
00415         Atom compare(Atom lhs, Atom rhs);
00416 
00418         Atom stricteq(Atom lhs, Atom rhs);
00419 
00425         static bool isObject(Atom atom)
00426         {
00427             return (atom&7) == kObjectType && !isNull(atom);
00428         }
00429 
00430         static bool isPointer(Atom atom)
00431         {
00432             return (atom&7) < kSpecialType || (atom&7) == kDoubleType;
00433         }
00434 
00435         static bool isTraits(Atom type)
00436         {
00437             return type != 0 && (type&7) == 0;
00438         }
00439 
00440         static bool isNamespace(Atom atom)
00441         {
00442             return (atom&7) == kNamespaceType && !isNull(atom);
00443         }
00444 
00445         static bool isMethodBinding(Binding b)
00446         {
00447             return (b&7) == BIND_METHOD;
00448         }
00449 
00450         static bool isAccessorBinding(Binding b)
00451         {
00452             return (b&7) >= BIND_GET;
00453         }
00454 
00455         static bool hasSetterBinding(Binding b)
00456         {
00457             return (b&6) == BIND_SET;
00458         }
00459 
00460         static bool hasGetterBinding(Binding b)
00461         {
00462             return (b&5) == BIND_GET;
00463         }
00464 
00465         static int bindingToGetterId(Binding b)
00466         {
00467             AvmAssert(hasGetterBinding(b));
00468             return urshift(b,3);
00469         }
00470 
00471         static int bindingToSetterId(Binding b)
00472         {
00473             AvmAssert(hasSetterBinding(b));
00474             return 1+urshift(b,3);
00475         }
00476 
00477         static int bindingToMethodId(Binding b)
00478         {
00479             AvmAssert(isMethodBinding(b));
00480             return urshift(b,3);
00481         }
00482 
00483         static int bindingToSlotId(Binding b)
00484         {
00485             AvmAssert(isSlotBinding(b));
00486             return urshift(b,3);
00487         }
00488 
00490         static int isSlotBinding(Binding b)
00491         {
00492             AvmAssert((BIND_CONST&6)==BIND_VAR);
00493             return (b&6)==BIND_VAR;
00494         }
00495 
00497         static int isVarBinding(Binding b)
00498         {
00499             return (b&7)==BIND_VAR;
00500         }
00502         static int isConstBinding(Binding b)
00503         {
00504             return (b&7)==BIND_CONST;
00505         }
00506         
00508         bool isFunction(Atom atom)
00509         {
00510             return istype(atom, traits.function_itraits);
00511         }
00512 
00514         static bool isDouble(Atom atom)
00515         {
00516             return (atom&7) == kDoubleType;
00517         }
00518 
00520         static bool isInteger(Atom atom)
00521         {
00522             return (atom&7) == kIntegerType;
00523         }
00524 
00526         static bool isNumber(Atom atom)
00527         {
00528             // accept kIntegerType(6) or kDoubleType(7)
00529             return (atom&6) == kIntegerType;
00530         }
00531 
00533         static bool isBoolean(Atom atom)
00534         {
00535             return (atom&7) == kBooleanType;
00536         }
00537 
00539         static bool isNull(Atom atom)
00540         {
00541             return ISNULL(atom);
00542         }
00543 
00545         static bool isUndefined(Atom atom)
00546         {
00547             return (atom == undefinedAtom);
00548         }
00549 
00550         static bool isNullOrUndefined(Atom atom)
00551         {
00552             return ((uintptr)atom) <= (uintptr)kSpecialType;
00553         }
00554 
00555 #ifdef AVMPLUS_VERBOSE
00556 
00557         void formatOpcode(PrintWriter& out, const byte *pc, AbcOpcode opcode, ptrdiff_t off, PoolObject* pool);
00558         static void formatMultiname(PrintWriter& out, uint32 index, PoolObject* pool);
00559 #endif
00560 
00566         Hashtable *resources;
00567 
00576 
00577         DRC(Stringp) kconstructor;
00578         DRC(Stringp) kEmptyString;
00579         DRC(Stringp) ktrue;
00580         DRC(Stringp) kfalse;
00581         DRC(Stringp) kundefined;
00582         DRC(Stringp) knull;
00583         DRC(Stringp) ktoString;
00584         DRC(Stringp) ktoLocaleString;
00585         DRC(Stringp) kvalueOf;
00586         DRC(Stringp) klength;
00587         DRC(Stringp) kobject;
00588         DRC(Stringp) kfunction;
00589         DRC(Stringp) kxml;
00590         DRC(Stringp) kboolean;
00591         DRC(Stringp) knumber;
00592         DRC(Stringp) kstring;
00593         DRC(Stringp) kuri;
00594         DRC(Stringp) kprefix;
00595         DRC(Stringp) kglobal;
00596         DRC(Stringp) kcallee;
00597         DRC(Stringp) kNeedsDxns;
00598         DRC(Stringp) kAsterisk;
00599         DRC(Stringp) kVersion;
00600         DRC(Stringp) kVector;
00601 #ifdef AVMPLUS_VERBOSE
00602         DRC(Stringp) knewline;
00603         DRC(Stringp) krightbracket;
00604         DRC(Stringp) kleftbracket;
00605         DRC(Stringp) kcolon;
00606         DRC(Stringp) ktabat;
00607         DRC(Stringp) kparens;
00608 #endif
00609 #if defined AVMPLUS_VERBOSE || defined FEATURE_SAMPLER
00610         DRC(Stringp) kanonymousFunc;
00611 #endif
00612         Atom kNaN;
00613 
00614         DRC(Stringp) cachedChars[128];
00618         AvmCore(MMgc::GC *gc);
00619 
00621         ~AvmCore();
00622 
00627         void initBuiltinPool();
00628         
00633         Toplevel* initTopLevel();       
00634 
00635         virtual size_t getToplevelSize() const;
00636         virtual Toplevel* createToplevel(VTable *vtable);
00637         
00638     public:
00644         uint32 toUInt32(Atom atom) const
00645         {
00646             return (uint32)integer(atom);
00647         }
00648 
00654         double toInteger(Atom atom) const
00655         {
00656             if ((atom & 7) == kIntegerType) {
00657                 return (double) (atom>>3);
00658             } else {
00659                 return MathUtils::toInt(number(atom));
00660             }
00661         }
00662 
00669 #ifdef AVMPLUS_64BIT
00670         int64   integer64(Atom atom)            { return (int64)integer(atom); }
00671         static  int64 integer64_i(Atom atom)    { return (int64)integer_i(atom); }
00672         static  int64 integer64_d(double d)     { return (int64)integer_d_sse2(d); }
00673         static  int64 integer64_d_sse2(double d){ return (int64)integer_d_sse2(d); }
00674 #endif
00675         int integer(Atom atom) const;
00676 
00677         // convert atom to integer when we know it is already a legal signed-32 bit int value
00678         static int integer_i(Atom a)
00679         {
00680             if ((a&7) == kIntegerType)
00681                 return int(a>>3);
00682             else
00683                 // TODO since we know value is legal int, use faster d->i
00684                 return MathUtils::real2int(atomToDouble(a));
00685         }
00686 
00687         // convert atom to integer when we know it is already a legal unsigned-32 bit int value
00688         static uint32 integer_u(Atom a)
00689         {
00690             if ((a&7) == kIntegerType)
00691             {
00692                 return uint32(a>>3);
00693             }
00694             else
00695             {
00696                 // TODO figure out real2int for unsigned
00697                 return (uint32) atomToDouble(a);
00698             }
00699         }
00700 
00701 #ifdef AVMPLUS_AMD64
00702         static int integer_d(double d) {
00703             return integer_d_sse2(d);
00704         }
00705         Atom doubleToAtom(double n) {
00706             return doubleToAtom_sse2(n);
00707         }
00708 #else
00709         static int integer_d(double d);
00710         Atom doubleToAtom(double n);
00711 #endif
00712 
00713 #if defined (AVMPLUS_IA32) || defined(AVMPLUS_AMD64)
00714         static int integer_d_sse2(double d);
00715         Atom doubleToAtom_sse2(double n);
00716 #endif
00717 
00718     private:
00719         static int doubleToInt32(double d);
00720 
00721     public:
00722         static double number_d(Atom a)
00723         {
00724             AvmAssert(isNumber(a));
00725 
00726             if ((a&7) == kIntegerType)
00727                 return (int)(a>>3);
00728             else
00729                 return atomToDouble(a);
00730         }
00731 
00736         Atom intAtom(Atom atom)
00737         {
00738             return intToAtom(integer(atom));
00739         }
00740 
00741         Atom uintAtom(Atom atom)
00742         {
00743             return uintToAtom(toUInt32(atom));
00744         }
00745 
00753         int boolean(Atom atom);
00754 
00760         Stringp string(Atom atom);
00761 
00762         Stringp coerce_s(Atom atom);
00763 
00767         static bool isString(Atom atom)
00768         {
00769             return (atom&0x7) == kStringType && !isNull(atom);
00770         }
00771 
00772         static bool isName(Atom atom)
00773         {
00774             return isString(atom) && atomToString(atom)->isInterned();
00775         }
00776 
00789         Stringp intern(Atom atom);
00790 
00791         Namespace* internNamespace(Namespace* ns);
00792 
00794         static int readS24(const byte *pc)
00795         {
00796             #ifdef AVMPLUS_UNALIGNED_ACCESS
00797                 // unaligned short access still faster than 2 byte accesses
00798                 return ((uint16_t*)pc)[0] | ((int8_t*)pc)[2]<<16;
00799             #else
00800                 return pc[0] | pc[1]<<8 | ((int8_t*)pc)[2]<<16;
00801             #endif
00802         }
00803 
00808         static int calculateInstructionWidth(const byte* p)
00809         {
00810             int a, b;
00811             unsigned int c, d;
00812             const byte* p2 = p;
00813             readOperands(p2, c, a, d, b);
00814             return int(p2-p);
00815         }
00816 
00822         static void readOperands(const byte* &pc, unsigned int& imm32, int& imm24, unsigned int& imm32b, int& imm8 )
00823         {
00824             AbcOpcode opcode = (AbcOpcode)*pc++;
00825             int op_count = opOperandCount[opcode];
00826 
00827             imm8 = pc[0];
00828             if( opcode == OP_pushbyte || opcode == OP_debug )
00829             {
00830                 // these two operands have a byte as their first operand, which is not encoded
00831                 // with the variable length encoding scheme for bigger numbers, because it will
00832                 // never be larger than a byte.
00833                 --op_count;
00834                 pc++;
00835             }
00836 
00837             if( op_count > 0 )
00838             {
00839                 if( opcode >= OP_ifnlt && opcode <= OP_lookupswitch )
00840                 {
00841                     imm24 = AvmCore::readS24(pc);
00842                     pc += 3;
00843                 }
00844                 else
00845                 {
00846                     imm32 = AvmCore::readU30(pc);
00847                 }
00848 
00849                 if( opcode == OP_debug )
00850                 {
00851                     --op_count; //OP_debug has a third operand of a byte
00852                     pc++;
00853                 }
00854                 if( op_count > 1 )
00855                 {
00856                     imm32b = AvmCore::readU30(pc);
00857                 }
00858             }
00859         }
00868         static uint32 readU30(const byte *&p)
00869         {
00870             unsigned int result = p[0];
00871             if (!(result & 0x00000080))
00872             {
00873                 p++;
00874                 return result;
00875             }
00876             result = (result & 0x0000007f) | p[1]<<7;
00877             if (!(result & 0x00004000))
00878             {
00879                 p += 2;
00880                 return result;
00881             }
00882             result = (result & 0x00003fff) | p[2]<<14;
00883             if (!(result & 0x00200000))
00884             {
00885                 p += 3;
00886                 return result;
00887             }
00888             result = (result & 0x001fffff) | p[3]<<21;
00889             if (!(result & 0x10000000))
00890             {
00891                 p += 4;
00892                 return result;
00893             }
00894             result = (result & 0x0fffffff) | p[4]<<28;
00895             p += 5;
00896             return result;
00897         }
00898 
00900         static int32_t readU16(const byte *pc)
00901         {
00902             #ifdef AVMPLUS_UNALIGNED_ACCESS
00903                 // unaligned short access still faster than 2 byte accesses
00904                 return *((uint16_t*)pc);
00905             #else
00906                 return pc[0] | pc[1]<<8;
00907             #endif
00908         }
00909 
00915         bool istype(Atom atom, Traits* itraits);
00916 
00922         Atom istypeAtom(Atom atom, Traits* itraits) { 
00923             return istype(atom, itraits) ? trueAtom : falseAtom; 
00924         }
00925 
00930         void increment_d(Atom *atom, int delta);
00931 
00936         void increment_i(Atom *atom, int delta);
00937         
00941         Atom primitive(Atom atom);
00942 
00944         Atom booleanAtom(Atom atom);
00945 
00947         Atom numberAtom(Atom atom);
00948         
00952         double number(Atom atom) const;
00953 
00959         Atom constant(const char *s)
00960         {
00961             return constantString(s)->atom();
00962         }
00963 
00964         Stringp constantString(const char *s);
00965 
00970         virtual void interrupt(MethodEnv *env) = 0;
00971 
00977         virtual void stackOverflow(MethodEnv *env) = 0;
00978 
00979         void _stackOverflow(MethodEnv *env) { stackOverflow(env); }
00980         
00985         void throwAtom(Atom atom);
00986 
00992         void throwException(Exception *exception);
00993 
00998         void throwErrorV(ClassClosure *type, int errorID, Stringp arg1=0, Stringp arg2=0, Stringp arg3=0);
00999 
01004         String* formatErrorMessageV( int errorID, Stringp arg1=0, Stringp arg2=0, Stringp arg3=0);
01005 
01010         String* toErrorString(int d);
01011         String* toErrorString(AbstractFunction* m);
01012         String* toErrorString(const Multiname* n);
01013         String* toErrorString(Namespace* ns);
01014         String* toErrorString(Traits* t);
01015         String* toErrorString(const char* s);
01016         String* toErrorString(const wchar* s);
01017         String* atomToErrorString(Atom a);
01018 
01024         virtual String* getErrorMessage(int errorID);
01025 
01026         #ifdef DEBUGGER
01027 
01033         bool willExceptionBeCaught(Exception* exception);
01034 
01039         String* findErrorMessage(int errorID,
01040                                  int* mapTable,
01041                                  const char** errorTable,
01042                                  int numErrors);
01043 
01047         virtual int determineLanguage();
01048         int langID;
01049         
01050 
01054         StackTrace* newStackTrace();
01055 
01056         #ifdef _DEBUG
01057         void dumpStackTrace();
01058         #endif
01059 #endif /* DEBUGGER */
01060 
01062         CallStackNode *callStack;
01063 
01064 #ifdef FEATURE_SAMPLER
01065 
01069         Sampler *sampler() { return &_sampler; }
01070         void sampleCheck() { _sampler.sampleCheck(); }
01071         bool sampling() { return _sampler.sampling; }
01072         bool passAllExceptionsToDebugger;
01073 
01074 #endif
01075 
01076         CodeContextAtom codeContextAtom;
01077 
01078         CodeContext* codeContext() const;
01079 
01081         ExceptionFrame *exceptionFrame;
01082         
01083         Exception *exceptionAddr;
01084 
01100         ExceptionHandler* findExceptionHandler(MethodInfo *info,
01101                                                sintptr pc,
01102                                                Exception *exception);
01103         
01104         ExceptionHandler* beginCatch(ExceptionFrame *ef,
01105                 MethodInfo *info, sintptr pc, Exception *exception);
01106 
01113         ExceptionHandler* findExceptionHandlerNoRethrow(MethodInfo *info,
01114                                                         sintptr pc,
01115                                                         Exception *exception);
01116 
01121         bool isXML (Atom atm);
01122 
01123         /* Returns tru if the atom is a Date object */
01124         bool isDate(Atom atm);
01125 
01126         // From http://www.w3.org/TR/2004/REC-xml-20040204/#NT-Name
01127         bool isLetter (wchar c);
01128         bool isDigit (wchar c);
01129         bool isCombiningChar (wchar c);
01130         bool isExtender (wchar c);
01131 
01132         Stringp ToXMLString (Atom a);
01133         Stringp EscapeElementValue (const Stringp s, bool removeLeadingTrailingWhitespace);
01134         Stringp EscapeAttributeValue (Atom v);
01135 
01140         E4XNode *atomToXML (Atom atm);
01141 
01146         XMLObject *atomToXMLObject (Atom atm);
01147 
01152         bool isXMLList (Atom atm);
01153 
01158         XMLListObject *atomToXMLList (Atom atm);
01159 
01164         bool isQName (Atom atm);
01165 
01170         bool isDictionary (Atom atm);
01171 
01172         bool isDictionaryLookup(Atom key, Atom obj)
01173         {
01174             return isObject(key) && isDictionary(obj);
01175         }
01176 
01181         bool isXMLName(Atom arg);
01182 
01187         QNameObject *atomToQName (Atom atm);
01188 
01190         Stringp _typeof (Atom arg);
01191 
01193         Hashtable *xmlEntities;
01194         
01195     private:
01196         DECLARE_NATIVE_CLASSES()
01197         DECLARE_NATIVE_SCRIPTS()
01198 
01199         void registerNatives(NativeTableEntryp nativeMap, AbstractFunction *nativeMethods[]);
01200 
01201         //
01202         // this used to be Heap
01203         //
01204 
01206         int stringCount;
01207 
01209         int deletedCount;
01210         #define AVMPLUS_STRING_DELETED ((Stringp)(1))
01211 
01213         int nsCount;
01214 
01215         int numStrings;
01216         int numNamespaces;
01217                 
01218     public:
01219 
01220         static Namespace *atomToNamespace(Atom atom)
01221         {
01222             AvmAssert((atom&7)==kNamespaceType);
01223             return (Namespace*)(atom&~7);
01224         }
01225         
01226         static double atomToDouble(Atom atom)
01227         {
01228             AvmAssert((atom&7)==kDoubleType);
01229 
01230             double* obj = (double*)(atom&~7);
01231             return *obj;
01232         }
01233 
01239         static Stringp atomToString(Atom atom)
01240         {
01241             AvmAssert((atom&7)==kStringType);
01242             return (Stringp)(atom&~7);
01243         }
01244 
01245         // Avoid adding validation checks here and returning NULL.  If this
01246         // is returning a bad value, the higher level function should be fixed
01247         // or AbcParser/Verifier should be enhanced to catch this case.
01248         static ScriptObject* atomToScriptObject(const Atom atom)
01249         {
01250             AvmAssert((atom&7)==kObjectType);
01251             return (ScriptObject*)(atom&~7);
01252         }
01253     
01254         // helper function, allows generic objects to work with Hashtable
01255         // and AtomArray, uses double type which is the only non-RC
01256         // GCObject type
01257         static Atom gcObjectToAtom(const void* obj);
01258         static const void* atomToGCObject(Atom a) { return (const void*)(a&~7); }
01259         static bool isGCObject(Atom a) { return (a&7)==kDoubleType; }
01260 
01261     private:
01263         int findString(const wchar *s, int len);
01264 
01266         int findNamespace(const Namespace *ns);
01267 
01268     public:
01274         Stringp internString(Stringp s);
01275         Stringp internString(Atom atom);
01276         Stringp internInt(int n);
01277         Stringp internDouble(double d);
01278         Stringp internUint32(uint32 ui);
01279 
01285         Stringp internAlloc(const wchar *s, int len);
01286         Stringp internAllocUtf8(const byte *s, int len);
01287 
01288 #ifdef FEATURE_SAMPLER
01289 
01292         Stringp findInternedString(const char *s, int len);
01293 #endif
01294 
01295         bool getIndexFromAtom (Atom a, uint32 *result) const
01296         {
01297             if (AvmCore::isInteger(a))
01298             {
01299                 *result = uint32(a >> 3);
01300                 return true;
01301             }
01302             else
01303             {
01304                 AvmAssert (AvmCore::isString(a));
01305                 return AvmCore::getIndexFromString (atomToString (a), result); 
01306             }
01307         }
01308 
01309         static bool getIndexFromString(Stringp s, uint32 *result);
01310             
01311         ScriptBufferImpl* newScriptBuffer(size_t size);
01312         VTable* newVTable(Traits* traits, VTable* base, ScopeChain* scope, AbcEnv* abcEnv, Toplevel* toplevel);
01313 
01314         RegExpObject* newRegExp(RegExpClass* regExpClass,
01315                                 Stringp pattern,
01316                                 Stringp options);
01317 
01318         ScriptObject* newObject(VTable* ivtable, ScriptObject *delegate);
01319 
01323         Traits* newTraits(Traits *base,
01324                           int nameCount,
01325                           int interfaceCount,
01326                           uint32 sizeofInstance);
01327         
01328         Namespace* newNamespace(Atom prefix, Atom uri, Namespace::NamespaceType type = Namespace::NS_Public);
01329         Namespace* newNamespace(Atom uri, Namespace::NamespaceType type = Namespace::NS_Public);
01330         Namespace* newNamespace(Stringp uri, Namespace::NamespaceType type = Namespace::NS_Public);
01331         Namespace* newPublicNamespace(Stringp uri) { return newNamespace(uri); }
01332         NamespaceSet* newNamespaceSet(int nsCount);
01333 
01334         // String creation
01335         Stringp newString(const char *str) const;
01336         Stringp newString(const wchar *str) const;
01337         Stringp newString(const char *str, int len) const;      
01338 
01339         Stringp uintToString(uint32 i);
01340         Stringp intToString(int i);
01341         Stringp doubleToString(double d);
01342         Stringp concatStrings(Stringp s1, Stringp s2) const;
01343         
01344         Atom uintToAtom(uint32 n);
01345         Atom intToAtom(int n);
01346 
01347         Atom allocDouble(double n)
01348         {
01349             union { 
01350                 double *d;
01351                 void *v;
01352             };
01353             v = GetGC()->Alloc(sizeof(double), 0);
01354             *d = n;
01355             return kDoubleType | (uintptr)v;
01356         }
01357         
01358         void rehashStrings(int newlen);
01359         void rehashNamespaces(int newlen);
01360 
01361         // static version for smart pointers
01362         static void atomWriteBarrier(MMgc::GC *gc, const void *container, Atom *address, Atom atomNew);
01363 #ifdef MMGC_DRC
01364         static void decrementAtomRegion(Atom *ar, int length);
01365 #endif
01366 
01367 #ifdef AVMPLUS_VERBOSE
01368     public:
01369         Stringp format(Atom atom);
01370         Stringp formatAtomPtr(Atom atom);
01371 #endif
01372 
01373     private:
01374         // hash set containing intern'ed strings
01375         DRC(Stringp) * strings;
01376         // hash set containing namespaces
01377         DRC(Namespacep) * namespaces;
01378 
01379 #ifdef AVMPLUS_INTERNINT_CACHE
01380         // See code in AvmCore::internInt
01381         // cache of interned names of nonnegative integers (numeric value % 256)
01382         class IndexString : public MMgc::GCObject {
01383         public:
01384             int value;
01385             DRCWB(Stringp) string;
01386         };
01387         
01388         IndexString* index_strings[256];
01389 #endif
01390         
01391 #ifdef AVMPLUS_WORD_CODE
01392     private:
01393         // Saturating counter.  
01394         uint32 lookup_cache_timestamp;
01395     public:
01396         uint32 lookupCacheTimestamp() { return lookup_cache_timestamp == ~0U ? 0 : lookup_cache_timestamp; }
01397         bool   lookupCacheIsValid(uint32 t) { return t == lookup_cache_timestamp; }
01398         void   invalidateLookupCache() { if (lookup_cache_timestamp != ~0U) ++lookup_cache_timestamp; }
01399 #endif
01400         
01401         // avoid multiple inheritance issues
01402         class GCInterface : MMgc::GCCallback
01403         {
01404         public:
01405             GCInterface(MMgc::GC * _gc) : MMgc::GCCallback(_gc), core(NULL) {}
01406             void SetCore(AvmCore* _core) { this->core = _core; }
01407             void presweep() { if(core) core->presweep(); }
01408             void postsweep() { if(core) core->postsweep(); }
01409             void log(const char *str) { if(core) core->console << str; }
01410         private:
01411             AvmCore *core;
01412         };
01413         GCInterface gcInterface;
01414 
01415 #ifdef FEATURE_SAMPLER
01416     private:
01417         Sampler _sampler;
01418 #endif
01419     };
01420 }
01421 
01422 #endif /* __avmplus_AvmCore__ */

Generated on Sun Oct 12 18:49:51 2008 for Tamarin by  doxygen 1.4.6