📄 internal.cpp
字号:
// -*- c-basic-offset: 2 -*-/* * This file is part of the KDE libraries * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) * Copyright (C) 2003 Apple Computer, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */#include <stdio.h>#include <math.h>#include <assert.h>#ifndef NDEBUG#include <strings.h> // for strdup#endif#include "array_object.h"#include "bool_object.h"#include "collector.h"#include "context.h"#include "date_object.h"#include "debugger.h"#include "error_object.h"#include "function_object.h"#include "internal.h"#include "interpreter_map.h"#include "lexer.h"#include "math_object.h"#include "nodes.h"#include "number_object.h"#include "object.h"#include "object_object.h"#include "operations.h"#include "regexp_object.h"#include "string_object.h"#define I18N_NOOP(s) sextern int kjsyyparse();using namespace KJS;#if !APPLE_CHANGES || KWIQnamespace KJS {#ifdef WORDS_BIGENDIAN const unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; const unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };#elif defined(arm) const unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }; const unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };#else const unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; const unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };#endif const double NaN = *(const double*) NaN_Bytes; const double Inf = *(const double*) Inf_Bytes;};#endif // APPLE_CHANGESstatic pthread_once_t interpreterLockOnce = PTHREAD_ONCE_INIT;static pthread_mutex_t interpreterLock;static int interpreterLockCount = 0;static void initializeInterpreterLock(){ pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&interpreterLock, &attr);}static inline void lockInterpreter(){ pthread_once(&interpreterLockOnce, initializeInterpreterLock); pthread_mutex_lock(&interpreterLock); interpreterLockCount++;}static inline void unlockInterpreter(){ interpreterLockCount--; pthread_mutex_unlock(&interpreterLock);}// ------------------------------ UndefinedImp ---------------------------------UndefinedImp *UndefinedImp::staticUndefined = 0;Value UndefinedImp::toPrimitive(ExecState */*exec*/, Type) const{ return Value((ValueImp*)this);}bool UndefinedImp::toBoolean(ExecState */*exec*/) const{ return false;}double UndefinedImp::toNumber(ExecState */*exec*/) const{ return NaN;}UString UndefinedImp::toString(ExecState */*exec*/) const{ return "undefined";}Object UndefinedImp::toObject(ExecState *exec) const{ Object err = Error::create(exec, TypeError, I18N_NOOP("Undefined value")); exec->setException(err); return err;}// ------------------------------ NullImp --------------------------------------NullImp *NullImp::staticNull = 0;Value NullImp::toPrimitive(ExecState */*exec*/, Type) const{ return Value((ValueImp*)this);}bool NullImp::toBoolean(ExecState */*exec*/) const{ return false;}double NullImp::toNumber(ExecState */*exec*/) const{ return 0.0;}UString NullImp::toString(ExecState */*exec*/) const{ return "null";}Object NullImp::toObject(ExecState *exec) const{ Object err = Error::create(exec, TypeError, I18N_NOOP("Null value")); exec->setException(err); return err;}// ------------------------------ BooleanImp -----------------------------------BooleanImp* BooleanImp::staticTrue = 0;BooleanImp* BooleanImp::staticFalse = 0;Value BooleanImp::toPrimitive(ExecState */*exec*/, Type) const{ return Value((ValueImp*)this);}bool BooleanImp::toBoolean(ExecState */*exec*/) const{ return val;}double BooleanImp::toNumber(ExecState */*exec*/) const{ return val ? 1.0 : 0.0;}UString BooleanImp::toString(ExecState */*exec*/) const{ return val ? "true" : "false";}Object BooleanImp::toObject(ExecState *exec) const{ List args; args.append(const_cast<BooleanImp*>(this)); return Object::dynamicCast(exec->lexicalInterpreter()->builtinBoolean().construct(exec,args));}// ------------------------------ StringImp ------------------------------------Value StringImp::toPrimitive(ExecState */*exec*/, Type) const{ return Value((ValueImp*)this);}bool StringImp::toBoolean(ExecState */*exec*/) const{ return (val.size() > 0);}double StringImp::toNumber(ExecState */*exec*/) const{ return val.toDouble();}UString StringImp::toString(ExecState */*exec*/) const{ return val;}Object StringImp::toObject(ExecState *exec) const{ List args; args.append(const_cast<StringImp*>(this)); return Object::dynamicCast(exec->lexicalInterpreter()->builtinString().construct(exec,args));}// ------------------------------ NumberImp ------------------------------------NumberImp *NumberImp::staticNaN;ValueImp *NumberImp::create(int i){ if (SimpleNumber::fits(i)) return SimpleNumber::make(i); NumberImp *imp = new NumberImp(static_cast<double>(i)); imp->setGcAllowedFast(); return imp;}ValueImp *NumberImp::create(double d){ if (SimpleNumber::fits(d)) return SimpleNumber::make((int)d); if (isNaN(d)) return staticNaN; NumberImp *imp = new NumberImp(d); imp->setGcAllowedFast(); return imp;}Value NumberImp::toPrimitive(ExecState *, Type) const{ return Number((NumberImp*)this);}bool NumberImp::toBoolean(ExecState *) const{ return !((val == 0) /* || (iVal() == N0) */ || isNaN(val));}double NumberImp::toNumber(ExecState *) const{ return val;}UString NumberImp::toString(ExecState *) const{ return UString::from(val);}Object NumberImp::toObject(ExecState *exec) const{ List args; args.append(const_cast<NumberImp*>(this)); return Object::dynamicCast(exec->lexicalInterpreter()->builtinNumber().construct(exec,args));}bool NumberImp::toUInt32(unsigned& uint32) const{ uint32 = (unsigned)val; return (double)uint32 == val;}double SimpleNumber::negZero = -0.0;// ------------------------------ LabelStack -----------------------------------LabelStack::LabelStack(const LabelStack &other){ tos = 0; *this = other;}LabelStack &LabelStack::operator=(const LabelStack &other){ clear(); tos = 0; StackElem *cur = 0; StackElem *se = other.tos; while (se) { StackElem *newPrev = new StackElem; newPrev->prev = 0; newPrev->id = se->id; if (cur) cur->prev = newPrev; else tos = newPrev; cur = newPrev; se = se->prev; } return *this;}bool LabelStack::push(const Identifier &id){ if (id.isEmpty() || contains(id)) return false; StackElem *newtos = new StackElem; newtos->id = id; newtos->prev = tos; tos = newtos; return true;}bool LabelStack::contains(const Identifier &id) const{ if (id.isEmpty()) return true; for (StackElem *curr = tos; curr; curr = curr->prev) if (curr->id == id) return true; return false;}void LabelStack::pop(){ if (tos) { StackElem *prev = tos->prev;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -