Commit 415e1c52 authored by weinig@apple.com's avatar weinig@apple.com

Reviewed by Darin.

        Fix for http://bugs.webkit.org/show_bug.cgi?id=16901
        Convert remaining JS function objects to use the new PrototypeFunction class

        - Moves Boolean, Function, RegExp, Number, Object and Global functions to their
          own static function implementations so that they can be used with the
          PrototypeFunction class.  SunSpider says this is 1.003x as fast.

        * kjs/JSGlobalObject.cpp:
        (KJS::JSGlobalObject::reset):
        * kjs/array_object.h:
        * kjs/bool_object.cpp:
        (KJS::BooleanInstance::BooleanInstance):
        (KJS::BooleanPrototype::BooleanPrototype):
        (KJS::booleanProtoFuncToString):
        (KJS::booleanProtoFuncValueOf):
        (KJS::BooleanObjectImp::BooleanObjectImp):
        (KJS::BooleanObjectImp::implementsConstruct):
        (KJS::BooleanObjectImp::construct):
        (KJS::BooleanObjectImp::callAsFunction):
        * kjs/bool_object.h:
        (KJS::BooleanInstance::classInfo):
        * kjs/error_object.cpp:
        (KJS::ErrorPrototype::ErrorPrototype):
        (KJS::errorProtoFuncToString):
        * kjs/error_object.h:
        * kjs/function.cpp:
        (KJS::globalFuncEval):
        (KJS::globalFuncParseInt):
        (KJS::globalFuncParseFloat):
        (KJS::globalFuncIsNaN):
        (KJS::globalFuncIsFinite):
        (KJS::globalFuncDecodeURI):
        (KJS::globalFuncDecodeURIComponent):
        (KJS::globalFuncEncodeURI):
        (KJS::globalFuncEncodeURIComponent):
        (KJS::globalFuncEscape):
        (KJS::globalFuncUnEscape):
        (KJS::globalFuncKJSPrint):
        (KJS::PrototypeFunction::PrototypeFunction):
        * kjs/function.h:
        * kjs/function_object.cpp:
        (KJS::FunctionPrototype::FunctionPrototype):
        (KJS::functionProtoFuncToString):
        (KJS::functionProtoFuncApply):
        (KJS::functionProtoFuncCall):
        * kjs/function_object.h:
        * kjs/number_object.cpp:
        (KJS::NumberPrototype::NumberPrototype):
        (KJS::numberProtoFuncToString):
        (KJS::numberProtoFuncToLocaleString):
        (KJS::numberProtoFuncValueOf):
        (KJS::numberProtoFuncToFixed):
        (KJS::numberProtoFuncToExponential):
        (KJS::numberProtoFuncToPrecision):
        * kjs/number_object.h:
        (KJS::NumberInstance::classInfo):
        (KJS::NumberObjectImp::classInfo):
        (KJS::NumberObjectImp::):
        * kjs/object_object.cpp:
        (KJS::ObjectPrototype::ObjectPrototype):
        (KJS::objectProtoFuncValueOf):
        (KJS::objectProtoFuncHasOwnProperty):
        (KJS::objectProtoFuncIsPrototypeOf):
        (KJS::objectProtoFuncDefineGetter):
        (KJS::objectProtoFuncDefineSetter):
        (KJS::objectProtoFuncLookupGetter):
        (KJS::objectProtoFuncLookupSetter):
        (KJS::objectProtoFuncPropertyIsEnumerable):
        (KJS::objectProtoFuncToLocaleString):
        (KJS::objectProtoFuncToString):
        * kjs/object_object.h:
        * kjs/regexp_object.cpp:
        (KJS::RegExpPrototype::RegExpPrototype):
        (KJS::regExpProtoFuncTest):
        (KJS::regExpProtoFuncExec):
        (KJS::regExpProtoFuncCompile):
        (KJS::regExpProtoFuncToString):
        * kjs/regexp_object.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@29588 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e8810eef
2008-01-16 Sam Weinig <sam@webkit.org>
Reviewed by Darin.
Fix for http://bugs.webkit.org/show_bug.cgi?id=16901
Convert remaining JS function objects to use the new PrototypeFunction class
- Moves Boolean, Function, RegExp, Number, Object and Global functions to their
own static function implementations so that they can be used with the
PrototypeFunction class. SunSpider says this is 1.003x as fast.
* kjs/JSGlobalObject.cpp:
(KJS::JSGlobalObject::reset):
* kjs/array_object.h:
* kjs/bool_object.cpp:
(KJS::BooleanInstance::BooleanInstance):
(KJS::BooleanPrototype::BooleanPrototype):
(KJS::booleanProtoFuncToString):
(KJS::booleanProtoFuncValueOf):
(KJS::BooleanObjectImp::BooleanObjectImp):
(KJS::BooleanObjectImp::implementsConstruct):
(KJS::BooleanObjectImp::construct):
(KJS::BooleanObjectImp::callAsFunction):
* kjs/bool_object.h:
(KJS::BooleanInstance::classInfo):
* kjs/error_object.cpp:
(KJS::ErrorPrototype::ErrorPrototype):
(KJS::errorProtoFuncToString):
* kjs/error_object.h:
* kjs/function.cpp:
(KJS::globalFuncEval):
(KJS::globalFuncParseInt):
(KJS::globalFuncParseFloat):
(KJS::globalFuncIsNaN):
(KJS::globalFuncIsFinite):
(KJS::globalFuncDecodeURI):
(KJS::globalFuncDecodeURIComponent):
(KJS::globalFuncEncodeURI):
(KJS::globalFuncEncodeURIComponent):
(KJS::globalFuncEscape):
(KJS::globalFuncUnEscape):
(KJS::globalFuncKJSPrint):
(KJS::PrototypeFunction::PrototypeFunction):
* kjs/function.h:
* kjs/function_object.cpp:
(KJS::FunctionPrototype::FunctionPrototype):
(KJS::functionProtoFuncToString):
(KJS::functionProtoFuncApply):
(KJS::functionProtoFuncCall):
* kjs/function_object.h:
* kjs/number_object.cpp:
(KJS::NumberPrototype::NumberPrototype):
(KJS::numberProtoFuncToString):
(KJS::numberProtoFuncToLocaleString):
(KJS::numberProtoFuncValueOf):
(KJS::numberProtoFuncToFixed):
(KJS::numberProtoFuncToExponential):
(KJS::numberProtoFuncToPrecision):
* kjs/number_object.h:
(KJS::NumberInstance::classInfo):
(KJS::NumberObjectImp::classInfo):
(KJS::NumberObjectImp::):
* kjs/object_object.cpp:
(KJS::ObjectPrototype::ObjectPrototype):
(KJS::objectProtoFuncValueOf):
(KJS::objectProtoFuncHasOwnProperty):
(KJS::objectProtoFuncIsPrototypeOf):
(KJS::objectProtoFuncDefineGetter):
(KJS::objectProtoFuncDefineSetter):
(KJS::objectProtoFuncLookupGetter):
(KJS::objectProtoFuncLookupSetter):
(KJS::objectProtoFuncPropertyIsEnumerable):
(KJS::objectProtoFuncToLocaleString):
(KJS::objectProtoFuncToString):
* kjs/object_object.h:
* kjs/regexp_object.cpp:
(KJS::RegExpPrototype::RegExpPrototype):
(KJS::regExpProtoFuncTest):
(KJS::regExpProtoFuncExec):
(KJS::regExpProtoFuncCompile):
(KJS::regExpProtoFuncToString):
* kjs/regexp_object.h:
2008-01-16 Cameron Zwarich <cwzwarich@uwaterloo.ca>
Reviewed by Maciej & Darin.
......
......@@ -231,7 +231,7 @@ void JSGlobalObject::reset(JSValue* prototype)
d()->booleanPrototype = new BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
d()->numberPrototype = new NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
d()->datePrototype = new DatePrototype(exec, d()->objectPrototype);
d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);;
d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);
d()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
d()->evalErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
......@@ -311,19 +311,19 @@ void JSGlobalObject::reset(JSValue* prototype)
// Set global functions.
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Eval, 1, "eval"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseInt, 2, "parseInt"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::ParseFloat, 1, "parseFloat"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsNaN, 1, "isNaN"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::IsFinite, 1, "isFinite"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::Escape, 1, "escape"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::UnEscape, 1, "unescape"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURI, 1, "decodeURI"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::DecodeURIComponent, 1, "decodeURIComponent"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURI, 1, "encodeURI"), DontEnum);
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::EncodeURIComponent, 1, "encodeURIComponent"), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "eval", globalFuncEval), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 2, "parseInt", globalFuncParseInt), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "parseFloat", globalFuncParseFloat), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isNaN", globalFuncIsNaN), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "isFinite", globalFuncIsFinite), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "escape", globalFuncEscape), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "unescape", globalFuncUnescape), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURI", globalFuncDecodeURI), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "decodeURIComponent", globalFuncDecodeURIComponent), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURI", globalFuncEncodeURI), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "encodeURIComponent", globalFuncEncodeURIComponent), DontEnum);
#ifndef NDEBUG
putDirectFunction(new GlobalFuncImp(exec, d()->functionPrototype, GlobalFuncImp::KJSPrint, 1, "kjsprint"), DontEnum);
putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, "kjsprint", globalFuncKJSPrint), DontEnum);
#endif
// Set prototype, and also insert the object prototype at the end of the chain.
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2007 Apple Inc. All rights reserved.
* Copyright (C) 2007 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2003 Apple Computer, Inc.
* Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -28,97 +26,92 @@
#include "operations.h"
#include <wtf/Assertions.h>
using namespace KJS;
namespace KJS {
// ------------------------------ BooleanInstance ---------------------------
const ClassInfo BooleanInstance::info = {"Boolean", 0, 0};
const ClassInfo BooleanInstance::info = { "Boolean", 0, 0 };
BooleanInstance::BooleanInstance(JSObject *proto)
: JSWrapperObject(proto)
BooleanInstance::BooleanInstance(JSObject* proto)
: JSWrapperObject(proto)
{
}
// ------------------------------ BooleanPrototype --------------------------
// Functions
static JSValue* booleanProtoFuncToString(ExecState*, JSObject*, const List&);
static JSValue* booleanProtoFuncValueOf(ExecState*, JSObject*, const List&);
// ECMA 15.6.4
BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto, FunctionPrototype* funcProto)
: BooleanInstance(objectProto)
BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
: BooleanInstance(objectPrototype)
{
putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ToString, 0, exec->propertyNames().toString), DontEnum);
putDirectFunction(new BooleanProtoFunc(exec, funcProto, BooleanProtoFunc::ValueOf, 0, exec->propertyNames().valueOf), DontEnum);
setInternalValue(jsBoolean(false));
setInternalValue(jsBoolean(false));
putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
}
// ------------------------------ BooleanProtoFunc --------------------------
// ------------------------------ Functions --------------------------
// ECMA 15.6.4.2 + 15.6.4.3
BooleanProtoFunc::BooleanProtoFunc(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
: InternalFunctionImp(funcProto, name)
, id(i)
JSValue* booleanProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&)
{
putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
}
if (!thisObj->inherits(&BooleanInstance::info))
return throwError(exec, TypeError);
JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue();
ASSERT(v);
// ECMA 15.6.4.2 + 15.6.4.3
JSValue *BooleanProtoFunc::callAsFunction(ExecState* exec, JSObject *thisObj, const List &/*args*/)
return jsString(v->toString(exec));
}
JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const List&)
{
// no generic function. "this" has to be a Boolean object
if (!thisObj->inherits(&BooleanInstance::info))
return throwError(exec, TypeError);
// execute "toString()" or "valueOf()", respectively
if (!thisObj->inherits(&BooleanInstance::info))
return throwError(exec, TypeError);
JSValue *v = static_cast<BooleanInstance*>(thisObj)->internalValue();
ASSERT(v);
JSValue* v = static_cast<BooleanInstance*>(thisObj)->internalValue();
ASSERT(v);
if (id == ToString)
return jsString(v->toString(exec));
return jsBoolean(v->toBoolean(exec)); /* TODO: optimize for bool case */
// TODO: optimize for bool case
return jsBoolean(v->toBoolean(exec));
}
// ------------------------------ BooleanObjectImp -----------------------------
BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* funcProto, BooleanPrototype* booleanProto)
: InternalFunctionImp(funcProto)
BooleanObjectImp::BooleanObjectImp(ExecState* exec, FunctionPrototype* functionPrototype, BooleanPrototype* booleanPrototype)
: InternalFunctionImp(functionPrototype)
{
putDirect(exec->propertyNames().prototype, booleanProto, DontEnum|DontDelete|ReadOnly);
putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
// no. of arguments for constructor
putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
}
bool BooleanObjectImp::implementsConstruct() const
{
return true;
return true;
}
// ECMA 15.6.2
JSObject *BooleanObjectImp::construct(ExecState *exec, const List &args)
JSObject* BooleanObjectImp::construct(ExecState* exec, const List& args)
{
BooleanInstance *obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype()));
bool b;
if (args.size() > 0)
b = args[0]->toBoolean(exec);
else
b = false;
obj->setInternalValue(jsBoolean(b));
return obj;
BooleanInstance* obj(new BooleanInstance(exec->lexicalGlobalObject()->booleanPrototype()));
obj->setInternalValue(jsBoolean(args[0]->toBoolean(exec)));
return obj;
}
// ECMA 15.6.1
JSValue *BooleanObjectImp::callAsFunction(ExecState *exec, JSObject *, const List &args)
JSValue* BooleanObjectImp::callAsFunction(ExecState* exec, JSObject*, const List& args)
{
if (args.isEmpty())
return jsBoolean(false);
else
return jsBoolean(args[0]->toBoolean(exec)); /* TODO: optimize for bool case */
// TODO: optimize for bool case
return jsBoolean(args[0]->toBoolean(exec));
}
} // namespace KJS
// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2008 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -27,61 +26,40 @@
namespace KJS {
class BooleanInstance : public JSWrapperObject {
public:
BooleanInstance(JSObject *proto);
class BooleanInstance : public JSWrapperObject {
public:
BooleanInstance(JSObject* proto);
virtual const ClassInfo *classInfo() const { return &info; }
static const ClassInfo info;
};
virtual const ClassInfo* classInfo() const { return &info; }
static const ClassInfo info;
};
/**
* @internal
*
* The initial value of Boolean.prototype (and thus all objects created
* with the Boolean constructor
*/
class BooleanPrototype : public BooleanInstance {
public:
BooleanPrototype(ExecState *exec,
ObjectPrototype *objectProto,
FunctionPrototype *funcProto);
};
/**
* @internal
*
* The initial value of Boolean.prototype (and thus all objects created
* with the Boolean constructor
*/
class BooleanPrototype : public BooleanInstance {
public:
BooleanPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*);
};
/**
* @internal
*
* Class to implement all methods that are properties of the
* Boolean.prototype object
*/
class BooleanProtoFunc : public InternalFunctionImp {
public:
BooleanProtoFunc(ExecState*, FunctionPrototype*, int i, int len, const Identifier&);
/**
* @internal
*
* The initial value of the the global variable's "Boolean" property
*/
class BooleanObjectImp : public InternalFunctionImp {
public:
BooleanObjectImp(ExecState*, FunctionPrototype*, BooleanPrototype*);
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
virtual bool implementsConstruct() const;
virtual JSObject* construct(ExecState*, const List&);
enum { ToString, ValueOf };
private:
int id;
};
virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
};
/**
* @internal
*
* The initial value of the the global variable's "Boolean" property
*/
class BooleanObjectImp : public InternalFunctionImp {
friend class BooleanProtoFunc;
public:
BooleanObjectImp(ExecState *exec, FunctionPrototype *funcProto,
BooleanPrototype *booleanProto);
} // namespace KJS
virtual bool implementsConstruct() const;
virtual JSObject *construct(ExecState *exec, const List &args);
virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
};
} // namespace
#endif
#endif // BOOL_OBJECT_H_
......@@ -41,25 +41,18 @@ ErrorInstance::ErrorInstance(JSObject* prototype)
// ------------------------------ ErrorPrototype ----------------------------
// ECMA 15.9.4
ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectProto, FunctionPrototype* funcProto)
: JSObject(objectProto)
ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
: JSObject(objectPrototype)
{
// The constructor will be added later in ErrorObjectImp's constructor
put(exec, exec->propertyNames().name, jsString("Error"), DontEnum);
put(exec, exec->propertyNames().message, jsString("Unknown error"), DontEnum);
putDirectFunction(new ErrorProtoFuncToString(exec, funcProto), DontEnum);
}
// ------------------------------ ErrorProtoFunc ----------------------------
ErrorProtoFuncToString::ErrorProtoFuncToString(ExecState* exec, FunctionPrototype* funcProto)
: InternalFunctionImp(funcProto, exec->propertyNames().toString)
{
putDirect(exec->propertyNames().length, jsNumber(0), DontDelete|ReadOnly|DontEnum);
putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
JSValue* ErrorProtoFuncToString::callAsFunction(ExecState* exec, JSObject* thisObj, const List&)
JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const List&)
{
UString s = "Error";
......
......@@ -38,12 +38,7 @@ namespace KJS {
ErrorPrototype(ExecState*, ObjectPrototype*, FunctionPrototype*);
};
class ErrorProtoFuncToString : public InternalFunctionImp {
public:
ErrorProtoFuncToString(ExecState*, FunctionPrototype*);
virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
};
JSValue* errorProtoFuncToString(ExecState*, JSObject*, const List&);
class ErrorObjectImp : public InternalFunctionImp {
public:
......
......@@ -471,15 +471,7 @@ ActivationImp::ActivationData::ActivationData(const ActivationData& old)
{
}
// ------------------------------ GlobalFunc -----------------------------------
GlobalFuncImp::GlobalFuncImp(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
: InternalFunctionImp(funcProto, name)
, id(i)
{
putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
}
// ------------------------------ Global Functions -----------------------------------
static JSValue* encode(ExecState* exec, const List& args, const char* do_not_escape)
{
......@@ -700,159 +692,170 @@ static double parseFloat(const UString& s)
return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
}
JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
{
JSValue* res = jsUndefined();
static const char do_not_escape[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"*+-./@_";
static const char do_not_escape_when_encoding_URI_component[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"!'()*-._~";
static const char do_not_escape_when_encoding_URI[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"!#$&'()*+,-./:;=?@_~";
static const char do_not_unescape_when_decoding_URI[] =
"#$&+,/:;=?@";
switch (id) {
case Eval: { // eval()
JSValue* x = args[0];
if (!x->isString())
JSValue* globalFuncEval(ExecState* exec, JSObject* thisObj, const List& args)
{
JSValue* x = args[0];
if (!x->isString())
return x;
else {
UString s = x->toString(exec);
int sourceId;
int errLine;
UString errMsg;
RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
Debugger* dbg = exec->dynamicGlobalObject()->debugger();
if (dbg) {
bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
if (!cont)
UString s = x->toString(exec);
int sourceId;
int errLine;
UString errMsg;
RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
Debugger* dbg = exec->dynamicGlobalObject()->debugger();
if (dbg) {
bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
if (!cont)
return jsUndefined();
}
}
// no program node means a syntax occurred
if (!evalNode)
return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
// No program node means a syntax occurred
if (!evalNode)
return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject();
bool switchGlobal = thisObj && thisObj != exec->dynamicGlobalObject() && thisObj->isGlobalObject();
// enter a new execution context
exec->dynamicGlobalObject()->tearOffActivation(exec);
JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
ExecState newExec(globalObject, evalNode.get(), exec);
if (switchGlobal) {
newExec.pushScope(thisObj);
newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj));
}
JSValue* value = evalNode->execute(&newExec);
if (switchGlobal)
newExec.popScope();
// enter a new execution context
exec->dynamicGlobalObject()->tearOffActivation(exec);
JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
ExecState newExec(globalObject, evalNode.get(), exec);
if (newExec.completionType() == Throw) {
exec->setException(value);
return value;
}
return value ? value : jsUndefined();
}
if (switchGlobal) {
newExec.pushScope(thisObj);
newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj));
}
case ParseInt:
res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
break;
case ParseFloat:
res = jsNumber(parseFloat(args[0]->toString(exec)));
break;
case IsNaN:
res = jsBoolean(isnan(args[0]->toNumber(exec)));
break;
case IsFinite: {
JSValue* value = evalNode->execute(&newExec);
if (switchGlobal)
newExec.popScope();
if (newExec.completionType() == Throw) {
exec->setException(value);
return value;
}
return value ? value : jsUndefined();
}
JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const List& args)
{
return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
}
JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const List& args)
{
return jsNumber(parseFloat(args[0]->toString(exec)));
}
JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const List& args)
{
return jsBoolean(isnan(args[0]->toNumber(exec)));
}
JSValue* globalFuncIsFinite(ExecState* exec, JSObject*, const List& args)
{
double n = args[0]->toNumber(exec);
res = jsBoolean(!isnan(n) && !isinf(n));
break;
}
case DecodeURI:
res = decode(exec, args, do_not_unescape_when_decoding_URI, true);
break;
case DecodeURIComponent:
res = decode(exec, args, "", true);