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 #ifndef _INTERNAL_H_
00026 #define _INTERNAL_H_
00027
00028 #include "ustring.h"
00029 #include "value.h"
00030 #include "object.h"
00031 #include "function.h"
00032 #include "types.h"
00033 #include "interpreter.h"
00034 #include "scope_chain.h"
00035 #include "array_instance.h"
00036
00037 #ifndef I18N_NOOP
00038 #define I18N_NOOP(s) s
00039 #endif
00040
00041 namespace KJS {
00042
00043 static const double D16 = 65536.0;
00044 static const double D32 = 4294967296.0;
00045
00046 class FunctionBodyNode;
00047 class FunctionBodyNode;
00048 class FunctionPrototypeImp;
00049 class FunctionImp;
00050 class Parameter;
00051 class Debugger;
00052
00053
00054
00055
00056
00057 class UndefinedImp : public ValueImp {
00058 public:
00059 Type type() const { return UndefinedType; }
00060
00061 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
00062 bool toBoolean(ExecState *exec) const;
00063 double toNumber(ExecState *exec) const;
00064 UString toString(ExecState *exec) const;
00065 Object toObject(ExecState *exec) const;
00066
00067 static UndefinedImp *staticUndefined;
00068 };
00069
00070 inline Undefined::Undefined(UndefinedImp *imp) : Value(imp) { }
00071
00072 class NullImp : public ValueImp {
00073 public:
00074 Type type() const { return NullType; }
00075
00076 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
00077 bool toBoolean(ExecState *exec) const;
00078 double toNumber(ExecState *exec) const;
00079 UString toString(ExecState *exec) const;
00080 Object toObject(ExecState *exec) const;
00081
00082 static NullImp *staticNull;
00083 };
00084
00085 inline Null::Null(NullImp *imp) : Value(imp) { }
00086
00087 class BooleanImp : public ValueImp {
00088 public:
00089 BooleanImp(bool v = false) : val(v) { }
00090 bool value() const { return val; }
00091
00092 Type type() const { return BooleanType; }
00093
00094 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
00095 bool toBoolean(ExecState *exec) const;
00096 double toNumber(ExecState *exec) const;
00097 UString toString(ExecState *exec) const;
00098 Object toObject(ExecState *exec) const;
00099
00100 static BooleanImp *staticTrue;
00101 static BooleanImp *staticFalse;
00102 private:
00103 bool val;
00104 };
00105
00106 inline Boolean::Boolean(BooleanImp *imp) : Value(imp) { }
00107
00108 class StringImp : public ValueImp {
00109 public:
00110 StringImp(const UString& v) : val(v) { }
00111 UString value() const { return val; }
00112
00113 Type type() const { return StringType; }
00114
00115 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
00116 bool toBoolean(ExecState *exec) const;
00117 double toNumber(ExecState *exec) const;
00118 UString toString(ExecState *exec) const;
00119 Object toObject(ExecState *exec) const;
00120
00121 private:
00122 UString val;
00123 };
00124
00125 inline String::String(StringImp *imp) : Value(imp) { }
00126
00127 class NumberImp : public ValueImp {
00128 friend class Number;
00129 friend class InterpreterImp;
00130 public:
00131 static ValueImp *create(int);
00132 static ValueImp *create(double);
00133 static ValueImp *zero() { return SimpleNumber::make(0); }
00134 static ValueImp *one() { return SimpleNumber::make(1); }
00135 static ValueImp *two() { return SimpleNumber::make(2); }
00136
00137 double value() const { return val; }
00138
00139 Type type() const { return NumberType; }
00140
00141 Value toPrimitive(ExecState *exec, Type preferred = UnspecifiedType) const;
00142 bool toBoolean(ExecState *exec) const;
00143 double toNumber(ExecState *exec) const;
00144 UString toString(ExecState *exec) const;
00145 Object toObject(ExecState *exec) const;
00146
00147 static NumberImp *staticNaN;
00148
00149 private:
00150 NumberImp(double v) : val(v) { }
00151
00152 virtual bool toUInt32(unsigned&) const;
00153
00154 double val;
00155 };
00156
00157 inline Number::Number(NumberImp *imp) : Value(imp) { }
00158
00162 class LabelStack {
00163 public:
00164 LabelStack(): tos(0L), iterationDepth(0), switchDepth(0) {}
00165 ~LabelStack();
00166
00167 LabelStack(const LabelStack &other);
00168 LabelStack &operator=(const LabelStack &other);
00169
00174 bool push(const Identifier &id);
00178 bool contains(const Identifier &id) const;
00182 void pop();
00183
00184 void pushIteration() { iterationDepth++; }
00185 void popIteration() { iterationDepth--; }
00186 bool inIteration() const { return (iterationDepth > 0); }
00187
00188 void pushSwitch() { switchDepth++; }
00189 void popSwitch() { switchDepth--; }
00190 bool inSwitch() const { return (switchDepth > 0); }
00191
00192 private:
00193 struct StackElem {
00194 Identifier id;
00195 StackElem *prev;
00196 };
00197
00198 StackElem *tos;
00199 void clear();
00200 int iterationDepth;
00201 int switchDepth;
00202 };
00203
00204
00205
00206
00207
00208
00209 class SourceCode {
00210 public:
00211 SourceCode(int _sid)
00212 : sid(_sid), interpreter(0), refcount(0), next(0) {}
00213
00214 void ref() { refcount++; }
00215 void deref() { if (!--refcount) cleanup(); }
00216 void cleanup();
00217
00218 int sid;
00219 InterpreterImp *interpreter;
00220 int refcount;
00221 SourceCode *next;
00222 };
00223
00231 class Parser {
00232 public:
00233 static FunctionBodyNode *parse(const UChar *code, unsigned int length, SourceCode **src,
00234 int *errLine = 0, UString *errMsg = 0);
00235
00236 static FunctionBodyNode *progNode;
00237 static SourceCode *source;
00238 static int sid;
00239 private:
00240 };
00241
00242 class InterpreterImp {
00243 friend class Collector;
00244 public:
00245 static void globalInit();
00246 static void globalClear();
00247
00248 InterpreterImp(Interpreter *interp, const Object &glob);
00249 ~InterpreterImp();
00250
00251 Object &globalObject() const { return const_cast<Object &>(global); }
00252 Interpreter* interpreter() const { return m_interpreter; }
00253
00254 void initGlobalObject();
00255 static void lock();
00256 static void unlock();
00257
00258 void mark();
00259
00260 ExecState *globalExec() { return globExec; }
00261 bool checkSyntax(const UString &code,int *errLine, UString *errMsg);
00262 bool checkSyntax(const UString &code);
00263 Completion evaluate(const UString &code, const Value &thisV);
00264 Debugger *debugger() const { return dbg; }
00265 void setDebugger(Debugger *d);
00266
00267 Object builtinObject() const { return b_Object; }
00268 Object builtinFunction() const { return b_Function; }
00269 Object builtinArray() const { return b_Array; }
00270 Object builtinBoolean() const { return b_Boolean; }
00271 Object builtinString() const { return b_String; }
00272 Object builtinNumber() const { return b_Number; }
00273 Object builtinDate() const { return b_Date; }
00274 Object builtinRegExp() const { return b_RegExp; }
00275 Object builtinError() const { return b_Error; }
00276
00277 Object builtinObjectPrototype() const { return b_ObjectPrototype; }
00278 Object builtinFunctionPrototype() const { return b_FunctionPrototype; }
00279 Object builtinArrayPrototype() const { return b_ArrayPrototype; }
00280 Object builtinBooleanPrototype() const { return b_BooleanPrototype; }
00281 Object builtinStringPrototype() const { return b_StringPrototype; }
00282 Object builtinNumberPrototype() const { return b_NumberPrototype; }
00283 Object builtinDatePrototype() const { return b_DatePrototype; }
00284 Object builtinRegExpPrototype() const { return b_RegExpPrototype; }
00285 Object builtinErrorPrototype() const { return b_ErrorPrototype; }
00286
00287 Object builtinEvalError() const { return b_evalError; }
00288 Object builtinRangeError() const { return b_rangeError; }
00289 Object builtinReferenceError() const { return b_referenceError; }
00290 Object builtinSyntaxError() const { return b_syntaxError; }
00291 Object builtinTypeError() const { return b_typeError; }
00292 Object builtinURIError() const { return b_uriError; }
00293
00294 Object builtinEvalErrorPrototype() const { return b_evalErrorPrototype; }
00295 Object builtinRangeErrorPrototype() const { return b_rangeErrorPrototype; }
00296 Object builtinReferenceErrorPrototype() const { return b_referenceErrorPrototype; }
00297 Object builtinSyntaxErrorPrototype() const { return b_syntaxErrorPrototype; }
00298 Object builtinTypeErrorPrototype() const { return b_typeErrorPrototype; }
00299 Object builtinURIErrorPrototype() const { return b_uriErrorPrototype; }
00300
00301 void setCompatMode(Interpreter::CompatMode mode) { m_compatMode = mode; }
00302 Interpreter::CompatMode compatMode() const { return m_compatMode; }
00303
00304
00305 static InterpreterImp* firstInterpreter() { return s_hook; }
00306 InterpreterImp *nextInterpreter() const { return next; }
00307 InterpreterImp *prevInterpreter() const { return prev; }
00308
00309 void addSourceCode(SourceCode *code);
00310 void removeSourceCode(SourceCode *code);
00311
00312 void setContext(ContextImp *c) { _context = c; }
00313
00314 private:
00315 void clear();
00316 Interpreter *m_interpreter;
00317 Object global;
00318 Debugger *dbg;
00319
00320
00321
00322
00323
00324 Object b_Object;
00325 Object b_Function;
00326 Object b_Array;
00327 Object b_Boolean;
00328 Object b_String;
00329 Object b_Number;
00330 Object b_Date;
00331 Object b_RegExp;
00332 Object b_Error;
00333
00334 Object b_ObjectPrototype;
00335 Object b_FunctionPrototype;
00336 Object b_ArrayPrototype;
00337 Object b_BooleanPrototype;
00338 Object b_StringPrototype;
00339 Object b_NumberPrototype;
00340 Object b_DatePrototype;
00341 Object b_RegExpPrototype;
00342 Object b_ErrorPrototype;
00343
00344 Object b_evalError;
00345 Object b_rangeError;
00346 Object b_referenceError;
00347 Object b_syntaxError;
00348 Object b_typeError;
00349 Object b_uriError;
00350
00351 Object b_evalErrorPrototype;
00352 Object b_rangeErrorPrototype;
00353 Object b_referenceErrorPrototype;
00354 Object b_syntaxErrorPrototype;
00355 Object b_typeErrorPrototype;
00356 Object b_uriErrorPrototype;
00357
00358 ExecState *globExec;
00359 Interpreter::CompatMode m_compatMode;
00360
00361
00362 static InterpreterImp* s_hook;
00363 InterpreterImp *next, *prev;
00364
00365 ContextImp *_context;
00366
00367 int recursion;
00368 SourceCode *sources;
00369 };
00370
00371 class AttachedInterpreter;
00372 class DebuggerImp {
00373 public:
00374
00375 DebuggerImp() {
00376 interps = 0;
00377 isAborted = false;
00378 }
00379
00380 void abort() { isAborted = true; }
00381 bool aborted() const { return isAborted; }
00382
00383 AttachedInterpreter *interps;
00384 bool isAborted;
00385 };
00386
00390 class FunctionImp : public InternalFunctionImp {
00391 friend class ActivationImp;
00392 public:
00393 FunctionImp(ExecState *exec, const Identifier &n = Identifier::null());
00394 virtual ~FunctionImp();
00395
00396 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00397 virtual void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr = None);
00398 virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
00399 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
00400
00401 virtual bool implementsCall() const;
00402 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00403
00404 void addParameter(const Identifier &n);
00405 Identifier parameterProperty(int index) const;
00406
00407 UString parameterString() const;
00408 virtual CodeType codeType() const = 0;
00409
00410 virtual Completion execute(ExecState *exec) = 0;
00411 int firstLine() const { return line0; }
00412 int lastLine() const { return line1; }
00413 int sourceId() const { return sid; }
00414
00415 virtual const ClassInfo *classInfo() const { return &info; }
00416 static const ClassInfo info;
00417 protected:
00418 Parameter *param;
00419 int line0;
00420 int line1;
00421 int sid;
00422
00423 private:
00424 void processParameters(ExecState *exec, const List &);
00425 virtual void processVarDecls(ExecState *exec);
00426 };
00427
00428 class DeclaredFunctionImp : public FunctionImp {
00429 public:
00430 DeclaredFunctionImp(ExecState *exec, const Identifier &n,
00431 FunctionBodyNode *b, const ScopeChain &sc);
00432 ~DeclaredFunctionImp();
00433
00434 bool implementsConstruct() const;
00435 Object construct(ExecState *exec, const List &args);
00436
00437 virtual Completion execute(ExecState *exec);
00438 CodeType codeType() const { return FunctionCode; }
00439 FunctionBodyNode *body;
00440
00441 virtual const ClassInfo *classInfo() const { return &info; }
00442 KJS_EXPORT static const ClassInfo info;
00443 private:
00444 virtual void processVarDecls(ExecState *exec);
00445 };
00446
00447 class ActivationImp;
00448
00449 class ArgumentsImp : public ObjectImp {
00450 public:
00451 ArgumentsImp(ExecState *exec, FunctionImp *func, const List &args, ActivationImp *act);
00452
00453 virtual void mark();
00454
00455 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00456 virtual void put(ExecState *exec, const Identifier &propertyName,
00457 const Value &value, int attr = None);
00458
00459 virtual const ClassInfo *classInfo() const { return &info; }
00460 static const ClassInfo info;
00461
00462 private:
00463 ActivationImp *activation;
00464 };
00465
00466 class ActivationImp : public ObjectImp {
00467 public:
00468 ActivationImp(FunctionImp *function, const List &arguments);
00469
00470 virtual Value get(ExecState *exec, const Identifier &propertyName) const;
00471 virtual bool hasProperty(ExecState *exec, const Identifier &propertyName) const;
00472 virtual bool deleteProperty(ExecState *exec, const Identifier &propertyName);
00473
00474 virtual const ClassInfo *classInfo() const { return &info; }
00475 static const ClassInfo info;
00476
00477 virtual void mark();
00478
00479 private:
00480 FunctionImp *_function;
00481 List _arguments;
00482 mutable ArgumentsImp *_argumentsObject;
00483 };
00484
00485 class GlobalFuncImp : public InternalFunctionImp {
00486 public:
00487 GlobalFuncImp(ExecState *exec, FunctionPrototypeImp *funcProto,
00488 int i, int len, const Identifier &_ident);
00489 virtual bool implementsCall() const;
00490 virtual Value call(ExecState *exec, Object &thisObj, const List &args);
00491 virtual CodeType codeType() const;
00492 enum { Eval, ParseInt, ParseFloat, IsNaN, IsFinite, DecodeURI, DecodeURIComponent,
00493 EncodeURI, EncodeURIComponent, Escape, UnEscape, KJSPrint };
00494 private:
00495 int id;
00496 };
00497
00498
00499 double roundValue(ExecState *exec, const Value &v);
00500
00501 #ifndef NDEBUG
00502 void printInfo(ExecState *exec, const char *s, const Value &o, int lineno = -1);
00503 #endif
00504
00505 }
00506
00507
00508 #endif // _INTERNAL_H_