00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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) 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) 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
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
00211 List<GrowableBuffer*> mirBuffers;
00212 GrowableBuffer* requestNewMirBuffer();
00213 GrowableBuffer* requestMirBuffer();
00214 void releaseMirBuffer(GrowableBuffer* buffer);
00215
00216
00217 #ifdef AVMPLUS_VERBOSE
00218 MMgc::GCHashtable* codegenMethodNames;
00219 #endif
00220 #endif
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;
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
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
00678 static int integer_i(Atom a)
00679 {
00680 if ((a&7) == kIntegerType)
00681 return int(a>>3);
00682 else
00683
00684 return MathUtils::real2int(atomToDouble(a));
00685 }
00686
00687
00688 static uint32 integer_u(Atom a)
00689 {
00690 if ((a&7) == kIntegerType)
00691 {
00692 return uint32(a>>3);
00693 }
00694 else
00695 {
00696
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
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
00831
00832
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;
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
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
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
01124 bool isDate(Atom atm);
01125
01126
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
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
01246
01247
01248 static ScriptObject* atomToScriptObject(const Atom atom)
01249 {
01250 AvmAssert((atom&7)==kObjectType);
01251 return (ScriptObject*)(atom&~7);
01252 }
01253
01254
01255
01256
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
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
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
01375 DRC(Stringp) * strings;
01376
01377 DRC(Namespacep) * namespaces;
01378
01379 #ifdef AVMPLUS_INTERNINT_CACHE
01380
01381
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
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
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