#include "JSBase.h"
#include "APICast.h"
+#include "completion.h"
#include <kjs/ExecState.h>
#include <kjs/InitializeThreading.h>
#include <kjs/interpreter.h>
if (!ctx)
initializeThreading();
+ // It might seem that we have a context passed to this function, and can use toJS(ctx)->heap(), but the parameter is likely to be NULL,
+ // and it may actually be garbage for some clients (most likely, because of JSGarbageCollect being called after releasing the context).
+
JSLock lock;
- if (!Collector::isBusy())
- Collector::collect();
+
+ // FIXME: It would be good to avoid creating a JSGlobalData instance if it didn't exist for this thread yet.
+ Heap* heap = JSGlobalData::threadInstance().heap;
+ if (!heap->isBusy())
+ heap->collect();
+
+ // FIXME: Similarly, we shouldn't create a shared instance here.
+ heap = JSGlobalData::sharedInstance().heap;
+ if (!heap->isBusy())
+ heap->collect();
+
// FIXME: Perhaps we should trigger a second mark and sweep
// once the garbage collector is done if this is called when
// the collector is busy.
if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
- JSObject* o = new JSCallbackFunction(exec, callAsFunction, propertyName);
+ JSObject* o = new (exec) JSCallbackFunction(exec, callAsFunction, propertyName);
thisObj->putDirect(propertyName, o, entry->attributes);
return o;
}
parentPrototype = parentClass->prototype(ctx); // can be null
if (!parentPrototype)
parentPrototype = exec->dynamicGlobalObject()->objectPrototype();
- cachedPrototype = new JSCallbackObject<JSObject>(exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction
+ cachedPrototype = new (exec) JSCallbackObject<JSObject>(exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction
}
return cachedPrototype;
}
JSLock lock;
if (!globalObjectClass) {
- JSGlobalObject* globalObject = new JSGlobalObject;
+ JSGlobalObject* globalObject = new (JSGlobalObject::Shared) JSGlobalObject;
return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
}
- JSGlobalObject* globalObject = new JSCallbackObject<JSGlobalObject>(globalObjectClass);
+ JSGlobalObject* globalObject = new (JSGlobalObject::Shared) JSCallbackObject<JSGlobalObject>(globalObjectClass);
JSGlobalContextRef ctx = toGlobalRef(globalObject->globalExec());
JSValue* prototype = globalObjectClass->prototype(ctx);
if (!prototype)
ExecState* exec = toJS(ctx);
if (!jsClass)
- return toRef(new JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
+ return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
JSValue* jsPrototype = jsClass->prototype(ctx);
if (!jsPrototype)
jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
- return toRef(new JSCallbackObject<JSObject>(exec, jsClass, jsPrototype, data));
+ return toRef(new (exec) JSCallbackObject<JSObject>(exec, jsClass, jsPrototype, data));
}
JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
ExecState* exec = toJS(ctx);
Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
- return toRef(new JSCallbackFunction(exec, callAsFunction, nameID));
+ return toRef(new (exec) JSCallbackFunction(exec, callAsFunction, nameID));
}
JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
? jsClass->prototype(ctx)
: exec->dynamicGlobalObject()->objectPrototype();
- JSCallbackConstructor* constructor = new JSCallbackConstructor(exec, jsClass, callAsConstructor);
+ JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec, jsClass, callAsConstructor);
constructor->putDirect(exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
return toRef(constructor);
}
ArgList args;
for (unsigned i = 0; i < parameterCount; i++)
- args.append(jsString(UString(toJS(parameterNames[i]))));
- args.append(jsString(UString(bodyRep)));
+ args.append(jsString(exec, UString(toJS(parameterNames[i]))));
+ args.append(jsString(exec, UString(bodyRep)));
JSObject* result = exec->dynamicGlobalObject()->functionConstructor()->construct(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
if (exec->hadException()) {
return toRef(jsBoolean(value));
}
-JSValueRef JSValueMakeNumber(JSContextRef, double value)
+JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
{
JSLock lock;
- return toRef(jsNumber(value));
+ return toRef(jsNumber(toJS(ctx), value));
}
-JSValueRef JSValueMakeString(JSContextRef, JSStringRef string)
+JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
{
JSLock lock;
UString::Rep* rep = toJS(string);
- return toRef(jsString(UString(rep)));
+ return toRef(jsString(toJS(ctx), UString(rep)));
}
bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
+2008-06-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin.
+
+ Prepare JavaScript heap for being per-thread.
+
+ * kjs/ExecState.h: Shuffle includes, making it possible to include ExecState.h in JSValue.h.
+ (KJS::ExecState::heap): Added an accessor.
+
+ * API/JSBase.cpp: (JSGarbageCollect): Collect both shared and per-thread heaps.
+
+ * API/JSContextRef.cpp: (JSGlobalContextCreate): When allocating JSGlobalObject, indicate
+ that it belongs to a shared heap.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * kjs/AllInOneFile.cpp:
+ Moved JSGlobalObject.cpp to AllInOneFile, as a build fix for inlineAllocate magic.
+
+ * VM/CodeGenerator.h: (KJS::CodeGenerator::globalExec): Added an accessor (working via
+ m_scopeChain).
+
+ * VM/RegisterFile.h:
+ (KJS::RegisterFile::mark):
+ * VM/RegisterFileStack.h:
+ (KJS::RegisterFileStack::mark):
+ Made these pseudo-mark functions take Heap*.
+
+ * kjs/InitializeThreading.cpp:
+ (KJS::initializeThreading): Initialize heap introspector.
+
+ * kjs/JSGlobalData.h: Added Heap to the structure.
+
+ * kjs/JSGlobalData.cpp:
+ (KJS::JSGlobalData::JSGlobalData): Initialize Heap.
+ (KJS::JSGlobalData::sharedInstance): Added a method to access shared global data instance
+ for legacy clients.
+
+ * kjs/JSGlobalObject.cpp:
+ (KJS::JSGlobalObject::~JSGlobalObject): Changed to work with per-thread head; fixed list
+ maintenance logic.
+ (KJS::JSGlobalObject::init): Changed to work with per-thread head.
+ (KJS::JSGlobalObject::put): Assert that a cross-heap operation is not being attempted.
+ (KJS::JSGlobalObject::reset): Pass ExecState* where now required.
+ (KJS::JSGlobalObject::mark): Pass the current heap to RegisterFileStack::mark.
+ (KJS::JSGlobalObject::operator new): Overload operator new to use per-thread or shared heap.
+ * kjs/JSGlobalObject.h: Removed static s_head member.
+
+ * kjs/PropertyMap.h: (KJS::PropertyMap::PropertyMap): Removed unused SavedProperty.
+
+ * kjs/collector.h: Turned Collector into an actual object with its own data, renamed to Heap.
+ (KJS::Heap::initializeHeapIntrospector): Added.
+ (KJS::Heap::heap): Added a method to determine which heap a JSValue is in, if any.
+ (KJS::Heap::allocate): Made non-static.
+ (KJS::Heap::inlineAllocateNumber): Ditto.
+ (KJS::Heap::markListSet): Ditto.
+ (KJS::Heap::cellBlock): Ditto.
+ (KJS::Heap::cellOffset): Ditto.
+ (KJS::Heap::isCellMarked): Ditto.
+ (KJS::Heap::markCell): Ditto.
+ (KJS::Heap::reportExtraMemoryCost): Ditto.
+ (KJS::CollectorBlock): Added a back-reference to Heap for Heap::heap() method.
+ (KJS::SmallCellCollectorBlock): Ditto.
+
+ * kjs/collector.cpp: Changed MIN_ARRAY_SIZE to a #define to avoid a PIC branch. Removed
+ main thread related machinery.
+ (KJS::Heap::Heap): Initialize the newly added data members.
+ (KJS::allocateBlock): Marked NEVER_INLINE, as this is a rare case that uses a PIC branch.
+ Moved static pagesize to the class to make it safely initialized.
+ (KJS::Heap::heapAllocate): Initialize heap back reference after a new block is allocated.
+ (KJS::Heap::registerThread): Removed introspector initialization, as it is now performed
+ in InitializeThreading.cpp.
+ (KJS::Heap::markOtherThreadConservatively): Assert that the "other thread" case only occurs
+ for legacy clients using a shared heap.
+ (KJS::Heap::markStackObjectsConservatively): Moved fastMallocForbid/Allow down here, since
+ it doesn't need to be forbidden during other GC phases.
+
+ * kjs/JSImmediate.h:
+ (KJS::jsUndefined):
+ (KJS::jsNull):
+ (KJS::jsBoolean):
+ Moved from JSvalue.h, to make these usable in files that cannot include JSValue.h (such
+ as list.h).
+
+ * API/JSCallbackObjectFunctions.h:
+ (KJS::::staticFunctionGetter):
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::prototype):
+ * API/JSObjectRef.cpp:
+ (JSObjectMake):
+ (JSObjectMakeFunctionWithCallback):
+ (JSObjectMakeConstructor):
+ (JSObjectMakeFunction):
+ * API/JSValueRef.cpp:
+ (JSValueMakeNumber):
+ (JSValueMakeString):
+ * JavaScriptCore.exp:
+ * VM/CodeGenerator.cpp:
+ (KJS::CodeGenerator::emitLoad):
+ * VM/JSPropertyNameIterator.cpp:
+ (KJS::JSPropertyNameIterator::create):
+ (KJS::JSPropertyNameIterator::next):
+ * VM/Machine.cpp:
+ (KJS::jsAddSlowCase):
+ (KJS::jsAdd):
+ (KJS::jsTypeStringForValue):
+ (KJS::scopeChainForCall):
+ (KJS::Machine::throwException):
+ (KJS::Machine::execute):
+ (KJS::Machine::privateExecute):
+ (KJS::Machine::retrieveArguments):
+ * kjs/ArrayPrototype.cpp:
+ (KJS::arrayProtoFuncToString):
+ (KJS::arrayProtoFuncToLocaleString):
+ (KJS::arrayProtoFuncJoin):
+ (KJS::arrayProtoFuncConcat):
+ (KJS::arrayProtoFuncPop):
+ (KJS::arrayProtoFuncPush):
+ (KJS::arrayProtoFuncShift):
+ (KJS::arrayProtoFuncSlice):
+ (KJS::arrayProtoFuncSplice):
+ (KJS::arrayProtoFuncUnShift):
+ (KJS::arrayProtoFuncFilter):
+ (KJS::arrayProtoFuncMap):
+ (KJS::arrayProtoFuncEvery):
+ (KJS::arrayProtoFuncForEach):
+ (KJS::arrayProtoFuncSome):
+ (KJS::arrayProtoFuncIndexOf):
+ (KJS::arrayProtoFuncLastIndexOf):
+ (KJS::ArrayConstructor::ArrayConstructor):
+ (KJS::ArrayConstructor::construct):
+ (KJS::ArrayConstructor::callAsFunction):
+ * kjs/BooleanObject.cpp:
+ (KJS::BooleanPrototype::BooleanPrototype):
+ (KJS::booleanProtoFuncToString):
+ (KJS::BooleanConstructor::BooleanConstructor):
+ (KJS::BooleanConstructor::construct):
+ * kjs/FunctionPrototype.cpp:
+ (KJS::FunctionPrototype::FunctionPrototype):
+ (KJS::functionProtoFuncToString):
+ (KJS::FunctionConstructor::FunctionConstructor):
+ (KJS::FunctionConstructor::construct):
+ * kjs/JSActivation.cpp:
+ (KJS::JSActivation::createArgumentsObject):
+ * kjs/JSArray.cpp:
+ (KJS::JSArray::JSArray):
+ (KJS::JSArray::lengthGetter):
+ * kjs/JSFunction.cpp:
+ (KJS::JSFunction::lengthGetter):
+ (KJS::JSFunction::construct):
+ (KJS::Arguments::Arguments):
+ (KJS::encode):
+ (KJS::decode):
+ (KJS::globalFuncParseInt):
+ (KJS::globalFuncParseFloat):
+ (KJS::globalFuncEscape):
+ (KJS::globalFuncUnescape):
+ (KJS::PrototypeFunction::PrototypeFunction):
+ (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
+ * kjs/JSImmediate.cpp:
+ (KJS::JSImmediate::toObject):
+ * kjs/JSLock.cpp:
+ (KJS::JSLock::registerThread):
+ * kjs/JSObject.cpp:
+ (KJS::JSObject::put):
+ (KJS::JSObject::defineGetter):
+ (KJS::JSObject::defineSetter):
+ (KJS::Error::create):
+ * kjs/JSObject.h:
+ (KJS::JSObject::putDirect):
+ * kjs/JSString.h:
+ (KJS::JSString::JSString):
+ * kjs/JSValue.cpp:
+ (KJS::JSCell::operator new):
+ (KJS::jsString):
+ (KJS::jsOwnedString):
+ * kjs/JSValue.h:
+ (KJS::JSNumberCell::operator new):
+ (KJS::jsNumberCell):
+ (KJS::jsNaN):
+ (KJS::jsNumber):
+ (KJS::JSCell::marked):
+ (KJS::JSCell::mark):
+ (KJS::JSValue::toJSNumber):
+ * kjs/MathObject.cpp:
+ (KJS::MathObject::getValueProperty):
+ (KJS::mathProtoFuncAbs):
+ (KJS::mathProtoFuncACos):
+ (KJS::mathProtoFuncASin):
+ (KJS::mathProtoFuncATan):
+ (KJS::mathProtoFuncATan2):
+ (KJS::mathProtoFuncCeil):
+ (KJS::mathProtoFuncCos):
+ (KJS::mathProtoFuncExp):
+ (KJS::mathProtoFuncFloor):
+ (KJS::mathProtoFuncLog):
+ (KJS::mathProtoFuncMax):
+ (KJS::mathProtoFuncMin):
+ (KJS::mathProtoFuncPow):
+ (KJS::mathProtoFuncRandom):
+ (KJS::mathProtoFuncRound):
+ (KJS::mathProtoFuncSin):
+ (KJS::mathProtoFuncSqrt):
+ (KJS::mathProtoFuncTan):
+ * kjs/NumberObject.cpp:
+ (KJS::NumberPrototype::NumberPrototype):
+ (KJS::numberProtoFuncToString):
+ (KJS::numberProtoFuncToLocaleString):
+ (KJS::numberProtoFuncToFixed):
+ (KJS::numberProtoFuncToExponential):
+ (KJS::numberProtoFuncToPrecision):
+ (KJS::NumberConstructor::NumberConstructor):
+ (KJS::NumberConstructor::getValueProperty):
+ (KJS::NumberConstructor::construct):
+ (KJS::NumberConstructor::callAsFunction):
+ * kjs/RegExpObject.cpp:
+ (KJS::RegExpPrototype::RegExpPrototype):
+ (KJS::regExpProtoFuncToString):
+ (KJS::RegExpObject::getValueProperty):
+ (KJS::RegExpConstructor::RegExpConstructor):
+ (KJS::RegExpMatchesArray::fillArrayInstance):
+ (KJS::RegExpConstructor::arrayOfMatches):
+ (KJS::RegExpConstructor::getBackref):
+ (KJS::RegExpConstructor::getLastParen):
+ (KJS::RegExpConstructor::getLeftContext):
+ (KJS::RegExpConstructor::getRightContext):
+ (KJS::RegExpConstructor::getValueProperty):
+ (KJS::RegExpConstructor::construct):
+ * kjs/RegExpObject.h:
+ * kjs/Shell.cpp:
+ (GlobalObject::GlobalObject):
+ (functionGC):
+ (functionRun):
+ (functionReadline):
+ (jscmain):
+ * kjs/date_object.cpp:
+ (KJS::formatLocaleDate):
+ (KJS::DatePrototype::DatePrototype):
+ (KJS::DateConstructor::DateConstructor):
+ (KJS::DateConstructor::construct):
+ (KJS::DateConstructor::callAsFunction):
+ (KJS::DateFunction::DateFunction):
+ (KJS::DateFunction::callAsFunction):
+ (KJS::dateProtoFuncToString):
+ (KJS::dateProtoFuncToUTCString):
+ (KJS::dateProtoFuncToDateString):
+ (KJS::dateProtoFuncToTimeString):
+ (KJS::dateProtoFuncToLocaleString):
+ (KJS::dateProtoFuncToLocaleDateString):
+ (KJS::dateProtoFuncToLocaleTimeString):
+ (KJS::dateProtoFuncValueOf):
+ (KJS::dateProtoFuncGetTime):
+ (KJS::dateProtoFuncGetFullYear):
+ (KJS::dateProtoFuncGetUTCFullYear):
+ (KJS::dateProtoFuncToGMTString):
+ (KJS::dateProtoFuncGetMonth):
+ (KJS::dateProtoFuncGetUTCMonth):
+ (KJS::dateProtoFuncGetDate):
+ (KJS::dateProtoFuncGetUTCDate):
+ (KJS::dateProtoFuncGetDay):
+ (KJS::dateProtoFuncGetUTCDay):
+ (KJS::dateProtoFuncGetHours):
+ (KJS::dateProtoFuncGetUTCHours):
+ (KJS::dateProtoFuncGetMinutes):
+ (KJS::dateProtoFuncGetUTCMinutes):
+ (KJS::dateProtoFuncGetSeconds):
+ (KJS::dateProtoFuncGetUTCSeconds):
+ (KJS::dateProtoFuncGetMilliSeconds):
+ (KJS::dateProtoFuncGetUTCMilliseconds):
+ (KJS::dateProtoFuncGetTimezoneOffset):
+ (KJS::dateProtoFuncSetTime):
+ (KJS::setNewValueFromTimeArgs):
+ (KJS::setNewValueFromDateArgs):
+ (KJS::dateProtoFuncSetYear):
+ (KJS::dateProtoFuncGetYear):
+ * kjs/error_object.cpp:
+ (KJS::ErrorPrototype::ErrorPrototype):
+ (KJS::errorProtoFuncToString):
+ (KJS::ErrorConstructor::ErrorConstructor):
+ (KJS::ErrorConstructor::construct):
+ (KJS::NativeErrorPrototype::NativeErrorPrototype):
+ (KJS::NativeErrorConstructor::NativeErrorConstructor):
+ (KJS::NativeErrorConstructor::construct):
+ * kjs/identifier.h:
+ * kjs/internal.cpp:
+ (KJS::StringObject::create):
+ (KJS::JSString::lengthGetter):
+ (KJS::JSString::indexGetter):
+ (KJS::JSString::indexNumericPropertyGetter):
+ * kjs/interpreter.cpp:
+ * kjs/list.cpp:
+ (KJS::ArgList::slowAppend):
+ * kjs/list.h:
+ * kjs/lookup.h:
+ (KJS::staticFunctionGetter):
+ (KJS::cacheGlobalObject):
+ * kjs/nodes.cpp:
+ (KJS::Node::emitThrowError):
+ (KJS::StringNode::emitCode):
+ (KJS::ArrayNode::emitCode):
+ (KJS::FuncDeclNode::makeFunction):
+ (KJS::FuncExprNode::makeFunction):
+ * kjs/nodes.h:
+ * kjs/object_object.cpp:
+ (KJS::ObjectPrototype::ObjectPrototype):
+ (KJS::objectProtoFuncToLocaleString):
+ (KJS::objectProtoFuncToString):
+ (KJS::ObjectConstructor::ObjectConstructor):
+ (KJS::ObjectConstructor::construct):
+ * kjs/protect.h:
+ (KJS::gcProtect):
+ (KJS::gcUnprotect):
+ * kjs/string_object.cpp:
+ (KJS::StringObject::StringObject):
+ (KJS::StringPrototype::StringPrototype):
+ (KJS::replace):
+ (KJS::stringProtoFuncCharAt):
+ (KJS::stringProtoFuncCharCodeAt):
+ (KJS::stringProtoFuncConcat):
+ (KJS::stringProtoFuncIndexOf):
+ (KJS::stringProtoFuncLastIndexOf):
+ (KJS::stringProtoFuncMatch):
+ (KJS::stringProtoFuncSearch):
+ (KJS::stringProtoFuncReplace):
+ (KJS::stringProtoFuncSlice):
+ (KJS::stringProtoFuncSplit):
+ (KJS::stringProtoFuncSubstr):
+ (KJS::stringProtoFuncSubstring):
+ (KJS::stringProtoFuncToLowerCase):
+ (KJS::stringProtoFuncToUpperCase):
+ (KJS::stringProtoFuncToLocaleLowerCase):
+ (KJS::stringProtoFuncToLocaleUpperCase):
+ (KJS::stringProtoFuncLocaleCompare):
+ (KJS::stringProtoFuncBig):
+ (KJS::stringProtoFuncSmall):
+ (KJS::stringProtoFuncBlink):
+ (KJS::stringProtoFuncBold):
+ (KJS::stringProtoFuncFixed):
+ (KJS::stringProtoFuncItalics):
+ (KJS::stringProtoFuncStrike):
+ (KJS::stringProtoFuncSub):
+ (KJS::stringProtoFuncSup):
+ (KJS::stringProtoFuncFontcolor):
+ (KJS::stringProtoFuncFontsize):
+ (KJS::stringProtoFuncAnchor):
+ (KJS::stringProtoFuncLink):
+ (KJS::StringConstructor::StringConstructor):
+ (KJS::StringConstructor::construct):
+ (KJS::StringConstructor::callAsFunction):
+ (KJS::StringConstructorFunction::StringConstructorFunction):
+ (KJS::StringConstructorFunction::callAsFunction):
+ * kjs/string_object.h:
+ (KJS::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
+ * kjs/ustring.h:
+ Updated for the above changes.
+
2008-06-17 Timothy Hatcher <timothy@apple.com>
Added a type to DebuggerCallFrame so the under interface can
__ZN3KJS11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjb
__ZN3KJS11PropertyMapD1Ev
__ZN3KJS12DateInstance4infoE
+__ZN3KJS12JSGlobalData14sharedInstanceEv
__ZN3KJS12JSGlobalData14threadInstanceEv
__ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
__ZN3KJS12RegisterFile14addGlobalSlotsEm
__ZN3KJS12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
__ZN3KJS12StringObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS12StringObject4infoE
-__ZN3KJS12StringObjectC2EPNS_8JSObjectERKNS_7UStringE
+__ZN3KJS12StringObjectC2EPNS_9ExecStateEPNS_8JSObjectERKNS_7UStringE
__ZN3KJS13CodeGenerator21setDumpsGeneratedCodeEb
__ZN3KJS13StatementNode6setLocEii
-__ZN3KJS13jsOwnedStringERKNS_7UStringE
+__ZN3KJS13jsOwnedStringEPNS_9ExecStateERKNS_7UStringE
__ZN3KJS14JSGlobalObject10globalExecEv
__ZN3KJS14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3KJS14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
__ZN3KJS14JSGlobalObject4initEPNS_8JSObjectE
__ZN3KJS14JSGlobalObject4markEv
__ZN3KJS14JSGlobalObjectD2Ev
+__ZN3KJS14JSGlobalObjectnwEm
+__ZN3KJS14JSGlobalObjectnwEmNS0_9SharedTagE
__ZN3KJS15JSWrapperObject4markEv
__ZN3KJS16InternalFunction11getCallDataERNS_8CallDataE
__ZN3KJS16InternalFunction4infoE
__ZN3KJS17RegisterFileStack20allocateRegisterFileEmPS0_
__ZN3KJS19initializeThreadingEv
__ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3KJS4Heap14allocateNumberEm
+__ZN3KJS4Heap15recordExtraCostEm
+__ZN3KJS4Heap17globalObjectCountEv
+__ZN3KJS4Heap20protectedObjectCountEv
+__ZN3KJS4Heap23collectOnMainThreadOnlyEPNS_7JSValueE
+__ZN3KJS4Heap25protectedObjectTypeCountsEv
+__ZN3KJS4Heap26protectedGlobalObjectCountEv
+__ZN3KJS4Heap4heapEPKNS_7JSValueE
+__ZN3KJS4Heap4sizeEv
+__ZN3KJS4Heap7collectEv
+__ZN3KJS4Heap7protectEPNS_7JSValueE
+__ZN3KJS4Heap8allocateEm
+__ZN3KJS4Heap9unprotectEPNS_7JSValueE
__ZN3KJS5equalEPKNS_7UString3RepES3_
__ZN3KJS6JSCell11getCallDataERNS_8CallDataE
__ZN3KJS6JSCell16getConstructDataERNS_13ConstructDataE
__ZN3KJS6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
__ZN3KJS6JSCell3putEPNS_9ExecStateEjPNS_7JSValueE
__ZN3KJS6JSCell9getObjectEv
-__ZN3KJS6JSCellnwEm
+__ZN3KJS6JSCellnwEmPNS_9ExecStateE
__ZN3KJS6JSLock12DropAllLocksC1Ev
__ZN3KJS6JSLock12DropAllLocksD1Ev
__ZN3KJS6JSLock14registerThreadEv
__ZN3KJS8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3KJS8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
__ZN3KJS8Profiler8profilerEv
-__ZN3KJS8jsStringEPKc
-__ZN3KJS8jsStringERKNS_7UStringE
-__ZN3KJS9Collector14allocateNumberEm
-__ZN3KJS9Collector15recordExtraCostEm
-__ZN3KJS9Collector17globalObjectCountEv
-__ZN3KJS9Collector20protectedObjectCountEv
-__ZN3KJS9Collector23collectOnMainThreadOnlyEPNS_7JSValueE
-__ZN3KJS9Collector25protectedObjectTypeCountsEv
-__ZN3KJS9Collector26protectedGlobalObjectCountEv
-__ZN3KJS9Collector4sizeEv
-__ZN3KJS9Collector7collectEv
-__ZN3KJS9Collector7protectEPNS_7JSValueE
-__ZN3KJS9Collector9unprotectEPNS_7JSValueE
+__ZN3KJS8jsStringEPNS_9ExecStateEPKc
+__ZN3KJS8jsStringEPNS_9ExecStateERKNS_7UStringE
__ZN3KJSeqERKNS_7UStringEPKc
__ZN3KJSgtERKNS_7UStringES2_
__ZN3KJSltERKNS_7UStringES2_
__ZNK3KJS16InternalFunction21implementsHasInstanceEv
__ZNK3KJS16JSVariableObject16isVariableObjectEv
__ZNK3KJS16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
-__ZNK3KJS17DebuggerCallFrame4typeEv
__ZNK3KJS17DebuggerCallFrame10thisObjectEv
__ZNK3KJS17DebuggerCallFrame12functionNameEv
+__ZNK3KJS17DebuggerCallFrame4typeEv
__ZNK3KJS17DebuggerCallFrame8evaluateERKNS_7UStringERPNS_7JSValueE
__ZNK3KJS4Node8toStringEv
__ZNK3KJS6JSCell12toThisObjectEPNS_9ExecStateE
14D797800DAC3307001A9F05 /* RegisterFileStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D7977E0DAC3307001A9F05 /* RegisterFileStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
14D797810DAC3307001A9F05 /* RegisterFileStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D7977F0DAC3307001A9F05 /* RegisterFileStack.cpp */; };
14DA81900D99FD2000B0A4FB /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; };
- 14DE0D690D02431400AACCA2 /* JSGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */; };
14E0FF120DBAAED00007C0AB /* Machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B15E70D81F986009CB8C7 /* Machine.cpp */; settings = {COMPILER_FLAGS = "-fno-tree-pre"; }; };
14F252570D08DD8D004ECFFF /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
14F252610D08DF2F004ECFFF /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F252600D08DF2F004ECFFF /* JSVariableObject.cpp */; };
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
- 14DE0D690D02431400AACCA2 /* JSGlobalObject.cpp in Sources */,
1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
{
emitOpcode(op_load);
instructions().append(dst->index());
- instructions().append(addConstant(jsNumber(d)));
+ instructions().append(addConstant(jsNumber(globalExec(), d)));
return dst;
}
CodeType codeType() const { return m_codeType; }
+ ExecState* globalExec() { return m_scopeChain->globalObject()->globalExec(); }
+
private:
void emitOpcode(OpcodeID);
void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
{
if (v->isUndefinedOrNull())
- return new JSPropertyNameIterator(0, 0, 0);
+ return new (exec) JSPropertyNameIterator(0, 0, 0);
JSObject* o = v->toObject(exec);
PropertyNameArray propertyNames(exec);
o->getPropertyNames(exec, propertyNames);
size_t numProperties = propertyNames.size();
- return new JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties);
+ return new (exec) JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties);
}
JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties)
{
while (m_position != m_end) {
if (m_object->hasProperty(exec, *m_position))
- return jsOwnedString((*m_position++).ustring());;
+ return jsOwnedString(exec, (*m_position++).ustring());;
m_position++;
}
invalidate();
UString value = p1->toString(exec) + p2->toString(exec);
if (value.isNull())
return throwOutOfMemoryError(exec);
- return jsString(value);
+ return jsString(exec, value);
}
- return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
+ return jsNumber(exec, p1->toNumber(exec) + p2->toNumber(exec));
}
// Fast-path choices here are based on frequency data from SunSpider:
const unsigned bothTypes = (t1 << 3) | t2;
if (bothTypes == ((NumberType << 3) | NumberType))
- return jsNumber(v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
+ return jsNumber(exec, v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
if (bothTypes == ((StringType << 3) | StringType)) {
UString value = static_cast<JSString*>(v1)->value() + static_cast<JSString*>(v2)->value();
if (value.isNull())
return throwOutOfMemoryError(exec);
- return jsString(value);
+ return jsString(exec, value);
}
// All other cases are pretty uncommon
return jsAddSlowCase(exec, v1, v2);
}
-static JSValue* jsTypeStringForValue(JSValue* v)
+static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
{
switch (v->type()) {
case UndefinedType:
- return jsString("undefined");
+ return jsString(exec, "undefined");
case NullType:
- return jsString("object");
+ return jsString(exec, "object");
case BooleanType:
- return jsString("boolean");
+ return jsString(exec, "boolean");
case NumberType:
- return jsString("number");
+ return jsString(exec, "number");
case StringType:
- return jsString("string");
+ return jsString(exec, "string");
default:
if (v->isObject()) {
// Return "undefined" for objects that should be treated
// as null when doing comparisons.
if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
- return jsString("undefined");
+ return jsString(exec, "undefined");
else if (static_cast<JSObject*>(v)->implementsCall())
- return jsString("function");
+ return jsString(exec, "function");
}
- return jsString("object");
+ return jsString(exec, "object");
}
}
return r;
}
-ALWAYS_INLINE ScopeChainNode* scopeChainForCall(FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register** registerBase, Register* r)
+ALWAYS_INLINE ScopeChainNode* scopeChainForCall(ExecState* exec, FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register** registerBase, Register* r)
{
if (newCodeBlock->needsFullScopeChain) {
- JSActivation* activation = new JSActivation(functionBodyNode, registerBase, r - (*registerBase));
+ JSActivation* activation = new (exec) JSActivation(functionBodyNode, registerBase, r - (*registerBase));
r[Machine::OptionalCalleeActivation - Machine::CallFrameHeaderSize - newCodeBlock->numLocals].u.jsValue = activation;
return callDataScopeChain->copy()->push(activation);
if (exceptionValue->isObject()) {
JSObject* exception = static_cast<JSObject*>(exceptionValue);
if (!exception->hasProperty(exec, Identifier(exec, "line")) && !exception->hasProperty(exec, Identifier(exec, "sourceURL"))) {
- exception->put(exec, Identifier(exec, "line"), jsNumber(codeBlock->lineNumberForVPC(vPC)));
- exception->put(exec, Identifier(exec, "sourceURL"), jsOwnedString(codeBlock->ownerNode->sourceURL()));
+ exception->put(exec, Identifier(exec, "line"), jsNumber(exec, codeBlock->lineNumberForVPC(vPC)));
+ exception->put(exec, Identifier(exec, "sourceURL"), jsOwnedString(exec, codeBlock->ownerNode->sourceURL()));
}
}
return 0;
}
- scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r);
+ scopeChain = scopeChainForCall(exec, functionBodyNode, newCodeBlock, scopeChain, registerBase, r);
ExecState newExec(exec, this, registerFile, scopeChain, callFrameOffset);
*/
int dst = (++vPC)->u.operand;
int regExp = (++vPC)->u.operand;
- r[dst].u.jsValue = new RegExpObject(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
+ r[dst].u.jsValue = new (exec) RegExpObject(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
++vPC;
NEXT_OPCODE;
if (JSImmediate::canDoFastAdditiveOperations(v))
result = JSImmediate::incImmediateNumber(v);
else
- result = jsNumber(v->toNumber(exec) + 1);
+ result = jsNumber(exec, v->toNumber(exec) + 1);
VM_CHECK_EXCEPTION();
r[srcDst].u.jsValue = result;
if (JSImmediate::canDoFastAdditiveOperations(v))
result = JSImmediate::decImmediateNumber(v);
else
- result = jsNumber(v->toNumber(exec) - 1);
+ result = jsNumber(exec, v->toNumber(exec) - 1);
VM_CHECK_EXCEPTION();
r[srcDst].u.jsValue = result;
result = JSImmediate::incImmediateNumber(v);
} else {
number = r[srcDst].u.jsValue->toJSNumber(exec);
- result = jsNumber(number->uncheckedGetNumber() + 1);
+ result = jsNumber(exec, number->uncheckedGetNumber() + 1);
}
VM_CHECK_EXCEPTION();
result = JSImmediate::decImmediateNumber(v);
} else {
number = r[srcDst].u.jsValue->toJSNumber(exec);
- result = jsNumber(number->uncheckedGetNumber() - 1);
+ result = jsNumber(exec, number->uncheckedGetNumber() - 1);
}
VM_CHECK_EXCEPTION();
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- JSValue* result = jsNumber(-r[src].u.jsValue->toNumber(exec));
+ JSValue* result = jsNumber(exec, -r[src].u.jsValue->toNumber(exec));
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = result;
JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
- JSValue* result = jsNumber(src1->toNumber(exec) * src2->toNumber(exec));
+ JSValue* result = jsNumber(exec, src1->toNumber(exec) * src2->toNumber(exec));
VM_CHECK_EXCEPTION();
dst = result;
int dst = (++vPC)->u.operand;
int dividend = (++vPC)->u.operand;
int divisor = (++vPC)->u.operand;
- JSValue* result = jsNumber(r[dividend].u.jsValue->toNumber(exec) / r[divisor].u.jsValue->toNumber(exec));
+ JSValue* result = jsNumber(exec, r[dividend].u.jsValue->toNumber(exec) / r[divisor].u.jsValue->toNumber(exec));
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = result;
++vPC;
int dividend = (++vPC)->u.operand;
int divisor = (++vPC)->u.operand;
double d = r[dividend].u.jsValue->toNumber(exec);
- JSValue* result = jsNumber(fmod(d, r[divisor].u.jsValue->toNumber(exec)));
+ JSValue* result = jsNumber(exec, fmod(d, r[divisor].u.jsValue->toNumber(exec)));
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = result;
++vPC;
if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
result = JSImmediate::subImmediateNumbers(src1, src2);
else {
- result = jsNumber(src1->toNumber(exec) - src2->toNumber(exec));
+ result = jsNumber(exec, src1->toNumber(exec) - src2->toNumber(exec));
VM_CHECK_EXCEPTION();
}
dst = result;
JSValue* shift = r[(++vPC)->u.operand].u.jsValue;
JSValue* result;
if (JSImmediate::areBothImmediateNumbers(val, shift))
- result = jsNumber(JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
+ result = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
else {
- result = jsNumber((val->toInt32(exec)) << (shift->toUInt32(exec) & 0x1f));
+ result = jsNumber(exec, (val->toInt32(exec)) << (shift->toUInt32(exec) & 0x1f));
VM_CHECK_EXCEPTION();
}
dst = result;
if (JSImmediate::areBothImmediateNumbers(val, shift))
result = JSImmediate::rightShiftImmediateNumbers(val, shift);
else {
- result = jsNumber((val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
+ result = jsNumber(exec, (val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
VM_CHECK_EXCEPTION();
}
dst = result;
if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
result = JSImmediate::rightShiftImmediateNumbers(val, shift);
else {
- result = jsNumber((val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
+ result = jsNumber(exec, (val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
VM_CHECK_EXCEPTION();
}
dst = result;
if (JSImmediate::areBothImmediateNumbers(src1, src2))
result = JSImmediate::andImmediateNumbers(src1, src2);
else {
- result = jsNumber(src1->toInt32(exec) & src2->toInt32(exec));
+ result = jsNumber(exec, src1->toInt32(exec) & src2->toInt32(exec));
VM_CHECK_EXCEPTION();
}
dst = result;
if (JSImmediate::areBothImmediateNumbers(src1, src2))
result = JSImmediate::xorImmediateNumbers(src1, src2);
else {
- result = jsNumber(src1->toInt32(exec) ^ src2->toInt32(exec));
+ result = jsNumber(exec, src1->toInt32(exec) ^ src2->toInt32(exec));
VM_CHECK_EXCEPTION();
}
dst = result;
if (JSImmediate::areBothImmediateNumbers(src1, src2))
result = JSImmediate::orImmediateNumbers(src1, src2);
else {
- result = jsNumber(src1->toInt32(exec) | src2->toInt32(exec));
+ result = jsNumber(exec, src1->toInt32(exec) | src2->toInt32(exec));
VM_CHECK_EXCEPTION();
}
dst = result;
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- JSValue* result = jsNumber(~r[src].u.jsValue->toInt32(exec));
+ JSValue* result = jsNumber(exec, ~r[src].u.jsValue->toInt32(exec));
VM_CHECK_EXCEPTION();
r[dst].u.jsValue = result;
*/
int dst = (++vPC)->u.operand;
int src = (++vPC)->u.operand;
- r[dst].u.jsValue = jsTypeStringForValue(r[src].u.jsValue);
+ r[dst].u.jsValue = jsTypeStringForValue(exec, r[src].u.jsValue);
++vPC;
NEXT_OPCODE;
codeBlock = newCodeBlock;
exec->m_callFrameOffset = callFrameOffset;
- setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
+ setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
k = codeBlock->jsValues.data();
vPC = codeBlock->instructions.begin();
prototype = static_cast<JSObject*>(p);
else
prototype = scopeChain->globalObject()->objectPrototype();
- JSObject* newObject = new JSObject(prototype);
+ JSObject* newObject = new (exec) JSObject(prototype);
r[firstArg].u.jsValue = newObject; // "this" value
initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, firstArg, argCount, 1, constructor);
codeBlock = newCodeBlock;
exec->m_callFrameOffset = callFrameOffset;
- setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
+ setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
k = codeBlock->jsValues.data();
vPC = codeBlock->instructions.begin();
JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue);
if (!activation) {
CodeBlock* codeBlock = &function->body->generatedCode();
- activation = new JSActivation(function->body, registerBase, callFrameOffset + CallFrameHeaderSize + codeBlock->numLocals);
+ activation = new (exec) JSActivation(function->body, registerBase, callFrameOffset + CallFrameHeaderSize + codeBlock->numLocals);
callFrame[OptionalCalleeActivation].u.jsValue = activation;
}
void copyGlobals(RegisterFile* src);
- void mark()
+ void mark(Heap* heap)
{
- Collector::markStackObjectsConservatively(m_buffer, m_base + m_size);
+ heap->markStackObjectsConservatively(m_buffer, m_base + m_size);
}
bool isGlobal() { return !!m_baseObserver; }
RegisterFile* current() { return m_stack.last(); }
- void mark()
+ void mark(Heap* heap)
{
Stack::iterator end = m_stack.end();
for (Stack::iterator it = m_stack.begin(); it != end; ++it)
- (*it)->mark();
+ (*it)->mark(heap);
}
// Pointer to a value that holds the base of the top-most global register file.
#include "nodes2string.cpp"
#include "NumberObject.cpp"
#include "JSObject.cpp"
+#include "JSGlobalObject.cpp"
#include "object_object.cpp"
#include "operations.cpp"
#include "Parser.cpp"
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
Vector<UChar, 256> strBuffer;
if (alreadyVisited)
- return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+ return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
break;
}
exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
- return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+ return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
Vector<UChar, 256> strBuffer;
if (alreadyVisited)
- return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+ return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
break;
}
exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
- return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+ return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& args)
bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
Vector<UChar, 256> strBuffer;
if (alreadyVisited)
- return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+ return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
UChar comma = ',';
UString separator = args[0]->isUndefined() ? UString(&comma, 1) : args[0]->toString(exec);
break;
}
exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
- return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+ return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
}
JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList& args)
curObj = static_cast<JSObject*>(curArg); // may be 0
++it;
}
- arr->put(exec, exec->propertyNames().length, jsNumber(n));
+ arr->put(exec, exec->propertyNames().length, jsNumber(exec, n));
return arr;
}
JSValue* result = 0;
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
if (length == 0) {
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
result = jsUndefined();
} else {
result = thisObj->get(exec, length - 1);
thisObj->deleteProperty(exec, length - 1);
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1));
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
}
return result;
}
for (unsigned n = 0; n < args.size(); n++)
thisObj->put(exec, length + n, args[n]);
length += args.size();
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
- return jsNumber(length);
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
+ return jsNumber(exec, length);
}
JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject* thisObj, const ArgList&)
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
if (length == 0) {
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
result = jsUndefined();
} else {
result = thisObj->get(exec, 0);
thisObj->deleteProperty(exec, k - 1);
}
thisObj->deleteProperty(exec, length - 1);
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1));
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
}
return result;
}
if (JSValue* v = getProperty(exec, thisObj, k))
resObj->put(exec, n, v);
}
- resObj->put(exec, exec->propertyNames().length, jsNumber(n));
+ resObj->put(exec, exec->propertyNames().length, jsNumber(exec, n));
return result;
}
if (JSValue* v = getProperty(exec, thisObj, k + begin))
resObj->put(exec, k, v);
}
- resObj->put(exec, exec->propertyNames().length, jsNumber(deleteCount));
+ resObj->put(exec, exec->propertyNames().length, jsNumber(exec, deleteCount));
unsigned additionalArgs = std::max<int>(args.size() - 2, 0);
if (additionalArgs != deleteCount) {
for (unsigned k = 0; k < additionalArgs; ++k)
thisObj->put(exec, k + begin, args[k + 2]);
- thisObj->put(exec, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs));
+ thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
return result;
}
}
for (unsigned k = 0; k < nrArgs; ++k)
thisObj->put(exec, k, args[k]);
- JSValue* result = jsNumber(length + nrArgs);
+ JSValue* result = jsNumber(exec, length + nrArgs);
thisObj->put(exec, exec->propertyNames().length, result);
return result;
}
ArgList eachArguments;
eachArguments.append(v);
- eachArguments.append(jsNumber(k));
+ eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
ArgList mapArgs;
- mapArgs.append(jsNumber(length));
+ mapArgs.append(jsNumber(exec, length));
JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, mapArgs));
for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
ArgList eachArguments;
eachArguments.append(v);
- eachArguments.append(jsNumber(k));
+ eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
ArgList eachArguments;
eachArguments.append(slot.getValue(exec, k));
- eachArguments.append(jsNumber(k));
+ eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
ArgList eachArguments;
eachArguments.append(slot.getValue(exec, k));
- eachArguments.append(jsNumber(k));
+ eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
eachFunction->callAsFunction(exec, applyThis, eachArguments);
ArgList eachArguments;
eachArguments.append(slot.getValue(exec, k));
- eachArguments.append(jsNumber(k));
+ eachArguments.append(jsNumber(exec, k));
eachArguments.append(thisObj);
bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
if (!e)
continue;
if (strictEqual(searchElement, e))
- return jsNumber(index);
+ return jsNumber(exec, index);
}
- return jsNumber(-1);
+ return jsNumber(exec, -1);
}
JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
if (d < 0) {
d += length;
if (d < 0)
- return jsNumber(-1);
+ return jsNumber(exec, -1);
}
if (d < length)
index = static_cast<int>(d);
if (!e)
continue;
if (strictEqual(searchElement, e))
- return jsNumber(index);
+ return jsNumber(exec, index);
}
- return jsNumber(-1);
+ return jsNumber(exec, -1);
}
// ------------------------------ ArrayConstructor -------------------------------
putDirect(exec->propertyNames().prototype, arrayProto, DontEnum|DontDelete|ReadOnly);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
ConstructType ArrayConstructor::getConstructData(ConstructData&)
uint32_t n = args[0]->toUInt32(exec);
if (n != args[0]->toNumber(exec))
return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
- return new JSArray(exec->lexicalGlobalObject()->arrayPrototype(), n);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), n);
}
// otherwise the array is constructed with the arguments in it
- return new JSArray(exec->lexicalGlobalObject()->arrayPrototype(), args);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), args);
}
// ECMA 15.6.1
JSValue* ArrayConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
{
// equivalent to 'new Array(....)'
- return construct(exec,args);
+ return construct(exec, args);
}
}
{
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);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
}
JSValue* v = static_cast<BooleanObject*>(thisObj)->internalValue();
ASSERT(v);
- return jsString(v->toString(exec));
+ return jsString(exec, v->toString(exec));
}
JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
{
putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
}
ConstructType BooleanConstructor::getConstructData(ConstructData&)
// ECMA 15.6.2
JSObject* BooleanConstructor::construct(ExecState* exec, const ArgList& args)
{
- BooleanObject* obj(new BooleanObject(exec->lexicalGlobalObject()->booleanPrototype()));
+ BooleanObject* obj(new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanPrototype()));
obj->setInternalValue(jsBoolean(args[0]->toBoolean(exec)));
return obj;
}
#define ExecState_h
#include "JSGlobalData.h"
-#include "LabelStack.h"
-#include "completion.h"
-#include "list.h"
#include "ScopeChain.h"
namespace KJS {
static const HashTable* regExpConstructorTable(ExecState* exec) { return exec->m_globalData->regExpConstructorTable; }
static const HashTable* stringTable(ExecState* exec) { return exec->m_globalData->stringTable; }
+ Heap* heap() const { return m_globalData->heap; }
+
private:
// Default constructor required for gcc 3.
ExecState() { }
FunctionPrototype::FunctionPrototype(ExecState* exec)
{
- putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
- putDirectFunction(new PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
}
// ECMA 15.3.4
if (thisObj->inherits(&JSFunction::info)) {
JSFunction* fi = static_cast<JSFunction*>(thisObj);
- return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
+ return jsString(exec, "function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
}
- return jsString("function " + static_cast<InternalFunction*>(thisObj)->functionName().ustring() + "() {\n [native code]\n}");
+ return jsString(exec, "function " + static_cast<InternalFunction*>(thisObj)->functionName().ustring() + "() {\n [native code]\n}");
}
JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const ArgList& args)
putDirect(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
// Number of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
}
ConstructType FunctionConstructor::getConstructData(ConstructData&)
functionBody->setSource(SourceRange(source, 0, source->length()));
ScopeChain scopeChain(exec->lexicalGlobalObject(), exec->globalThisValue());
- JSFunction* fimp = new JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
+ JSFunction* fimp = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
// parse parameter list. throw syntax error on illegal identifiers
int len = p.size();
#if USE(MULTIPLE_THREADS)
s_dtoaP5Mutex = new Mutex;
#if !PLATFORM(DARWIN) // Darwin has pthread_main_np(), and doesn't need registerAsMainThread() called.
- Collector::registerAsMainThread();
+ Heap::registerAsMainThread();
#endif
JSGlobalData::threadInstance();
UString::null();
{
#if PLATFORM(DARWIN)
pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce);
+
+ // FIXME: do we want heap introspector to work on other threads?
+ if (pthread_main_np())
+ JSGlobalData::threadInstance().heap->initializeHeapIntrospector();
#else
static bool initializedThreading = false;
if (!initializedThreading) {
int argc;
exec->machine()->getFunctionAndArguments(registerBase(), callFrame, function, argv, argc);
ArgList args(reinterpret_cast<JSValue***>(registerBase()), argv - *registerBase(), argc);
- return new Arguments(exec, function, args, this);
+ return new (exec) Arguments(exec, function, args, this);
}
} // namespace KJS
m_vectorLength = initialCapacity;
m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
- Collector::reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
+ Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
checkConsistency();
}
return value ? value : jsUndefined();
}
-JSValue* JSArray::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
- return jsNumber(static_cast<JSArray*>(slot.slotBase())->m_length);
+ return jsNumber(exec, static_cast<JSArray*>(slot.slotBase())->m_length);
}
ALWAYS_INLINE bool JSArray::inlineGetOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
return exec->machine()->retrieveCaller(exec, thisObj);
}
-JSValue* JSFunction::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
- return jsNumber(thisObj->body->parameters().size());
+ return jsNumber(exec, thisObj->body->parameters().size());
}
bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
else
proto = exec->lexicalGlobalObject()->objectPrototype();
- JSObject* thisObj = new JSObject(proto);
+ JSObject* thisObj = new (exec) JSObject(proto);
JSValue* exception = 0;
JSValue* result = machine().execute(body.get(), exec, this, thisObj, args, &exec->dynamicGlobalObject()->registerFileStack(), _scope.node(), &exception);
, indexToNameMap(func, args)
{
putDirect(exec->propertyNames().callee, func, DontEnum);
- putDirect(exec->propertyNames().length, args.size(), DontEnum);
+ putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
int i = 0;
ArgList::const_iterator end = args.end();
r += tmp;
}
}
- return jsString(r);
+ return jsString(exec, r);
}
static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
k++;
s.append(c);
}
- return jsString(s);
+ return jsString(exec, s);
}
static bool isStrWhiteSpace(unsigned short c)
JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
+ return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
}
JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(parseFloat(args[0]->toString(exec)));
+ return jsNumber(exec, parseFloat(args[0]->toString(exec)));
}
JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const ArgList& args)
r += s;
}
- return jsString(r);
+ return jsString(exec, r);
}
JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const ArgList& args)
s += UString(c, 1);
}
- return jsString(s);
+ return jsString(exec, s);
}
#ifndef NDEBUG
, m_function(function)
{
ASSERT_ARG(function, function);
- putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
}
PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function)
, m_function(function)
{
ASSERT_ARG(function, function);
- putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
}
JSValue* PrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
{
ASSERT_ARG(function, function);
ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
- putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
}
JSValue* PrototypeReflexiveFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
#include "Parser.h"
#if USE(MULTIPLE_THREADS)
+#include <wtf/Threading.h>
#include <wtf/ThreadSpecific.h>
#endif
JSGlobalData::JSGlobalData()
-// : heap(new Heap)
+ : heap(new Heap)
#if USE(MULTIPLE_THREADS)
- : arrayTable(new HashTable(KJS::arrayTable))
+ , arrayTable(new HashTable(KJS::arrayTable))
, dateTable(new HashTable(KJS::dateTable))
, mathTable(new HashTable(KJS::mathTable))
, numberTable(new HashTable(KJS::numberTable))
, regExpConstructorTable(new HashTable(KJS::regExpConstructorTable))
, stringTable(new HashTable(KJS::stringTable))
#else
- : arrayTable(&KJS::arrayTable)
+ , arrayTable(&KJS::arrayTable)
, dateTable(&KJS::dateTable)
, mathTable(&KJS::mathTable)
, numberTable(&KJS::numberTable)
#endif
}
+JSGlobalData& JSGlobalData::sharedInstance()
+{
+ return threadInstance();
+/*
+#if USE(MULTIPLE_THREADS)
+ AtomicallyInitializedStatic(JSGlobalData, sharedInstance);
+#else
+ static JSGlobalData sharedInstance;
+#endif
+ return sharedInstance;
+*/
+}
+
}
#define JSGlobalData_h
#include "list.h"
-#include "ustring.h"
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
namespace KJS {
class CommonIdentifiers;
-// class Heap;
+ class Heap;
class IdentifierTable;
class JSGlobalObject;
class Lexer;
// JavaScriptCore clients, which all share a single JSGlobalData, and thus cannot run concurrently.
struct JSGlobalData : Noncopyable {
static JSGlobalData& threadInstance();
+ static JSGlobalData& sharedInstance();
-// Heap* heap;
+ Heap* heap;
const HashTable* arrayTable;
const HashTable* dateTable;
#endif
}
-JSGlobalObject* JSGlobalObject::s_head = 0;
-
JSGlobalObject::~JSGlobalObject()
{
- ASSERT(JSLock::currentThreadIsHoldingLock());
-
if (d()->debugger)
d()->debugger->detach(this);
d()->next->d()->prev = d()->prev;
d()->prev->d()->next = d()->next;
- s_head = d()->next;
- if (s_head == this)
- s_head = 0;
+ JSGlobalObject*& headObject = head();
+ if (headObject == this)
+ headObject = d()->next;
+ if (headObject == this)
+ headObject = 0;
HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
{
ASSERT(JSLock::currentThreadIsHoldingLock());
- if (s_head) {
- d()->prev = s_head;
- d()->next = s_head->d()->next;
- s_head->d()->next->d()->prev = this;
- s_head->d()->next = this;
+ if (JSGlobalObject*& headObject = head()) {
+ d()->prev = headObject;
+ d()->next = headObject->d()->next;
+ headObject->d()->next->d()->prev = this;
+ headObject->d()->next = this;
} else
- s_head = d()->next = d()->prev = this;
+ headObject = d()->next = d()->prev = this;
resetTimeoutCheck();
d()->timeoutTime = 0;
void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
{
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
if (symbolTablePut(propertyName, value))
return;
return JSVariableObject::put(exec, propertyName, value);
ExecState* exec = d()->globalExec.get();
// Prototypes
- d()->functionPrototype = new FunctionPrototype(exec);
- d()->objectPrototype = new ObjectPrototype(exec, d()->functionPrototype);
+ d()->functionPrototype = new (exec) FunctionPrototype(exec);
+ d()->objectPrototype = new (exec) ObjectPrototype(exec, d()->functionPrototype);
d()->functionPrototype->setPrototype(d()->objectPrototype);
- d()->arrayPrototype = new ArrayPrototype(exec, d()->objectPrototype);
- d()->stringPrototype = new StringPrototype(exec, d()->objectPrototype);
- 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()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+ d()->arrayPrototype = new (exec) ArrayPrototype(exec, d()->objectPrototype);
+ d()->stringPrototype = new (exec) StringPrototype(exec, d()->objectPrototype);
+ d()->booleanPrototype = new (exec) BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+ d()->numberPrototype = new (exec) NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+ d()->datePrototype = new (exec) DatePrototype(exec, d()->objectPrototype);
+ d()->regExpPrototype = new (exec) RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+ d()->errorPrototype = new (exec) ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
- d()->evalErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
- d()->rangeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
- d()->referenceErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
- d()->syntaxErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
- d()->typeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
- d()->URIErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
+ d()->evalErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
+ d()->rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
+ d()->referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
+ d()->syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
+ d()->typeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
+ d()->URIErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
// Constructors
- d()->objectConstructor = new ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
- d()->functionConstructor = new FunctionConstructor(exec, d()->functionPrototype);
- d()->arrayConstructor = new ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
- d()->stringConstructor = new StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
- d()->booleanConstructor = new BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
- d()->numberConstructor = new NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
- d()->dateConstructor = new DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
- d()->regExpConstructor = new RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
- d()->errorConstructor = new ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
+ d()->objectConstructor = new (exec) ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
+ d()->functionConstructor = new (exec) FunctionConstructor(exec, d()->functionPrototype);
+ d()->arrayConstructor = new (exec) ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
+ d()->stringConstructor = new (exec) StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
+ d()->booleanConstructor = new (exec) BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
+ d()->numberConstructor = new (exec) NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
+ d()->dateConstructor = new (exec) DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
+ d()->regExpConstructor = new (exec) RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
+ d()->errorConstructor = new (exec) ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
- d()->evalErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
- d()->rangeErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->rangeErrorPrototype);
- d()->referenceErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->referenceErrorPrototype);
- d()->syntaxErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
- d()->typeErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
- d()->URIErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
+ d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
+ d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->rangeErrorPrototype);
+ d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->referenceErrorPrototype);
+ d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
+ d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
+ d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
d()->functionPrototype->putDirect(exec->propertyNames().constructor, d()->functionConstructor, DontEnum);
// Set global values.
GlobalPropertyInfo staticGlobals[] = {
- GlobalPropertyInfo(Identifier(exec, "Math"), new MathObject(exec, d()->objectPrototype), DontEnum | DontDelete),
- GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete),
- GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, d()->objectPrototype), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
+ GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete)
};
// Set global functions.
- d()->evalFunction = new PrototypeReflexiveFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
+ d()->evalFunction = new (exec) PrototypeReflexiveFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
putDirectFunction(d()->evalFunction, DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
#ifndef NDEBUG
- putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
#endif
// Set prototype, and also insert the object prototype at the end of the chain.
for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
(*it)->mark();
- registerFileStack().mark();
+ registerFileStack().mark(globalData()->heap);
markIfNeeded(d()->globalExec->exception());
return true;
}
+void* JSGlobalObject::operator new(size_t size)
+{
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return JSGlobalData::threadInstance().heap->inlineAllocate(size);
+#else
+ return JSGlobalData::threadInstance().heap->allocate(size);
+#endif
+}
+
+void* JSGlobalObject::operator new(size_t size, SharedTag)
+{
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return JSGlobalData::sharedInstance().heap->inlineAllocate(size);
+#else
+ return JSGlobalData::sharedInstance().heap->allocate(size);
+#endif
+}
} // namespace KJS
virtual void put(ExecState*, const Identifier&, JSValue*);
virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
-
virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
// Per-thread hash tables, cached on the global object for faster access.
JSGlobalData* globalData() { return d()->globalData; }
+ enum SharedTag { Shared };
+ void* operator new(size_t);
+ void* operator new(size_t, SharedTag);
+
void init(JSObject* thisValue);
JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
private:
bool checkTimeout();
void resetTimeoutCheck();
-
- static JSGlobalObject* s_head;
};
inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
{
ASSERT(isImmediate(v));
if (v == jsNull())
- return new JSNotAnObject(throwError(exec, TypeError, "Null value"));
+ return new (exec) JSNotAnObject(throwError(exec, TypeError, "Null value"));
else if (v == jsUndefined())
- return new JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
+ return new (exec) JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
else if (isBoolean(v)) {
ArgList args;
args.append(const_cast<JSValue *>(v));
return static_cast<JSType>(tag);
}
+ALWAYS_INLINE JSValue* jsUndefined()
+{
+ return JSImmediate::undefinedImmediate();
+}
+
+inline JSValue* jsNull()
+{
+ return JSImmediate::nullImmediate();
+}
+
+inline JSValue* jsBoolean(bool b)
+{
+ return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
+}
+
} // namespace KJS
#endif
void JSLock::registerThread()
{
- Collector::registerThread();
+ Heap::registerThread();
}
JSLock::DropAllLocks::DropAllLocks()
void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value)
{
ASSERT(value);
+ ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
if (propertyName == exec->propertyNames().underscoreProto) {
JSObject* proto = value->getObject();
return 0;
}
-void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc)
+void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
{
JSValue *o = getDirect(propertyName);
GetterSetter *gs;
if (o && o->type() == GetterSetterType) {
gs = static_cast<GetterSetter *>(o);
} else {
- gs = new GetterSetter;
+ gs = new (exec) GetterSetter;
putDirect(propertyName, gs, IsGetterSetter);
}
gs->setGetter(getterFunc);
}
-void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc)
+void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
{
JSValue *o = getDirect(propertyName);
GetterSetter *gs;
if (o && o->type() == GetterSetterType) {
gs = static_cast<GetterSetter *>(o);
} else {
- gs = new GetterSetter;
+ gs = new (exec) GetterSetter;
putDirect(propertyName, gs, IsGetterSetter);
}
ArgList args;
if (message.isEmpty())
- args.append(jsString(name));
+ args.append(jsString(exec, name));
else
- args.append(jsString(message));
+ args.append(jsString(exec, message));
JSObject *err = static_cast<JSObject *>(cons->construct(exec,args));
if (lineno != -1)
- err->put(exec, Identifier(exec, "line"), jsNumber(lineno));
+ err->put(exec, Identifier(exec, "line"), jsNumber(exec, lineno));
if (sourceId != -1)
- err->put(exec, Identifier(exec, "sourceId"), jsNumber(sourceId));
+ err->put(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceId));
if(!sourceURL.isNull())
- err->put(exec, Identifier(exec, "sourceURL"), jsString(sourceURL));
+ err->put(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL));
return err;
}
JSValue **getDirectLocation(const Identifier& propertyName, bool& isWriteable)
{ return _prop.getLocation(propertyName, isWriteable); }
void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0);
- void putDirect(const Identifier &propertyName, int value, int attr = 0);
+ void putDirect(ExecState*, const Identifier& propertyName, int value, int attr = 0);
void removeDirect(const Identifier &propertyName);
// convenience to add a function property under the function's own built-in name
: _proto(proto)
{
ASSERT(proto);
+ ASSERT(Heap::heap(this) == Heap::heap(proto));
}
inline JSObject::JSObject()
_prop.put(propertyName, value, attr);
}
-inline void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
+inline void JSObject::putDirect(ExecState* exec, const Identifier &propertyName, int value, int attr)
{
- _prop.put(propertyName, jsNumber(value), attr);
+ _prop.put(propertyName, jsNumber(exec, value), attr);
}
inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
class JSString : public JSCell {
public:
- JSString(const UString& value) : m_value(value) { Collector::reportExtraMemoryCost(value.cost()); }
+ JSString(const UString& value) : m_value(value) { Heap::heap(this)->reportExtraMemoryCost(value.cost()); }
enum HasOtherOwnerType { HasOtherOwner };
JSString(const UString& value, HasOtherOwnerType) : m_value(value) { }
static const double D16 = 65536.0;
static const double D32 = 4294967296.0;
-void* JSCell::operator new(size_t size)
+void* JSCell::operator new(size_t size, ExecState* exec)
{
- return Collector::allocate(size);
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+ return exec->heap()->inlineAllocate(size);
+#else
+ return exec->heap()->allocate(size);
+#endif
}
bool JSCell::getUInt32(uint32_t&) const
return toObject(exec);
}
-JSCell* jsString(const char* s)
+JSCell* jsString(ExecState* exec, const char* s)
{
- return new JSString(s ? s : "");
+ return new (exec) JSString(s ? s : "");
}
-JSCell* jsString(const UString& s)
+JSCell* jsString(ExecState* exec, const UString& s)
{
- return s.isNull() ? new JSString("") : new JSString(s);
+ return s.isNull() ? new (exec) JSString("") : new (exec) JSString(s);
}
-JSCell* jsOwnedString(const UString& s)
+JSCell* jsOwnedString(ExecState* exec, const UString& s)
{
- return s.isNull() ? new JSString("", JSString::HasOtherOwner) : new JSString(s, JSString::HasOtherOwner);
+ return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner);
}
} // namespace KJS
#include "CallData.h"
#include "ConstructData.h"
+#include "ExecState.h"
#include "JSImmediate.h"
#include "collector.h"
#include "ustring.h"
*/
class JSValue : Noncopyable {
friend class JSCell; // so it can derive from this class
- friend class Collector; // so it can call asCell()
+ friend class Heap; // so it can call asCell()
private:
JSValue();
virtual ~JSValue();
};
class JSCell : public JSValue {
- friend class Collector;
+ friend class Heap;
friend class GetterSetter;
friend class JSObject;
friend class JSPropertyNameIterator;
virtual JSObject* toObject(ExecState*) const = 0;
// Garbage collection.
- void* operator new(size_t);
+ void* operator new(size_t, ExecState*);
virtual void mark();
bool marked() const;
};
class JSNumberCell : public JSCell {
- friend JSValue* jsNumberCell(double);
+ friend JSValue* jsNumberCell(ExecState*, double);
public:
double value() const { return val; }
virtual JSObject* toObject(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
- void* operator new(size_t size)
+ void* operator new(size_t size, ExecState* exec)
{
#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
- return Collector::inlineAllocateNumber(size);
+ return exec->heap()->inlineAllocateNumber(size);
#else
- return Collector::allocateNumber(size);
+ return exec->heap()->allocateNumber(size);
#endif
}
double val;
};
-JSCell* jsString(const UString&); // returns empty string if passed null string
-JSCell* jsString(const char* = ""); // returns empty string if passed 0
+JSCell* jsString(ExecState*, const UString&); // returns empty string if passed null string
+JSCell* jsString(ExecState*, const char* = ""); // returns empty string if passed 0
// should be used for strings that are owned by an object that will
// likely outlive the JSValue this makes, such as the parse tree or a
// DOM object that contains a UString
-JSCell* jsOwnedString(const UString&);
+JSCell* jsOwnedString(ExecState*, const UString&);
extern const double NaN;
extern const double Inf;
// Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so
// inlining it may not always be a win.
-inline JSValue* jsNumberCell(double d)
+inline JSValue* jsNumberCell(ExecState* exec, double d)
{
- return new JSNumberCell(d);
+ return new (exec) JSNumberCell(d);
}
-ALWAYS_INLINE JSValue* jsUndefined()
+inline JSValue* jsNaN(ExecState* exec)
{
- return JSImmediate::undefinedImmediate();
+ return jsNumberCell(exec, NaN);
}
-inline JSValue* jsNull()
-{
- return JSImmediate::nullImmediate();
-}
-
-inline JSValue* jsNaN()
-{
- return jsNumberCell(NaN);
-}
-
-inline JSValue* jsBoolean(bool b)
-{
- return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
-}
-
-ALWAYS_INLINE JSValue* jsNumber(double d)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
{
JSValue* v = JSImmediate::from(d);
- return v ? v : jsNumberCell(d);
+ return v ? v : jsNumberCell(exec, d);
}
-ALWAYS_INLINE JSValue* jsNumber(int i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(i);
+ return v ? v : jsNumberCell(exec, i);
}
-ALWAYS_INLINE JSValue* jsNumber(unsigned i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(i);
+ return v ? v : jsNumberCell(exec, i);
}
-ALWAYS_INLINE JSValue* jsNumber(long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(i);
+ return v ? v : jsNumberCell(exec, i);
}
-ALWAYS_INLINE JSValue* jsNumber(unsigned long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(i);
+ return v ? v : jsNumberCell(exec, i);
}
-ALWAYS_INLINE JSValue* jsNumber(long long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(static_cast<double>(i));
+ return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
-ALWAYS_INLINE JSValue* jsNumber(unsigned long long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
{
JSValue* v = JSImmediate::from(i);
- return v ? v : jsNumberCell(static_cast<double>(i));
-}
-
-ALWAYS_INLINE JSValue* jsNumberFromAnd(ExecState *exec, JSValue* v1, JSValue* v2)
-{
- if (JSImmediate::areBothImmediateNumbers(v1, v2))
- return JSImmediate::andImmediateNumbers(v1, v2);
- return jsNumber(v1->toInt32(exec) & v2->toInt32(exec));
+ return v ? v : jsNumberCell(exec, static_cast<double>(i));
}
inline JSValue::JSValue()
inline bool JSCell::marked() const
{
- return Collector::isCellMarked(this);
+ return Heap::isCellMarked(this);
}
inline void JSCell::mark()
{
- return Collector::markCell(this);
+ return Heap::markCell(this);
}
ALWAYS_INLINE JSCell* JSValue::asCell()
ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
{
- return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(this->toNumber(exec));
+ return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));
}
inline UString JSValue::toString(ExecState *exec) const
return getStaticPropertySlot<MathObject, JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot);
}
-JSValue* MathObject::getValueProperty(ExecState*, int token) const
+JSValue* MathObject::getValueProperty(ExecState* exec, int token) const
{
switch (token) {
case Euler:
- return jsNumber(exp(1.0));
+ return jsNumber(exec, exp(1.0));
case Ln2:
- return jsNumber(log(2.0));
+ return jsNumber(exec, log(2.0));
case Ln10:
- return jsNumber(log(10.0));
+ return jsNumber(exec, log(10.0));
case Log2E:
- return jsNumber(1.0 / log(2.0));
+ return jsNumber(exec, 1.0 / log(2.0));
case Log10E:
- return jsNumber(1.0 / log(10.0));
+ return jsNumber(exec, 1.0 / log(10.0));
case Pi:
- return jsNumber(piDouble);
+ return jsNumber(exec, piDouble);
case Sqrt1_2:
- return jsNumber(sqrt(0.5));
+ return jsNumber(exec, sqrt(0.5));
case Sqrt2:
- return jsNumber(sqrt(2.0));
+ return jsNumber(exec, sqrt(2.0));
}
ASSERT_NOT_REACHED();
JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, const ArgList& args)
{
double arg = args[0]->toNumber(exec);
- return signbit(arg) ? jsNumber(-arg) : jsNumber(arg);
+ return signbit(arg) ? jsNumber(exec, -arg) : jsNumber(exec, arg);
}
JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(acos(args[0]->toNumber(exec)));
+ return jsNumber(exec, acos(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(asin(args[0]->toNumber(exec)));
+ return jsNumber(exec, asin(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(atan(args[0]->toNumber(exec)));
+ return jsNumber(exec, atan(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
+ return jsNumber(exec, atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
}
JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, const ArgList& args)
{
double arg = args[0]->toNumber(exec);
if (signbit(arg) && arg > -1.0)
- return jsNumber(-0.0);
- return jsNumber(ceil(arg));
+ return jsNumber(exec, -0.0);
+ return jsNumber(exec, ceil(arg));
}
JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(cos(args[0]->toNumber(exec)));
+ return jsNumber(exec, cos(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(exp(args[0]->toNumber(exec)));
+ return jsNumber(exec, exp(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, const ArgList& args)
{
double arg = args[0]->toNumber(exec);
if (signbit(arg) && arg == 0.0)
- return jsNumber(-0.0);
- return jsNumber(floor(arg));
+ return jsNumber(exec, -0.0);
+ return jsNumber(exec, floor(arg));
}
JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(log(args[0]->toNumber(exec)));
+ return jsNumber(exec, log(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const ArgList& args)
if (val > result || (val == 0 && result == 0 && !signbit(val)))
result = val;
}
- return jsNumber(result);
+ return jsNumber(exec, result);
}
JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const ArgList& args)
if (val < result || (val == 0 && result == 0 && signbit(val)))
result = val;
}
- return jsNumber(result);
+ return jsNumber(exec, result);
}
JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const ArgList& args)
double arg2 = args[1]->toNumber(exec);
if (isnan(arg2))
- return jsNaN();
+ return jsNaN(exec);
if (isinf(arg2) && fabs(arg) == 1)
- return jsNaN();
- return jsNumber(pow(arg, arg2));
+ return jsNaN(exec);
+ return jsNumber(exec, pow(arg, arg2));
}
-JSValue* mathProtoFuncRandom(ExecState*, JSObject*, const ArgList&)
+JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, const ArgList&)
{
#if !USE(MULTIPLE_THREADS)
static bool didInitRandom;
}
#endif
- return jsNumber(wtf_random());
+ return jsNumber(exec, wtf_random());
}
JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, const ArgList& args)
{
double arg = args[0]->toNumber(exec);
if (signbit(arg) && arg >= -0.5)
- return jsNumber(-0.0);
- return jsNumber(floor(arg + 0.5));
+ return jsNumber(exec, -0.0);
+ return jsNumber(exec, floor(arg + 0.5));
}
JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(sin(args[0]->toNumber(exec)));
+ return jsNumber(exec, sin(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(sqrt(args[0]->toNumber(exec)));
+ return jsNumber(exec, sqrt(args[0]->toNumber(exec)));
}
JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, const ArgList& args)
{
- return jsNumber(tan(args[0]->toNumber(exec)));
+ return jsNumber(exec, tan(args[0]->toNumber(exec)));
}
} // namespace KJS
NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
: NumberObject(objectPrototype)
{
- setInternalValue(jsNumber(0));
+ setInternalValue(jsNumber(exec, 0));
// The constructor will be added later, after NumberConstructor has been constructed
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
}
// ------------------------------ Functions ---------------------------
double radixAsDouble = args[0]->toInteger(exec); // nan -> 0
if (radixAsDouble == 10 || args[0]->isUndefined())
- return jsString(v->toString(exec));
+ return jsString(exec, v->toString(exec));
if (radixAsDouble < 2 || radixAsDouble > 36)
return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
const char* lastCharInString = s + sizeof(s) - 1;
double x = v->toNumber(exec);
if (isnan(x) || isinf(x))
- return jsString(UString::from(x));
+ return jsString(exec, UString::from(x));
bool isNegative = x < 0.0;
if (isNegative)
*p = '\0';
ASSERT(p < s + sizeof(s));
- return jsString(startOfResultString);
+ return jsString(exec, startOfResultString);
}
JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
return throwError(exec, TypeError);
// TODO
- return jsString(static_cast<NumberObject*>(thisObj)->internalValue()->toString(exec));
+ return jsString(exec, static_cast<NumberObject*>(thisObj)->internalValue()->toString(exec));
}
JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
double x = v->toNumber(exec);
if (isnan(x))
- return jsString("NaN");
+ return jsString(exec, "NaN");
UString s;
if (x < 0) {
x = 0;
if (x >= pow(10.0, 21.0))
- return jsString(s + UString::from(x));
+ return jsString(exec, s + UString::from(x));
const double tenToTheF = pow(10.0, f);
double n = floor(x * tenToTheF);
}
int kMinusf = k - f;
if (kMinusf < m.size())
- return jsString(s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
- return jsString(s + m.substr(0, kMinusf));
+ return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
+ return jsString(exec, s + m.substr(0, kMinusf));
}
static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
double x = v->toNumber(exec);
if (isnan(x) || isinf(x))
- return jsString(UString::from(x));
+ return jsString(exec, UString::from(x));
JSValue* fractionalDigitsValue = args[0];
double df = fractionalDigitsValue->toInteger(exec);
}
if (isnan(x))
- return jsString("NaN");
+ return jsString(exec, "NaN");
if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
x = 0;
freedtoa(result);
- return jsString(buf);
+ return jsString(exec, buf);
}
JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const ArgList& args)
double doublePrecision = args[0]->toIntegerPreserveNaN(exec);
double x = v->toNumber(exec);
if (args[0]->isUndefined() || isnan(x) || isinf(x))
- return jsString(v->toString(exec));
+ return jsString(exec, v->toString(exec));
UString s;
if (x < 0) {
if (m.size() > 1)
m = m.substr(0, 1) + "." + m.substr(1);
if (e >= 0)
- return jsString(s + m + "e+" + UString::from(e));
- return jsString(s + m + "e-" + UString::from(-e));
+ return jsString(exec, s + m + "e+" + UString::from(e));
+ return jsString(exec, s + m + "e-" + UString::from(-e));
}
} else {
m = char_sequence('0', precision);
}
if (e == precision - 1)
- return jsString(s + m);
+ return jsString(exec, s + m);
if (e >= 0) {
if (e + 1 < m.size())
- return jsString(s + m.substr(0, e + 1) + "." + m.substr(e + 1));
- return jsString(s + m);
+ return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
+ return jsString(exec, s + m);
}
- return jsString(s + "0." + char_sequence('0', -(e + 1)) + m);
+ return jsString(exec, s + "0." + char_sequence('0', -(e + 1)) + m);
}
// ------------------------------ NumberConstructor ------------------------------
putDirect(exec->propertyNames().prototype, numberProto, DontEnum|DontDelete|ReadOnly);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
}
-JSValue* NumberConstructor::getValueProperty(ExecState*, int token) const
+JSValue* NumberConstructor::getValueProperty(ExecState* exec, int token) const
{
// ECMA 15.7.3
switch (token) {
case NaNValue:
- return jsNaN();
+ return jsNaN(exec);
case NegInfinity:
- return jsNumberCell(-Inf);
+ return jsNumberCell(exec, -Inf);
case PosInfinity:
- return jsNumberCell(Inf);
+ return jsNumberCell(exec, Inf);
case MaxValue:
- return jsNumberCell(1.7976931348623157E+308);
+ return jsNumberCell(exec, 1.7976931348623157E+308);
case MinValue:
- return jsNumberCell(5E-324);
+ return jsNumberCell(exec, 5E-324);
}
ASSERT_NOT_REACHED();
return jsNull();
JSObject* NumberConstructor::construct(ExecState* exec, const ArgList& args)
{
JSObject* proto = exec->lexicalGlobalObject()->numberPrototype();
- NumberObject* obj = new NumberObject(proto);
+ NumberObject* obj = new (exec) NumberObject(proto);
// FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
double n = args.isEmpty() ? 0 : args[0]->toNumber(exec);
- obj->setInternalValue(jsNumber(n));
+ obj->setInternalValue(jsNumber(exec, n));
return obj;
}
JSValue* NumberConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
{
// FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
- return jsNumber(args.isEmpty() ? 0 : args[0]->toNumber(exec));
+ return jsNumber(exec, args.isEmpty() ? 0 : args[0]->toNumber(exec));
}
} // namespace KJS
struct PropertyMapEntry;
struct PropertyMapHashTable;
- class SavedProperty : Noncopyable {
- public:
- // Since we use this in arrays, we allocate it uninitialized
- // and then explicitly initialize. This means we can allocate
- // the array without initializing every saved property in the
- // array twice. To accomplish this, the class uses data members
- // with types that don't have constructors.
- SavedProperty();
- void init(UString::Rep* name, JSValue*, unsigned attributes);
- ~SavedProperty();
-
- UString::Rep* name() const;
- JSValue* value() const;
- unsigned attributes() const;
-
- private:
- UString::Rep* m_name;
- JSValue* m_value;
- unsigned m_attributes;
- };
-
class PropertyMap : Noncopyable {
public:
PropertyMap();
{
}
-
- inline SavedProperty::SavedProperty()
-#ifndef NDEBUG
- : m_name(0)
- , m_value(0)
- , m_attributes(0)
-#endif
- {
- }
-
- inline void SavedProperty::init(UString::Rep* name, JSValue* value, unsigned attributes)
- {
- ASSERT(name);
- ASSERT(value);
-
- ASSERT(!m_name);
- ASSERT(!m_value);
- ASSERT(!m_attributes);
-
- m_name = name;
- m_value = value;
- m_attributes = attributes;
- name->ref();
- gcProtect(value);
- }
-
- inline SavedProperty::~SavedProperty()
- {
- ASSERT(m_name);
- ASSERT(m_value);
-
- m_name->deref();
- gcUnprotect(m_value);
- }
-
- inline UString::Rep* SavedProperty::name() const
- {
- ASSERT(m_name);
- ASSERT(m_value);
-
- return m_name;
- }
-
- inline JSValue* SavedProperty::value() const
- {
- ASSERT(m_name);
- ASSERT(m_value);
-
- return m_value;
- }
-
- inline unsigned SavedProperty::attributes() const
- {
- ASSERT(m_name);
- ASSERT(m_value);
-
- return m_attributes;
- }
-
} // namespace
#endif // _KJS_PROPERTY_MAP_H_
RegExpPrototype::RegExpPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
: JSObject(objectPrototype)
{
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
}
// ------------------------------ Functions ---------------------------
{
if (!thisObj->inherits(&RegExpObject::info)) {
if (thisObj->inherits(&RegExpPrototype::info))
- return jsString("//");
+ return jsString(exec, "//");
return throwError(exec, TypeError);
}
result += "i";
if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
result += "m";
- return jsString(result);
+ return jsString(exec, result);
}
// ------------------------------ RegExpObject ------------------------------------
return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
}
-JSValue* RegExpObject::getValueProperty(ExecState*, int token) const
+JSValue* RegExpObject::getValueProperty(ExecState* exec, int token) const
{
switch (token) {
case Global:
case Multiline:
return jsBoolean(m_regExp->multiline());
case Source:
- return jsString(m_regExp->pattern());
+ return jsString(exec, m_regExp->pattern());
case LastIndex:
- return jsNumber(m_lastIndex);
+ return jsNumber(exec, m_lastIndex);
}
ASSERT_NOT_REACHED();
putDirect(exec->propertyNames().prototype, regProto, DontEnum | DontDelete | ReadOnly);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum);
}
/*
for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
int start = d->lastOvector[2 * i];
if (start >= 0)
- JSArray::put(exec, i, jsString(d->lastInput.substr(start, d->lastOvector[2 * i + 1] - start)));
+ JSArray::put(exec, i, jsString(exec, d->lastInput.substr(start, d->lastOvector[2 * i + 1] - start)));
}
- JSArray::put(exec, exec->propertyNames().index, jsNumber(d->lastOvector[0]));
- JSArray::put(exec, exec->propertyNames().input, jsString(d->lastInput));
+ JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]));
+ JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->lastInput));
delete d;
setLazyCreationData(0);
JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
{
- return new RegExpMatchesArray(exec, d.get());
+ return new (exec) RegExpMatchesArray(exec, d.get());
}
-JSValue* RegExpConstructor::getBackref(unsigned i) const
+JSValue* RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
{
if (d->lastOvector && i <= d->lastNumSubPatterns)
- return jsString(d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
- return jsString("");
+ return jsString(exec, d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
+ return jsString(exec, "");
}
-JSValue* RegExpConstructor::getLastParen() const
+JSValue* RegExpConstructor::getLastParen(ExecState* exec) const
{
unsigned i = d->lastNumSubPatterns;
if (i > 0) {
ASSERT(d->lastOvector);
- return jsString(d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
+ return jsString(exec, d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
}
- return jsString("");
+ return jsString(exec, "");
}
-JSValue *RegExpConstructor::getLeftContext() const
+JSValue* RegExpConstructor::getLeftContext(ExecState* exec) const
{
if (d->lastOvector)
- return jsString(d->lastInput.substr(0, d->lastOvector[0]));
- return jsString("");
+ return jsString(exec, d->lastInput.substr(0, d->lastOvector[0]));
+ return jsString(exec, "");
}
-JSValue *RegExpConstructor::getRightContext() const
+JSValue* RegExpConstructor::getRightContext(ExecState* exec) const
{
if (d->lastOvector) {
UString s = d->lastInput;
- return jsString(s.substr(d->lastOvector[1], s.size() - d->lastOvector[1]));
+ return jsString(exec, s.substr(d->lastOvector[1], s.size() - d->lastOvector[1]));
}
- return jsString("");
+ return jsString(exec, "");
}
bool RegExpConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
}
-JSValue *RegExpConstructor::getValueProperty(ExecState*, int token) const
+JSValue *RegExpConstructor::getValueProperty(ExecState* exec, int token) const
{
switch (token) {
case Dollar1:
- return getBackref(1);
+ return getBackref(exec, 1);
case Dollar2:
- return getBackref(2);
+ return getBackref(exec, 2);
case Dollar3:
- return getBackref(3);
+ return getBackref(exec, 3);
case Dollar4:
- return getBackref(4);
+ return getBackref(exec, 4);
case Dollar5:
- return getBackref(5);
+ return getBackref(exec, 5);
case Dollar6:
- return getBackref(6);
+ return getBackref(exec, 6);
case Dollar7:
- return getBackref(7);
+ return getBackref(exec, 7);
case Dollar8:
- return getBackref(8);
+ return getBackref(exec, 8);
case Dollar9:
- return getBackref(9);
+ return getBackref(exec, 9);
case Input:
- return jsString(d->lastInput);
+ return jsString(exec, d->lastInput);
case Multiline:
return jsBoolean(d->multiline);
case LastMatch:
- return getBackref(0);
+ return getBackref(exec, 0);
case LastParen:
- return getLastParen();
+ return getLastParen(exec);
case LeftContext:
- return getLeftContext();
+ return getLeftContext(exec);
case RightContext:
- return getRightContext();
+ return getRightContext(exec);
default:
- ASSERT(0);
+ ASSERT_NOT_REACHED();
}
- return jsString("");
+ return jsString(exec, "");
}
void RegExpConstructor::put(ExecState *exec, const Identifier &propertyName, JSValue *value)
RefPtr<RegExp> regExp = RegExp::create(pattern, flags);
return regExp->isValid()
- ? new RegExpObject(exec->lexicalGlobalObject()->regExpPrototype(), regExp.release())
+ ? new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpPrototype(), regExp.release())
: throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
}
const UString& input() const;
private:
- JSValue* getBackref(unsigned) const;
- JSValue* getLastParen() const;
- JSValue* getLeftContext() const;
- JSValue* getRightContext() const;
+ JSValue* getBackref(ExecState*, unsigned) const;
+ JSValue* getLastParen(ExecState*) const;
+ JSValue* getLeftContext(ExecState*) const;
+ JSValue* getRightContext(ExecState*) const;
OwnPtr<RegExpConstructorPrivate> d;
};
#include "Parser.h"
#include "ArrayPrototype.h"
#include "collector.h"
+#include "completion.h"
#include "JSFunction.h"
#include "InitializeThreading.h"
#include "interpreter.h"
GlobalObject::GlobalObject(Vector<UString>& arguments)
{
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "print"), functionPrint));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "quit"), functionQuit));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "gc"), functionGC));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "version"), functionVersion));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "run"), functionRun));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "load"), functionLoad));
- putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "readline"), functionReadline));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "print"), functionPrint));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "quit"), functionQuit));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "gc"), functionGC));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "version"), functionVersion));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "run"), functionRun));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "load"), functionLoad));
+ putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "readline"), functionReadline));
JSObject* array = arrayConstructor()->construct(globalExec(), globalExec()->emptyList());
for (size_t i = 0; i < arguments.size(); ++i)
- array->put(globalExec(), i, jsString(arguments[i]));
+ array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
putDirect(Identifier(globalExec(), "arguments"), array);
Interpreter::setShouldPrintExceptions(true);
return jsUndefined();
}
-JSValue* functionGC(ExecState*, JSObject*, const ArgList&)
+JSValue* functionGC(ExecState* exec, JSObject*, const ArgList&)
{
JSLock lock;
- Collector::collect();
+ exec->heap()->collect();
return jsUndefined();
}
Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
stopWatch.stop();
- return jsNumber(stopWatch.getElapsedMS());
+ return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
}
JSValue* functionLoad(ExecState* exec, JSObject*, const ArgList& args)
return jsUndefined();
}
-JSValue* functionReadline(ExecState*, JSObject*, const ArgList&)
+JSValue* functionReadline(ExecState* exec, JSObject*, const ArgList&)
{
Vector<char, 256> line;
int c;
line.append(c);
}
line.append('\0');
- return jsString(line.data());
+ return jsString(exec, line.data());
}
JSValue* functionQuit(ExecState*, JSObject*, const ArgList&)
runInteractive(globalObject);
#ifndef NDEBUG
- Collector::collect();
+ JSGlobalData::threadInstance().heap->collect();
#endif
return success ? 0 : 3;
/*
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
*
* This library is free software; you can redistribute it and/or
#if USE(MULTIPLE_THREADS)
#include <pthread.h>
+#include <wtf/Threading.h>
#endif
#if PLATFORM(DARWIN)
// tunable parameters
const size_t SPARE_EMPTY_BLOCKS = 2;
-const size_t MIN_ARRAY_SIZE = 14;
const size_t GROWTH_FACTOR = 2;
const size_t LOW_WATER_FACTOR = 4;
const size_t ALLOCATIONS_PER_COLLECTION = 4000;
+// This value has to be a macro to be used in max() without introducing
+// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
+#define MIN_ARRAY_SIZE 14UL
+
+Heap::Heap()
+ : m_pagesize(getpagesize())
+ , mainThreadOnlyObjectCount(0)
+ , m_markListSet(0)
+{
+ memset(&primaryHeap, 0, sizeof(CollectorHeap));
+ memset(&numberHeap, 0, sizeof(CollectorHeap));
+}
-static CollectorHeap primaryHeap = { 0, 0, 0, 0, 0, 0, 0, NoOperation };
-static CollectorHeap numberHeap = { 0, 0, 0, 0, 0, 0, 0, NoOperation };
-
-size_t Collector::mainThreadOnlyObjectCount = 0;
-HashSet<ArgList*>* Collector::m_markListSet;
-
-static CollectorBlock* allocateBlock()
+static NEVER_INLINE CollectorBlock* allocateBlock()
{
#if PLATFORM(DARWIN)
vm_address_t address = 0;
posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE);
memset(address, 0, BLOCK_SIZE);
#else
- static size_t pagesize = getpagesize();
size_t extra = 0;
- if (BLOCK_SIZE > pagesize)
- extra = BLOCK_SIZE - pagesize;
+ if (BLOCK_SIZE > m_pagesize)
+ extra = BLOCK_SIZE - m_pagesize;
void* mmapResult = mmap(NULL, BLOCK_SIZE + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
uintptr_t address = reinterpret_cast<uintptr_t>(mmapResult);
#elif HAVE(POSIX_MEMALIGN)
free(block);
#else
- munmap(reinterpret_cast<char *>(block), BLOCK_SIZE);
+ munmap(reinterpret_cast<char*>(block), BLOCK_SIZE);
#endif
}
-void Collector::recordExtraCost(size_t cost)
+void Heap::recordExtraCost(size_t cost)
{
// Our frequency of garbage collection tries to balance memory use against speed
// by collecting based on the number of newly created values. However, for values
primaryHeap.extraCost += cost;
}
-template <Collector::HeapType heapType> struct HeapConstants;
+template <Heap::HeapType heapType> struct HeapConstants;
-template <> struct HeapConstants<Collector::PrimaryHeap> {
+template <> struct HeapConstants<Heap::PrimaryHeap> {
static const size_t cellSize = CELL_SIZE;
static const size_t cellsPerBlock = CELLS_PER_BLOCK;
static const size_t bitmapShift = 0;
typedef CollectorBlock Block;
};
-template <> struct HeapConstants<Collector::NumberHeap> {
+template <> struct HeapConstants<Heap::NumberHeap> {
static const size_t cellSize = SMALL_CELL_SIZE;
static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
static const size_t bitmapShift = 1;
typedef SmallCellCollectorBlock Block;
};
-template <Collector::HeapType heapType> ALWAYS_INLINE void* Collector::heapAllocate(size_t s)
+template <Heap::HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
{
typedef typename HeapConstants<heapType>::Block Block;
typedef typename HeapConstants<heapType>::Cell Cell;
targetBlock = (Block*)allocateBlock();
targetBlock->freeList = targetBlock->cells;
+ targetBlock->heap = this;
targetBlockUsedCells = 0;
heap.blocks[usedBlocks] = (CollectorBlock*)targetBlock;
heap.usedBlocks = usedBlocks + 1;
return newCell;
}
-#ifndef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
-void* Collector::allocate(size_t s)
+void* Heap::allocate(size_t s)
{
return heapAllocate<PrimaryHeap>(s);
}
-#endif
-void* Collector::allocateNumber(size_t s)
+void* Heap::allocateNumber(size_t s)
{
return heapAllocate<NumberHeap>(s);
}
static pthread_t mainThread;
#endif
-void Collector::registerAsMainThread()
+void Heap::registerAsMainThread()
{
#if USE(MULTIPLE_THREADS)
mainThread = pthread_self();
#endif
}
-class Collector::Thread {
+class Heap::Thread {
public:
Thread(pthread_t pthread, const PlatformThread& platThread, void* base)
: posixThread(pthread)
pthread_key_t registeredThreadKey;
pthread_once_t registeredThreadKeyOnce = PTHREAD_ONCE_INIT;
-Collector::Thread* registeredThreads;
+Heap::Thread* registeredThreads;
static void destroyRegisteredThread(void* data)
{
- Collector::Thread* thread = (Collector::Thread*)data;
+ Heap::Thread* thread = (Heap::Thread*)data;
// Can't use JSLock convenience object here because we don't want to re-register
// an exiting thread.
if (registeredThreads == thread) {
registeredThreads = registeredThreads->next;
} else {
- Collector::Thread* last = registeredThreads;
- Collector::Thread* t;
+ Heap::Thread* last = registeredThreads;
+ Heap::Thread* t;
for (t = registeredThreads->next; t != NULL; t = t->next) {
if (t == thread) {
last->next = t->next;
pthread_key_create(®isteredThreadKey, destroyRegisteredThread);
}
-void Collector::registerThread()
+void Heap::registerThread()
{
ASSERT(JSLock::lockCount() > 0);
ASSERT(JSLock::currentThreadIsHoldingLock());
pthread_once(®isteredThreadKeyOnce, initializeRegisteredThreadKey);
if (!pthread_getspecific(registeredThreadKey)) {
-#if PLATFORM(DARWIN)
- if (onMainThread())
- CollectorHeapIntrospector::init(&primaryHeap, &numberHeap);
-#endif
-
- Collector::Thread* thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
+ Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
thread->next = registeredThreads;
registeredThreads = thread;
}
}
+void Heap::initializeHeapIntrospector()
+{
+ ASSERT(pthread_main_np());
+ CollectorHeapIntrospector::init(&primaryHeap, &numberHeap);
+}
+
#endif
#define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char*) - 1)) == 0)
// cell size needs to be a power of two for this to be valid
#define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0)
-void Collector::markStackObjectsConservatively(void* start, void* end)
+void Heap::markStackObjectsConservatively(void* start, void* end)
{
if (start > end) {
void* tmp = start;
// Mark the the number heap, we can mark these Cells directly to avoid the virtual call cost
for (size_t block = 0; block < usedNumberBlocks; block++) {
if ((numberBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
- Collector::markCell(reinterpret_cast<JSCell*>(xAsBits));
+ Heap::markCell(reinterpret_cast<JSCell*>(xAsBits));
goto endMarkLoop;
}
}
}
}
-void NEVER_INLINE Collector::markCurrentThreadConservativelyInternal()
+void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal()
{
void* dummy;
void* stackPointer = &dummy;
markStackObjectsConservatively(stackPointer, stackBase);
}
-void Collector::markCurrentThreadConservatively()
+void Heap::markCurrentThreadConservatively()
{
// setjmp forces volatile registers onto the stack
jmp_buf registers;
#endif
}
-void Collector::markOtherThreadConservatively(Thread* thread)
+void Heap::markOtherThreadConservatively(Thread* thread)
{
+ ASSERT(this == JSGlobalData::sharedInstance().heap);
+
suspendThread(thread->platformThread);
PlatformThreadRegisters regs;
#endif
-void Collector::markStackObjectsConservatively()
+void Heap::markStackObjectsConservatively()
{
markCurrentThreadConservatively();
#if USE(MULTIPLE_THREADS)
- for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
- if (!pthread_equal(thread->posixThread, pthread_self())) {
- markOtherThreadConservatively(thread);
+
+ if (this == JSGlobalData::sharedInstance().heap) {
+
+#ifndef NDEBUG
+ // Forbid malloc during the mark phase. Marking a thread suspends it, so
+ // a malloc inside mark() would risk a deadlock with a thread that had been
+ // suspended while holding the malloc lock.
+ fastMallocForbid();
+#endif
+ for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
+ if (!pthread_equal(thread->posixThread, pthread_self()))
+ markOtherThreadConservatively(thread);
}
+#ifndef NDEBUG
+ fastMallocAllow();
+#endif
}
#endif
}
-typedef HashCountedSet<JSCell*> ProtectCountSet;
-
-static ProtectCountSet& protectedValues()
-{
- static ProtectCountSet staticProtectCountSet;
- return staticProtectCountSet;
-}
-
-void Collector::protect(JSValue* k)
+void Heap::protect(JSValue* k)
{
ASSERT(k);
ASSERT(JSLock::lockCount() > 0);
if (JSImmediate::isImmediate(k))
return;
- protectedValues().add(k->asCell());
+ protectedValues.add(k->asCell());
}
-void Collector::unprotect(JSValue* k)
+void Heap::unprotect(JSValue* k)
{
ASSERT(k);
ASSERT(JSLock::lockCount() > 0);
if (JSImmediate::isImmediate(k))
return;
- protectedValues().remove(k->asCell());
+ protectedValues.remove(k->asCell());
}
-void Collector::collectOnMainThreadOnly(JSValue* value)
+void Heap::collectOnMainThreadOnly(JSValue* value)
{
ASSERT(value);
ASSERT(JSLock::lockCount() > 0);
++mainThreadOnlyObjectCount;
}
-void Collector::markProtectedObjects()
+Heap* Heap::heap(const JSValue* v)
+{
+ if (JSImmediate::isImmediate(v))
+ return 0;
+ return Heap::cellBlock(v->asCell())->heap;
+}
+
+void Heap::markProtectedObjects()
{
- ProtectCountSet& protectedValues = KJS::protectedValues();
ProtectCountSet::iterator end = protectedValues.end();
for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) {
JSCell* val = it->first;
}
}
-void Collector::markMainThreadOnlyObjects()
+void Heap::markMainThreadOnlyObjects()
{
#if USE(MULTIPLE_THREADS)
ASSERT(!onMainThread());
}
}
-template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThreadIsMainThread)
+template <Heap::HeapType heapType> size_t Heap::sweep(bool currentThreadIsMainThread)
{
typedef typename HeapConstants<heapType>::Block Block;
typedef typename HeapConstants<heapType>::Cell Cell;
UNUSED_PARAM(currentThreadIsMainThread); // currentThreadIsMainThread is only used in ASSERTs
// SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
- CollectorHeap& heap = heapType == Collector::PrimaryHeap ? primaryHeap : numberHeap;
+ CollectorHeap& heap = heapType == Heap::PrimaryHeap ? primaryHeap : numberHeap;
size_t emptyBlocks = 0;
size_t numLiveObjects = heap.numLiveObjects;
if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
Cell* cell = curBlock->cells + i;
- if (heapType != Collector::NumberHeap) {
+ if (heapType != Heap::NumberHeap) {
JSCell* imp = reinterpret_cast<JSCell*>(cell);
// special case for allocated but uninitialized object
// (We don't need this check earlier because nothing prior this point
ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
if (curBlock->collectOnMainThreadOnly.get(i)) {
curBlock->collectOnMainThreadOnly.clear(i);
- --Collector::mainThreadOnlyObjectCount;
+ --mainThreadOnlyObjectCount;
}
imp->~JSCell();
}
++minimumCellsToProcess;
} else {
if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
- if (heapType != Collector::NumberHeap) {
+ if (heapType != Heap::NumberHeap) {
JSCell* imp = reinterpret_cast<JSCell*>(cell);
ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
if (curBlock->collectOnMainThreadOnly.get(i)) {
curBlock->collectOnMainThreadOnly.clear(i);
- --Collector::mainThreadOnlyObjectCount;
+ --mainThreadOnlyObjectCount;
}
imp->~JSCell();
}
return numLiveObjects;
}
-bool Collector::collect()
+bool Heap::collect()
{
- ASSERT(JSLock::lockCount() > 0);
- ASSERT(JSLock::currentThreadIsHoldingLock());
+#ifndef NDEBUG
+ if (JSGlobalData::sharedInstance().heap == this) {
+ ASSERT(JSLock::lockCount() > 0);
+ ASSERT(JSLock::currentThreadIsHoldingLock());
+ }
+#endif
ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation));
if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation))
// MARK: first mark all referenced objects recursively starting out from the set of root objects
-#ifndef NDEBUG
- // Forbid malloc during the mark phase. Marking a thread suspends it, so
- // a malloc inside mark() would risk a deadlock with a thread that had been
- // suspended while holding the malloc lock.
- fastMallocForbid();
-#endif
-
markStackObjectsConservatively();
markProtectedObjects();
if (m_markListSet && m_markListSet->size())
markMainThreadOnlyObjects();
#endif
-#ifndef NDEBUG
- fastMallocAllow();
-#endif
-
size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
size_t numLiveObjects = sweep<PrimaryHeap>(currentThreadIsMainThread);
numLiveObjects += sweep<NumberHeap>(currentThreadIsMainThread);
return numLiveObjects < originalLiveObjects;
}
-size_t Collector::size()
+size_t Heap::size()
{
return primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
}
-size_t Collector::globalObjectCount()
+size_t Heap::globalObjectCount()
{
size_t count = 0;
if (JSGlobalObject::head()) {
return count;
}
-size_t Collector::protectedGlobalObjectCount()
+size_t Heap::protectedGlobalObjectCount()
{
size_t count = 0;
if (JSGlobalObject::head()) {
JSGlobalObject* o = JSGlobalObject::head();
do {
- if (protectedValues().contains(o))
+ if (protectedValues.contains(o))
++count;
o = o->next();
} while (o != JSGlobalObject::head());
return count;
}
-size_t Collector::protectedObjectCount()
+size_t Heap::protectedObjectCount()
{
- return protectedValues().size();
+ return protectedValues.size();
}
static const char* typeName(JSCell* val)
return name;
}
-HashCountedSet<const char*>* Collector::protectedObjectTypeCounts()
+HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
{
HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
- ProtectCountSet& protectedValues = KJS::protectedValues();
ProtectCountSet::iterator end = protectedValues.end();
for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it)
counts->add(typeName(it->first));
return counts;
}
-bool Collector::isBusy()
+bool Heap::isBusy()
{
return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
}
/*
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
* Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 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
#include <string.h>
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
namespace KJS {
class JSValue;
class ArgList;
- class Collector {
+ enum OperationInProgress { NoOperation, Allocation, Collection };
+
+ struct CollectorHeap {
+ CollectorBlock** blocks;
+ size_t numBlocks;
+ size_t usedBlocks;
+ size_t firstBlockWithPossibleSpace;
+
+ size_t numLiveObjects;
+ size_t numLiveObjectsAtLastCollect;
+ size_t extraCost;
+
+ OperationInProgress operationInProgress;
+ };
+
+ class Heap : Noncopyable {
public:
class Thread;
enum HeapType { PrimaryHeap, NumberHeap };
// one file, so the heapAllocate template definitions are available.
// However, allocateNumber is used via jsNumberCell outside JavaScriptCore.
// Thus allocateNumber needs to provide a non-inline version too.
- static void* allocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
- static void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
-#else
- static void* allocate(size_t);
+ void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
+ void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
#endif
- static void* allocateNumber(size_t s);
+ void* allocateNumber(size_t);
+ void* allocate(size_t);
- static bool collect();
- static bool isBusy(); // true if an allocation or collection is in progress
+ bool collect();
+ bool isBusy(); // true if an allocation or collection is in progress
static const size_t minExtraCostSize = 256;
- static void reportExtraMemoryCost(size_t cost);
+ void reportExtraMemoryCost(size_t cost);
+
+ size_t size();
- static size_t size();
+ void protect(JSValue*);
+ void unprotect(JSValue*);
- static void protect(JSValue*);
- static void unprotect(JSValue*);
-
- static void collectOnMainThreadOnly(JSValue*);
+ void collectOnMainThreadOnly(JSValue*);
- static size_t globalObjectCount();
- static size_t protectedObjectCount();
- static size_t protectedGlobalObjectCount();
- static HashCountedSet<const char*>* protectedObjectTypeCounts();
+ static Heap* heap(const JSValue*); // 0 for immediate values
+
+ size_t globalObjectCount();
+ size_t protectedObjectCount();
+ size_t protectedGlobalObjectCount();
+ HashCountedSet<const char*>* protectedObjectTypeCounts();
- static void registerThread();
-
static void registerAsMainThread();
+ static void registerThread(); // Should only be called by clients that can use the same heap from multiple threads.
+
+#if PLATFORM(DARWIN)
+ void initializeHeapIntrospector();
+#endif
static bool isCellMarked(const JSCell*);
static void markCell(JSCell*);
- static void markStackObjectsConservatively(void* start, void* end);
+ void markStackObjectsConservatively(void* start, void* end);
- static HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
+ HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
private:
- template <Collector::HeapType heapType> static void* heapAllocate(size_t s);
- template <Collector::HeapType heapType> static size_t sweep(bool);
+ template <Heap::HeapType heapType> void* heapAllocate(size_t);
+ template <Heap::HeapType heapType> size_t sweep(bool);
static const CollectorBlock* cellBlock(const JSCell*);
static CollectorBlock* cellBlock(JSCell*);
static size_t cellOffset(const JSCell*);
- Collector();
+ Heap();
+ friend class JSGlobalData;
+
+ void recordExtraCost(size_t);
+ void markProtectedObjects();
+ void markMainThreadOnlyObjects();
+ void markCurrentThreadConservatively();
+ void markCurrentThreadConservativelyInternal();
+ void markOtherThreadConservatively(Thread*);
+ void markStackObjectsConservatively();
- static void recordExtraCost(size_t);
- static void markProtectedObjects();
- static void markMainThreadOnlyObjects();
- static void markCurrentThreadConservatively();
- static void markCurrentThreadConservativelyInternal();
- static void markOtherThreadConservatively(Thread*);
- static void markStackObjectsConservatively();
+ typedef HashCountedSet<JSCell*> ProtectCountSet;
- static size_t mainThreadOnlyObjectCount;
- static bool memoryFull;
+ const size_t m_pagesize;
- static HashSet<ArgList*>* m_markListSet;
+ size_t mainThreadOnlyObjectCount;
+ CollectorHeap primaryHeap;
+ CollectorHeap numberHeap;
+ ProtectCountSet protectedValues;
+ HashSet<ArgList*>* m_markListSet;
};
// tunable parameters
CollectorCell* freeList;
CollectorBitmap marked;
CollectorBitmap collectOnMainThreadOnly;
+ Heap* heap;
};
class SmallCellCollectorBlock {
SmallCollectorCell* freeList;
CollectorBitmap marked;
CollectorBitmap collectOnMainThreadOnly;
+ Heap* heap;
};
- enum OperationInProgress { NoOperation, Allocation, Collection };
-
- struct CollectorHeap {
- CollectorBlock** blocks;
- size_t numBlocks;
- size_t usedBlocks;
- size_t firstBlockWithPossibleSpace;
-
- size_t numLiveObjects;
- size_t numLiveObjectsAtLastCollect;
- size_t extraCost;
-
- OperationInProgress operationInProgress;
- };
-
- inline const CollectorBlock* Collector::cellBlock(const JSCell* cell)
+ inline const CollectorBlock* Heap::cellBlock(const JSCell* cell)
{
return reinterpret_cast<const CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
}
- inline CollectorBlock* Collector::cellBlock(JSCell* cell)
+ inline CollectorBlock* Heap::cellBlock(JSCell* cell)
{
return const_cast<CollectorBlock*>(cellBlock(const_cast<const JSCell*>(cell)));
}
- inline size_t Collector::cellOffset(const JSCell* cell)
+ inline size_t Heap::cellOffset(const JSCell* cell)
{
return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
}
- inline bool Collector::isCellMarked(const JSCell* cell)
+ inline bool Heap::isCellMarked(const JSCell* cell)
{
return cellBlock(cell)->marked.get(cellOffset(cell));
}
- inline void Collector::markCell(JSCell* cell)
+ inline void Heap::markCell(JSCell* cell)
{
cellBlock(cell)->marked.set(cellOffset(cell));
}
- inline void Collector::reportExtraMemoryCost(size_t cost)
+ inline void Heap::reportExtraMemoryCost(size_t cost)
{
if (cost > minExtraCostSize)
recordExtraCost(cost / (CELL_SIZE * 2));
enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
-static JSCell* formatLocaleDate(const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
{
static const char* formatStrings[] = {"%#c", "%#x", "%X"};
size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
if ( ret == 0 )
- return jsString("");
+ return jsString(exec, "");
// Copy original into the buffer
if (yearNeedsOffset && format != LocaleTime) {
strncpy(yearLocation, yearString, yearLen - 1);
}
- return jsString(timebuffer);
+ return jsString(exec, timebuffer);
}
#endif // PLATFORM(WIN_OS)
*/
// ECMA 15.9.4
-DatePrototype::DatePrototype(ExecState *, ObjectPrototype *objectProto)
- : DateInstance(objectProto)
+DatePrototype::DatePrototype(ExecState* exec, ObjectPrototype* objectProto)
+ : DateInstance(objectProto)
{
- setInternalValue(jsNaN());
+ setInternalValue(jsNaN(exec));
// The constructor will be added later, after DateConstructor has been built.
}
: InternalFunction(funcProto, Identifier(exec, dateProto->classInfo()->className))
{
putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly);
- putDirectFunction(new DateFunction(exec, funcProto, DateFunction::Parse, 1, exec->propertyNames().parse), DontEnum);
- putDirectFunction(new DateFunction(exec, funcProto, DateFunction::UTC, 7, exec->propertyNames().UTC), DontEnum);
- putDirectFunction(new DateFunction(exec, funcProto, DateFunction::Now, 0, exec->propertyNames().now), DontEnum);
- putDirect(exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
+ putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Parse, 1, exec->propertyNames().parse), DontEnum);
+ putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::UTC, 7, exec->propertyNames().UTC), DontEnum);
+ putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Now, 0, exec->propertyNames().now), DontEnum);
+ putDirect(exec, exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
}
ConstructType DateConstructor::getConstructData(ConstructData&)
}
}
- DateInstance *ret = new DateInstance(exec->lexicalGlobalObject()->datePrototype());
- ret->setInternalValue(jsNumber(timeClip(value)));
+ DateInstance* ret = new (exec) DateInstance(exec->lexicalGlobalObject()->datePrototype());
+ ret->setInternalValue(jsNumber(exec, timeClip(value)));
return ret;
}
// ECMA 15.9.2
-JSValue *DateConstructor::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const ArgList &/*args*/)
+JSValue* DateConstructor::callAsFunction(ExecState* exec, JSObject * /*thisObj*/, const ArgList &/*args*/)
{
time_t localTime = time(0);
tm localTM;
getLocalTime(&localTime, &localTM);
GregorianDateTime ts(localTM);
- return jsString(formatDate(ts) + " " + formatTime(ts, false));
+ return jsString(exec, formatDate(ts) + " " + formatTime(ts, false));
}
// ------------------------------ DateFunction ----------------------------
DateFunction::DateFunction(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
: InternalFunction(funcProto, name), id(i)
{
- putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
+ putDirect(exec, exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
}
// ECMA 15.9.4.2 - 3
JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
{
if (id == Parse)
- return jsNumber(parseDate(args[0]->toString(exec)));
+ return jsNumber(exec, parseDate(args[0]->toString(exec)));
else if (id == Now)
- return jsNumber(getCurrentUTCTime());
+ return jsNumber(exec, getCurrentUTCTime());
else { // UTC
int n = args.size();
if (isnan(args[0]->toNumber(exec))
|| (n >= 5 && isnan(args[4]->toNumber(exec)))
|| (n >= 6 && isnan(args[5]->toNumber(exec)))
|| (n >= 7 && isnan(args[6]->toNumber(exec)))) {
- return jsNaN();
+ return jsNaN(exec);
}
GregorianDateTime t;
t.minute = args[4]->toInt32(exec);
t.second = args[5]->toInt32(exec);
double ms = (n >= 7) ? args[6]->toNumber(exec) : 0;
- return jsNumber(gregorianDateTimeToMS(t, ms, true));
+ return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
}
}
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsString(formatDate(t) + " " + formatTime(t, utc));
+ return jsString(exec, formatDate(t) + " " + formatTime(t, utc));
}
JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsString(formatDateUTCVariant(t) + " " + formatTime(t, utc));
+ return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsString(formatDate(t));
+ return jsString(exec, formatDate(t));
}
JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsString(formatTime(t, utc));
+ return jsString(exec, formatTime(t, utc));
}
JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList& args)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
#if PLATFORM(MAC)
double secs = floor(milli / msPerSecond);
- return jsString(formatLocaleDate(exec, secs, true, true, args));
+ return jsString(exec, formatLocaleDate(exec, secs, true, true, args));
#else
UNUSED_PARAM(args);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(t, LocaleDateAndTime);
+ return formatLocaleDate(exec, t, LocaleDateAndTime);
#endif
}
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
#if PLATFORM(MAC)
double secs = floor(milli / msPerSecond);
- return jsString(formatLocaleDate(exec, secs, true, false, args));
+ return jsString(exec, formatLocaleDate(exec, secs, true, false, args));
#else
UNUSED_PARAM(args);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(t, LocaleDate);
+ return formatLocaleDate(exec, t, LocaleDate);
#endif
}
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
#if PLATFORM(MAC)
double secs = floor(milli / msPerSecond);
- return jsString(formatLocaleDate(exec, secs, false, true, args));
+ return jsString(exec, formatLocaleDate(exec, secs, false, true, args));
#else
UNUSED_PARAM(args);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return formatLocaleDate(t, LocaleTime);
+ return formatLocaleDate(exec, t, LocaleTime);
#endif
}
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
- return jsNumber(milli);
+ return jsNumber(exec, milli);
}
JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
- return jsNumber(milli);
+ return jsNumber(exec, milli);
}
JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(1900 + t.year);
+ return jsNumber(exec, 1900 + t.year);
}
JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(1900 + t.year);
+ return jsNumber(exec, 1900 + t.year);
}
JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsString("Invalid Date");
+ return jsString(exec, "Invalid Date");
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsString(formatDateUTCVariant(t) + " " + formatTime(t, utc));
+ return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
}
JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.month);
+ return jsNumber(exec, t.month);
}
JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.month);
+ return jsNumber(exec, t.month);
}
JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.monthDay);
+ return jsNumber(exec, t.monthDay);
}
JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.monthDay);
+ return jsNumber(exec, t.monthDay);
}
JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.weekDay);
+ return jsNumber(exec, t.weekDay);
}
JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.weekDay);
+ return jsNumber(exec, t.weekDay);
}
JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.hour);
+ return jsNumber(exec, t.hour);
}
JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.hour);
+ return jsNumber(exec, t.hour);
}
JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.minute);
+ return jsNumber(exec, t.minute);
}
JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.minute);
+ return jsNumber(exec, t.minute);
}
JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.second);
+ return jsNumber(exec, t.second);
}
JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(t.second);
+ return jsNumber(exec, t.second);
}
JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
double secs = floor(milli / msPerSecond);
double ms = milli - secs * msPerSecond;
- return jsNumber(ms);
+ return jsNumber(exec, ms);
}
JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
double secs = floor(milli / msPerSecond);
double ms = milli - secs * msPerSecond;
- return jsNumber(ms);
+ return jsNumber(exec, ms);
}
JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject* thisObj, const ArgList&)
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
- return jsNumber(-gmtoffset(t) / minutesPerHour);
+ return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
}
JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject* thisObj, const ArgList& args)
DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
double milli = timeClip(args[0]->toNumber(exec));
- JSValue* result = jsNumber(milli);
+ JSValue* result = jsNumber(exec, milli);
thisDateObj->setInternalValue(result);
return result;
}
double milli = v->toNumber(exec);
if (args.isEmpty() || isnan(milli)) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
if (args.isEmpty()) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
}
if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
- JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
+ JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
thisDateObj->setInternalValue(result);
return result;
}
DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
if (args.isEmpty()) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
bool ok = true;
int32_t year = args[0]->toInt32(exec, ok);
if (!ok) {
- JSValue* result = jsNaN();
+ JSValue* result = jsNaN(exec);
thisDateObj->setInternalValue(result);
return result;
}
t.year = (year > 99 || year < 0) ? year - 1900 : year;
- JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, utc));
+ JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
thisDateObj->setInternalValue(result);
return result;
}
JSValue* v = thisDateObj->internalValue();
double milli = v->toNumber(exec);
if (isnan(milli))
- return jsNaN();
+ return jsNaN(exec);
GregorianDateTime t;
thisDateObj->msToGregorianDateTime(milli, utc, t);
// NOTE: IE returns the full year even in getYear.
- return jsNumber(t.year);
+ return jsNumber(exec, t.year);
}
} // namespace KJS
{
// The constructor will be added later in ErrorConstructor's constructor
- putDirect(exec->propertyNames().name, jsString("Error"), DontEnum);
- putDirect(exec->propertyNames().message, jsString("Unknown error"), DontEnum);
+ putDirect(exec->propertyNames().name, jsString(exec, "Error"), DontEnum);
+ putDirect(exec->propertyNames().message, jsString(exec, "Unknown error"), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
}
JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
// Mozilla compatible format
s += ": " + v->toString(exec);
- return jsString(s);
+ return jsString(exec, s);
}
// ------------------------------ ErrorConstructor -------------------------------
{
// ECMA 15.11.3.1 Error.prototype
putDirect(exec->propertyNames().prototype, errorProto, DontEnum|DontDelete|ReadOnly);
- putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
}
ConstructType ErrorConstructor::getConstructData(ConstructData&)
JSObject* ErrorConstructor::construct(ExecState* exec, const ArgList& args)
{
JSObject* proto = static_cast<JSObject*>(exec->lexicalGlobalObject()->errorPrototype());
- JSObject* imp = new ErrorInstance(proto);
+ JSObject* imp = new (exec) ErrorInstance(proto);
JSObject* obj(imp);
if (!args[0]->isUndefined())
- imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
+ imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
return obj;
}
NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, ErrorPrototype* errorProto, const UString& name, const UString& message)
: JSObject(errorProto)
{
- putDirect(exec->propertyNames().name, jsString(name), 0);
- putDirect(exec->propertyNames().message, jsString(message), 0);
+ putDirect(exec->propertyNames().name, jsString(exec, name), 0);
+ putDirect(exec->propertyNames().message, jsString(exec, message), 0);
}
// ------------------------------ NativeErrorConstructor -------------------------------
: InternalFunction(funcProto, Identifier(exec, prot->getDirect(exec->propertyNames().name)->getString()))
, proto(prot)
{
- putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum);
}
JSObject* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
{
- JSObject* imp = new ErrorInstance(proto);
+ JSObject* imp = new (exec) ErrorInstance(proto);
JSObject* obj(imp);
if (!args[0]->isUndefined())
- imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
+ imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
return obj;
}
namespace KJS {
+ class ExecState;
+
class Identifier {
friend class PropertyMap;
public:
inline StringObject* StringObject::create(ExecState* exec, JSString* string)
{
- return new StringObject(exec->lexicalGlobalObject()->stringPrototype(), string);
+ return new (exec) StringObject(exec->lexicalGlobalObject()->stringPrototype(), string);
}
JSObject* JSString::toObject(ExecState* exec) const
return StringObject::create(exec, const_cast<JSString*>(this));
}
-JSValue* JSString::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSString::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
- return jsNumber(static_cast<JSString*>(slot.slotBase())->value().size());
+ return jsNumber(exec, static_cast<JSString*>(slot.slotBase())->value().size());
}
-JSValue* JSString::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSString::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
{
- return jsString(static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
+ return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
}
-JSValue* JSString::indexNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
+JSValue* JSString::indexNumericPropertyGetter(ExecState* exec, unsigned index, const PropertySlot& slot)
{
- return jsString(static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
+ return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
}
bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
#include "JSGlobalObject.h"
#include "Machine.h"
#include "Parser.h"
+#include "completion.h"
#include "debugger.h"
#include <profiler/Profiler.h>
#include <stdio.h>
#include "config.h"
#include "list.h"
+#include "JSValue.h"
+
using std::min;
namespace KJS {
if (!m_markSet) {
// We can only register for explicit marking once we know which heap
// is the current one, i.e., when a non-immediate value is appended.
- if (!JSImmediate::isImmediate(v)) { // Will be: if (Heap* heap = Heap::heap(v))
- ListSet& markSet = Collector::markListSet();
+ if (Heap* heap = Heap::heap(v)) {
+ ListSet& markSet = heap->markListSet();
markSet.add(this);
m_markSet = &markSet;
}
/*
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- * Copyright (C) 2003, 2007 Apple Computer, Inc.
+ * Copyright (C) 2003, 2007, 2008 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
#ifndef KJS_LIST_H
#define KJS_LIST_H
-#include <kjs/JSValue.h>
+#include "JSImmediate.h"
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
#include <wtf/Vector.h>
void slowAppend(JSValue*);
JSValue** buffer() const { return *m_bufferSlot + m_offset; }
-
+
JSValue*** m_bufferSlot;
size_t m_offset;
size_t m_size;
return cachedVal;
const HashEntry* entry = slot.staticEntry();
- JSValue* val = new PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
+ JSValue* val = new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
thisObj->putDirect(propertyName, val, entry->attributes);
return val;
}
ASSERT(obj->isObject());
return static_cast<JSObject* >(obj);
}
- JSObject* newObject = new ClassCtor(exec);
+ JSObject* newObject = new (exec) ClassCtor(exec);
globalObject->putDirect(propertyName, newObject, DontEnum);
return newObject;
}
RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
{
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(msg));
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), msg));
generator.emitThrow(exception);
return exception;
}
{
UString message = msg;
substitute(message, label.ustring());
- RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(message));
+ RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), message));
generator.emitThrow(exception);
return exception;
}
RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
{
// FIXME: should we try to atomize constant strings?
- return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(m_value));
+ return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(generator.globalExec(), m_value));
}
// ------------------------------ RegExpNode -----------------------------------
generator.emitPutByIndex(newArray.get(), length++, value);
}
- value = generator.emitLoad(generator.newTemporary(), jsNumber(m_elision + length));
+ value = generator.emitLoad(generator.newTemporary(), jsNumber(generator.globalExec(), m_elision + length));
generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
return generator.moveToDestinationIfNeeded(dst, newArray.get());
JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
{
- JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
+ JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
- func->putDirect(exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
+ func->putDirect(exec->propertyNames().length, jsNumber(exec, m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
return func;
}
JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
{
- JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
+ JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
*/
if (!m_ident.isNull()) {
- JSObject* functionScopeObject = new JSObject;
+ JSObject* functionScopeObject = new (exec) JSObject;
functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
func->scope().push(functionScopeObject);
}
#define NODES_H_
#include "JSString.h"
+#include "LabelStack.h"
#include "Opcode.h"
#include "regexp.h"
#include "RegisterID.h"
ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
: JSObject() // [[Prototype]] is null
{
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
// Mozilla extensions
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
- putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
+ putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
}
JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
{
- return jsString(thisObj->toString(exec));
+ return jsString(exec, thisObj->toString(exec));
}
-JSValue* objectProtoFuncToString(ExecState*, JSObject* thisObj, const ArgList&)
+JSValue* objectProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
{
- return jsString("[object " + thisObj->className() + "]");
+ return jsString(exec, "[object " + thisObj->className() + "]");
}
// ------------------------------ ObjectConstructor --------------------------------
putDirect(exec->propertyNames().prototype, objProto, DontEnum|DontDelete|ReadOnly);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
ConstructType ObjectConstructor::getConstructData(ConstructData&)
return arg->toObject(exec);
case NullType:
case UndefinedType:
- return new JSObject(exec->lexicalGlobalObject()->objectPrototype());
+ return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
default:
ASSERT_NOT_REACHED();
return 0;
namespace KJS {
- inline void gcProtect(JSValue *val)
- {
- Collector::protect(val);
+ inline void gcProtect(JSValue* val)
+ {
+ Heap* heap = Heap::heap(val);
+ if (heap)
+ heap->protect(val);
}
- inline void gcUnprotect(JSValue *val)
- {
- Collector::unprotect(val);
+ inline void gcUnprotect(JSValue* val)
+ {
+ Heap* heap = Heap::heap(val);
+ if (heap)
+ heap->unprotect(val);
}
inline void gcProtectNullTolerant(JSValue *val)
const ClassInfo StringObject::info = { "String", 0, 0, 0 };
-StringObject::StringObject(JSObject *proto)
+StringObject::StringObject(ExecState* exec, JSObject* proto)
: JSWrapperObject(proto)
{
- setInternalValue(jsString(""));
+ setInternalValue(jsString(exec, ""));
}
-StringObject::StringObject(JSObject *proto, JSString* string)
+StringObject::StringObject(JSObject* proto, JSString* string)
: JSWrapperObject(proto)
{
setInternalValue(string);
}
-StringObject::StringObject(JSObject *proto, const UString &string)
+StringObject::StringObject(ExecState* exec, JSObject* proto, const UString& string)
: JSWrapperObject(proto)
{
- setInternalValue(jsString(string));
+ setInternalValue(jsString(exec, string));
}
bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
*/
// ECMA 15.5.4
StringPrototype::StringPrototype(ExecState* exec, ObjectPrototype* objProto)
- : StringObject(objProto)
+ : StringObject(exec, objProto)
{
// The constructor will be added later, after StringConstructor has been built
- putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
}
bool StringPrototype::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
if (matchStart < 0)
args.append(jsUndefined());
else
- args.append(jsString(source.substr(matchStart, matchLen)));
+ args.append(jsString(exec, source.substr(matchStart, matchLen)));
}
- args.append(jsNumber(completeMatchStart));
+ args.append(jsNumber(exec, completeMatchStart));
args.append(sourceVal);
substitutedReplacement = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
if (result == source)
return sourceVal;
- return jsString(result);
+ return jsString(exec, result);
}
// First arg is a string
if (replacementFunction) {
ArgList args;
- args.append(jsString(source.substr(matchPos, matchLen)));
- args.append(jsNumber(matchPos));
+ args.append(jsString(exec, source.substr(matchPos, matchLen)));
+ args.append(jsNumber(exec, matchPos));
args.append(sourceVal);
replacementString = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
}
- return jsString(source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
+ return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
}
JSValue* stringProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
u = s.substr(static_cast<int>(dpos), 1);
else
u = "";
- return jsString(u);
+ return jsString(exec, u);
}
JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject* thisObj, const ArgList& args)
JSValue* a0 = args[0];
double dpos = a0->toInteger(exec);
if (dpos >= 0 && dpos < len)
- result = jsNumber(s[static_cast<int>(dpos)]);
+ result = jsNumber(exec, s[static_cast<int>(dpos)]);
else
- result = jsNaN();
+ result = jsNaN(exec);
return result;
}
for (ArgList::const_iterator it = args.begin(); it != end; ++it) {
s += (*it)->toString(exec);
}
- return jsString(s);
+ return jsString(exec, s);
}
JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
dpos = 0;
else if (dpos > len)
dpos = len;
- return jsNumber(s.find(u2, static_cast<int>(dpos)));
+ return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
}
JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
dpos = 0;
else if (!(dpos <= len)) // true for NaN
dpos = len;
- return jsNumber(s.rfind(u2, static_cast<int>(dpos)));
+ return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
}
JSValue* stringProtoFuncMatch(ExecState* exec, JSObject* thisObj, const ArgList& args)
ArgList list;
int lastIndex = 0;
while (pos >= 0) {
- list.append(jsString(u.substr(pos, matchLength)));
+ list.append(jsString(exec, u.substr(pos, matchLength)));
lastIndex = pos;
pos += matchLength == 0 ? 1 : matchLength;
regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
int pos;
int matchLength;
regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
- return jsNumber(pos);
+ return jsNumber(exec, pos);
}
JSValue* stringProtoFuncReplace(ExecState* exec, JSObject* thisObj, const ArgList& args)
JSString* sVal = thisObj->inherits(&StringObject::info) ?
static_cast<StringObject*>(thisObj)->internalValue() :
- static_cast<JSString*>(jsString(s));
+ static_cast<JSString*>(jsString(exec, s));
JSValue* a0 = args[0];
JSValue* a1 = args[1];
from = 0;
if (to > len)
to = len;
- return jsString(s.substr(static_cast<int>(from), static_cast<int>(to - from)));
+ return jsString(exec, s.substr(static_cast<int>(from), static_cast<int>(to - from)));
}
- return jsString("");
+ return jsString(exec, "");
}
JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList& args)
RegExp *reg = static_cast<RegExpObject *>(a0)->regExp();
if (u.isEmpty() && reg->match(u, 0) >= 0) {
// empty string matched by regexp -> empty array
- res->put(exec, exec->propertyNames().length, jsNumber(0));
+ res->put(exec, exec->propertyNames().length, jsNumber(exec, 0));
return result;
}
pos = 0;
int mlen = ovector[1] - ovector[0];
pos = mpos + (mlen == 0 ? 1 : mlen);
if (mpos != p0 || mlen) {
- res->put(exec,i, jsString(u.substr(p0, mpos-p0)));
+ res->put(exec,i, jsString(exec, u.substr(p0, mpos-p0)));
p0 = mpos + mlen;
i++;
}
if (spos < 0)
res->put(exec, i++, jsUndefined());
else
- res->put(exec, i++, jsString(u.substr(spos, ovector[si * 2 + 1] - spos)));
+ res->put(exec, i++, jsString(exec, u.substr(spos, ovector[si * 2 + 1] - spos)));
}
}
} else {
if (u2.isEmpty()) {
if (u.isEmpty()) {
// empty separator matches empty string -> empty array
- res->put(exec, exec->propertyNames().length, jsNumber(0));
+ res->put(exec, exec->propertyNames().length, jsNumber(exec, 0));
return result;
} else {
while (static_cast<uint32_t>(i) != limit && i < u.size()-1)
- res->put(exec, i++, jsString(u.substr(p0++, 1)));
+ res->put(exec, i++, jsString(exec, u.substr(p0++, 1)));
}
} else {
while (static_cast<uint32_t>(i) != limit && (pos = u.find(u2, p0)) >= 0) {
- res->put(exec, i, jsString(u.substr(p0, pos-p0)));
+ res->put(exec, i, jsString(exec, u.substr(p0, pos - p0)));
p0 = pos + u2.size();
i++;
}
}
// add remaining string, if any
if (static_cast<uint32_t>(i) != limit)
- res->put(exec, i++, jsString(u.substr(p0)));
- res->put(exec, exec->propertyNames().length, jsNumber(i));
+ res->put(exec, i++, jsString(exec, u.substr(p0)));
+ res->put(exec, exec->propertyNames().length, jsNumber(exec, i));
return result;
}
double start = a0->toInteger(exec);
double length = a1->isUndefined() ? len : a1->toInteger(exec);
if (start >= len)
- return jsString("");
+ return jsString(exec, "");
if (length < 0)
- return jsString("");
+ return jsString(exec, "");
if (start < 0) {
start += len;
if (start < 0)
}
if (length > len)
length = len;
- return jsString(s.substr(static_cast<int>(start), static_cast<int>(length)));
+ return jsString(exec, s.substr(static_cast<int>(start), static_cast<int>(length)));
}
JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject* thisObj, const ArgList& args)
end = start;
start = temp;
}
- return jsString(s.substr((int)start, (int)end-(int)start));
+ return jsString(exec, s.substr((int)start, (int)end-(int)start));
}
JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
JSString* sVal = thisObj->inherits(&StringObject::info)
? static_cast<StringObject*>(thisObj)->internalValue()
- : static_cast<JSString*>(jsString(s));
+ : static_cast<JSString*>(jsString(exec, s));
int ssize = s.size();
if (!ssize)
return sVal;
}
if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
return sVal;
- return jsString(UString(buffer.releaseBuffer(), length, false));
+ return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
JSString* sVal = thisObj->inherits(&StringObject::info)
? static_cast<StringObject*>(thisObj)->internalValue()
- : static_cast<JSString*>(jsString(s));
+ : static_cast<JSString*>(jsString(exec, s));
int ssize = s.size();
if (!ssize)
return sVal;
}
if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
return sVal;
- return jsString(UString(buffer.releaseBuffer(), length, false));
+ return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
// FIXME: See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt for locale-sensitive mappings that aren't implemented.
JSString* sVal = thisObj->inherits(&StringObject::info)
? static_cast<StringObject*>(thisObj)->internalValue()
- : static_cast<JSString*>(jsString(s));
+ : static_cast<JSString*>(jsString(exec, s));
int ssize = s.size();
if (!ssize)
return sVal;
}
if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
return sVal;
- return jsString(UString(buffer.releaseBuffer(), length, false));
+ return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
JSString* sVal = thisObj->inherits(&StringObject::info)
? static_cast<StringObject*>(thisObj)->internalValue()
- : static_cast<JSString*>(jsString(s));
+ : static_cast<JSString*>(jsString(exec, s));
int ssize = s.size();
if (!ssize)
return sVal;
}
if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
return sVal;
- return jsString(UString(buffer.releaseBuffer(), length, false));
+ return jsString(exec, UString(buffer.releaseBuffer(), length, false));
}
JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject* thisObj, const ArgList& args)
{
if (args.size() < 1)
- return jsNumber(0);
+ return jsNumber(exec, 0);
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
JSValue* a0 = args[0];
- return jsNumber(localeCompare(s, a0->toString(exec)));
+ return jsNumber(exec, localeCompare(s, a0->toString(exec)));
}
JSValue* stringProtoFuncBig(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<big>" + s + "</big>");
+ return jsString(exec, "<big>" + s + "</big>");
}
JSValue* stringProtoFuncSmall(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<small>" + s + "</small>");
+ return jsString(exec, "<small>" + s + "</small>");
}
JSValue* stringProtoFuncBlink(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<blink>" + s + "</blink>");
+ return jsString(exec, "<blink>" + s + "</blink>");
}
JSValue* stringProtoFuncBold(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<b>" + s + "</b>");
+ return jsString(exec, "<b>" + s + "</b>");
}
JSValue* stringProtoFuncFixed(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<tt>" + s + "</tt>");
+ return jsString(exec, "<tt>" + s + "</tt>");
}
JSValue* stringProtoFuncItalics(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<i>" + s + "</i>");
+ return jsString(exec, "<i>" + s + "</i>");
}
JSValue* stringProtoFuncStrike(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<strike>" + s + "</strike>");
+ return jsString(exec, "<strike>" + s + "</strike>");
}
JSValue* stringProtoFuncSub(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<sub>" + s + "</sub>");
+ return jsString(exec, "<sub>" + s + "</sub>");
}
JSValue* stringProtoFuncSup(ExecState* exec, JSObject* thisObj, const ArgList&)
{
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
- return jsString("<sup>" + s + "</sup>");
+ return jsString(exec, "<sup>" + s + "</sup>");
}
JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject* thisObj, const ArgList& args)
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
JSValue* a0 = args[0];
- return jsString("<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
+ return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
}
JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject* thisObj, const ArgList& args)
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
JSValue* a0 = args[0];
- return jsString("<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
+ return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
}
JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject* thisObj, const ArgList& args)
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
JSValue* a0 = args[0];
- return jsString("<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
+ return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
}
JSValue* stringProtoFuncLink(ExecState* exec, JSObject* thisObj, const ArgList& args)
// This optimizes the common case that thisObj is a StringObject
UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
JSValue* a0 = args[0];
- return jsString("<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
+ return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
}
// ------------------------------ StringConstructor ------------------------------
// ECMA 15.5.3.1 String.prototype
putDirect(exec->propertyNames().prototype, stringProto, DontEnum|DontDelete|ReadOnly);
- putDirectFunction(new StringConstructorFunction(exec, funcProto, exec->propertyNames().fromCharCode), DontEnum);
+ putDirectFunction(new (exec) StringConstructorFunction(exec, funcProto, exec->propertyNames().fromCharCode), DontEnum);
// no. of arguments for constructor
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
}
// ECMA 15.5.2
-JSObject *StringConstructor::construct(ExecState *exec, const ArgList &args)
+JSObject* StringConstructor::construct(ExecState* exec, const ArgList& args)
{
- JSObject *proto = exec->lexicalGlobalObject()->stringPrototype();
- if (args.size() == 0)
- return new StringObject(proto);
- return new StringObject(proto, args[0]->toString(exec));
+ JSObject* proto = exec->lexicalGlobalObject()->stringPrototype();
+ if (!args.size())
+ return new (exec) StringObject(exec, proto);
+ return new (exec) StringObject(exec, proto, args[0]->toString(exec));
}
// ECMA 15.5.1
JSValue *StringConstructor::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
{
if (args.isEmpty())
- return jsString("");
+ return jsString(exec, "");
else {
JSValue *v = args[0];
- return jsString(v->toString(exec));
+ return jsString(exec, v->toString(exec));
}
}
StringConstructorFunction::StringConstructorFunction(ExecState* exec, FunctionPrototype* funcProto, const Identifier& name)
: InternalFunction(funcProto, name)
{
- putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
}
JSValue *StringConstructorFunction::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
} else
s = "";
- return jsString(s);
+ return jsString(exec, s);
}
} // namespace KJS
class StringObject : public JSWrapperObject {
public:
- StringObject(JSObject* prototype);
- StringObject(JSObject* prototype, const UString&);
+ StringObject(ExecState*, JSObject* prototype);
+ StringObject(ExecState*, JSObject* prototype, const UString&);
static StringObject* create(ExecState*, JSString*);
// WebCore uses this to make style.filter undetectable
class StringObjectThatMasqueradesAsUndefined : public StringObject {
public:
- StringObjectThatMasqueradesAsUndefined(JSObject* proto, const UString& string)
- : StringObject(proto, string) { }
+ StringObjectThatMasqueradesAsUndefined(ExecState* exec, JSObject* proto, const UString& string)
+ : StringObject(exec, proto, string) { }
virtual bool masqueradeAsUndefined() const { return true; }
virtual bool toBoolean(ExecState*) const { return false; }
};
// huge buffer.
// FIXME: this should be size_t but that would cause warnings until we
// fix UString sizes to be size_t instead of int
-static const int minShareSize = Collector::minExtraCostSize / sizeof(UChar);
+static const int minShareSize = Heap::minExtraCostSize / sizeof(UChar);
inline size_t UString::cost() const
{
+2008-06-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin.
+
+ Prepare JavaScript heap for being per-thread.
+
+ * JSRun.cpp: (JSRun::JSRun): Create JSGlueGlobalObject in a shared JS heap.
+
+ * JSUtils.h: Made getThreadGlobalExecState available throughout JSGlue.
+
+ * JSUtils.cpp:
+ (JSObjectKJSValue): Pass an ExecState where now required.
+ (unprotectGlobalObject):
+ (initializeGlobalObjectKey):
+ (getThreadGlobalExecState):
+ Moved these functions from JSValueWrapper.cpp, as the global exec state is now needed
+ elsewhere. I'm not quite sure how this relates to the global object from JSRun, but
+ since the new uses are all for Heap access, there doesn't seem to be any behavior change.
+
+ * JavaScriptGlue.cpp:
+ (JSLockInterpreter): Don't call registerThread explicitly, as JSLock will do that.
+
+ * UserObjectImp.cpp: (UserObjectImp::toPrimitive): Pass ExecState* where now required.
+
2008-06-17 Mark Rowe <mrowe@apple.com>
Reviewed by Darin Adler.
#include "config.h"
#include "JSRun.h"
+#include <JavaScriptCore/completion.h>
+
JSRun::JSRun(CFStringRef source, JSFlags inFlags)
: JSBase(kJSRunTypeID),
fSource(CFStringToUString(source)),
- fGlobalObject(new JSGlueGlobalObject(inFlags)),
+ fGlobalObject(new (JSGlobalObject::Shared) JSGlueGlobalObject(inFlags)),
fFlags(inFlags)
{
}
CFTypeID typeID = CFGetTypeID(cfType);
if (typeID == CFStringGetTypeID())
{
- result = jsString(CFStringToUString((CFStringRef)cfType));
+ result = jsString(getThreadGlobalExecState(), CFStringToUString((CFStringRef)cfType));
handled = true;
}
else if (typeID == CFNumberGetTypeID())
{
double num;
CFNumberGetValue((CFNumberRef)cfType, kCFNumberDoubleType, &num);
- result = jsNumber(num);
+ result = jsNumber(getThreadGlobalExecState(), num);
handled = true;
}
else if (typeID == CFBooleanGetTypeID())
}
if (!handled)
{
- result = new UserObjectImp(ptr);
+ result = new (getThreadGlobalExecState()) UserObjectImp(ptr);
}
}
return result;
return result;
}
+/*
+ * This is a slight hack. The JSGlue API has no concept of execution state.
+ * However, execution state is an inherent part of JS, and JSCore requires it.
+ * So, we keep a single execution state for the whole thread and supply it
+ * where necessary.
+
+ * The execution state holds two things: (1) exceptions; (2) the global object.
+ * JSGlue has no API for accessing exceptions, so we just discard them. As for
+ * the global object, JSGlue includes no calls that depend on it. Its property
+ * getters and setters are per-object; they don't walk up the enclosing scope.
+ * Functions called by JSObjectCallFunction may reference values in the enclosing
+ * scope, but they do so through an internally stored scope chain, so we don't
+ * need to supply the global scope.
+ */
+
+static pthread_key_t globalObjectKey;
+static pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
+
+static void unprotectGlobalObject(void* data)
+{
+ JSLock lock;
+ gcUnprotect(static_cast<JSGlobalObject*>(data));
+}
+
+static void initializeGlobalObjectKey()
+{
+ pthread_key_create(&globalObjectKey, unprotectGlobalObject);
+}
+
+ExecState* getThreadGlobalExecState()
+{
+ pthread_once(&globalObjectKeyOnce, initializeGlobalObjectKey);
+ JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(pthread_getspecific(globalObjectKey));
+ if (!globalObject) {
+ globalObject = new (JSGlobalObject::Shared) JSGlueGlobalObject;
+ gcProtect(globalObject);
+ pthread_setspecific(globalObjectKey, globalObject);
+ }
+
+ ExecState* exec = globalObject->globalExec();
+
+ // Discard exceptions -- otherwise an exception would forestall JS
+ // evaluation throughout the thread
+ exec->clearException();
+ return exec;
+}
+
inline CFTypeRef RetainCFType(CFTypeRef x) { if (x) x = CFRetain(x); return x; }
inline void ReleaseCFType(CFTypeRef x) { if (x) CFRelease(x); }
+ExecState* getThreadGlobalExecState();
+
enum {
kJSInvalidTypeID = 0,
kJSObjectTypeID,
return fValue;
}
-/*
- * This is a slight hack. The JSGlue API has no concept of execution state.
- * However, execution state is an inherent part of JS, and JSCore requires it.
- * So, we keep a single execution state for the whole thread and supply it
- * where necessary.
-
- * The execution state holds two things: (1) exceptions; (2) the global object.
- * JSGlue has no API for accessing exceptions, so we just discard them. As for
- * the global object, JSGlue includes no calls that depend on it. Its property
- * getters and setters are per-object; they don't walk up the enclosing scope.
- * Functions called by JSObjectCallFunction may reference values in the enclosing
- * scope, but they do so through an internally stored scope chain, so we don't
- * need to supply the global scope.
- */
-
-pthread_key_t globalObjectKey;
-pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
-
-static void unprotectGlobalObject(void* data)
-{
- JSLock lock;
- gcUnprotect(static_cast<JSGlobalObject*>(data));
-}
-
-static void initializeGlobalObjectKey()
-{
- pthread_key_create(&globalObjectKey, unprotectGlobalObject);
-}
-
-static ExecState* getThreadGlobalExecState()
-{
- pthread_once(&globalObjectKeyOnce, initializeGlobalObjectKey);
- JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(pthread_getspecific(globalObjectKey));
- if (!globalObject) {
- globalObject = new JSGlueGlobalObject;
- gcProtect(globalObject);
- pthread_setspecific(globalObjectKey, globalObject);
- }
-
- ExecState* exec = globalObject->globalExec();
-
- // Discard exceptions -- otherwise an exception would forestall JS
- // evaluation throughout the thread
- exec->clearException();
- return exec;
-}
-
void JSValueWrapper::GetJSObectCallBacks(JSObjectCallBacks& callBacks)
{
callBacks.dispose = (JSObjectDisposeProcPtr)JSValueWrapper::JSObjectDispose;
#include "JSBase.h"
#include "JSObject.h"
#include "JSRun.h"
+#include <JavaScriptCore/completion.h>
#include <JavaScriptCore/InitializeThreading.h>
static CFTypeRef sJSCFNullRef = 0;
initializeThreading();
JSLock lock;
- Collector::collect();
+ getThreadGlobalExecState()->heap()->collect();
}
/*
{
initializeThreading();
JSLock::lock();
- JSLock::registerThread();
}
result = jsBoolean(false);
}
} else if (cfType == CFStringGetTypeID()) {
- result = jsString(CFStringToUString((CFStringRef)cfValue));
+ result = jsString(exec, CFStringToUString((CFStringRef)cfValue));
} else if (cfType == CFNumberGetTypeID()) {
double d = 0.0;
CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
- result = jsNumber(d);
+ result = jsNumber(exec, d);
} else if (cfType == CFURLGetTypeID()) {
CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
if (absURL) {
- result = jsString(CFStringToUString(CFURLGetString(absURL)));
+ result = jsString(exec, CFStringToUString(CFURLGetString(absURL)));
ReleaseCFType(absURL);
}
}
+2008-06-17 Alexey Proskuryakov <ap@webkit.org>
+
+ Reviewed by Darin.
+
+ Prepare JavaScript heap for being per-thread.
+
+ * ForwardingHeaders/kjs/JSGlobalData.h: Added.
+ * bindings/js/GCController.cpp:
+ (WebCore::collect):
+ (WebCore::GCController::gcTimerFired):
+ (WebCore::GCController::garbageCollectNow):
+ * bindings/js/JSAudioConstructor.cpp:
+ (WebCore::JSAudioConstructor::JSAudioConstructor):
+ * bindings/js/JSCSSRuleCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+ (WebCore::JSCSSStyleDeclaration::nameGetter):
+ * bindings/js/JSCSSValueCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSCanvasPixelArrayCustom.cpp:
+ (WebCore::JSCanvasPixelArray::indexGetter):
+ (WebCore::toJS):
+ * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSClipboardCustom.cpp:
+ (WebCore::JSClipboard::types):
+ (WebCore::JSClipboard::getData):
+ * bindings/js/JSCustomXPathNSResolver.cpp:
+ (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+ * bindings/js/JSDOMApplicationCacheCustom.cpp:
+ (WebCore::JSDOMApplicationCache::addEventListener):
+ (WebCore::JSDOMApplicationCache::removeEventListener):
+ (WebCore::JSDOMApplicationCache::setOnchecking):
+ (WebCore::JSDOMApplicationCache::setOnerror):
+ (WebCore::JSDOMApplicationCache::setOnnoupdate):
+ (WebCore::JSDOMApplicationCache::setOndownloading):
+ (WebCore::JSDOMApplicationCache::setOnprogress):
+ (WebCore::JSDOMApplicationCache::setOnupdateready):
+ (WebCore::JSDOMApplicationCache::setOncached):
+ * bindings/js/JSDOMBinding.cpp:
+ (WebCore::jsStringOrNull):
+ (WebCore::jsOwnedStringOrNull):
+ (WebCore::jsStringOrUndefined):
+ (WebCore::jsStringOrFalse):
+ (WebCore::nonCachingStaticFunctionGetter):
+ (WebCore::objectToStringFunctionGetter):
+ * bindings/js/JSDOMBinding.h:
+ (WebCore::DOMObject::DOMObject):
+ (WebCore::cacheDOMObject):
+ (WebCore::cacheSVGDOMObject):
+ * bindings/js/JSDOMWindowBase.cpp:
+ (WebCore::JSDOMWindowBase::JSDOMWindowBase):
+ (WebCore::JSDOMWindowBase::getValueProperty):
+ (WebCore::JSDOMWindowBase::setListener):
+ (WebCore::JSDOMWindowBase::findOrCreateJSEventListener):
+ (WebCore::JSDOMWindowBase::findJSUnprotectedEventListener):
+ (WebCore::JSDOMWindowBase::findOrCreateJSUnprotectedEventListener):
+ (WebCore::windowProtoFuncAToB):
+ (WebCore::windowProtoFuncBToA):
+ (WebCore::windowProtoFuncSetTimeout):
+ (WebCore::windowProtoFuncSetInterval):
+ (WebCore::windowProtoFuncAddEventListener):
+ * bindings/js/JSDOMWindowBase.h:
+ * bindings/js/JSDOMWindowShell.cpp:
+ (WebCore::JSDOMWindowShell::operator new):
+ * bindings/js/JSDOMWindowShell.h:
+ * bindings/js/JSDocumentCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSElementCustom.cpp:
+ (WebCore::toJSNewlyCreated):
+ * bindings/js/JSEventCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSEventListener.cpp:
+ (WebCore::JSLazyEventListener::eventParameterName):
+ (WebCore::JSLazyEventListener::parseCode):
+ * bindings/js/JSEventTargetBase.cpp:
+ (WebCore::jsEventTargetAddEventListener):
+ * bindings/js/JSEventTargetBase.h:
+ (WebCore::JSEventTargetPrototype::self):
+ * bindings/js/JSEventTargetNode.cpp:
+ (WebCore::JSEventTargetNode::setListener):
+ * bindings/js/JSHTMLCollectionCustom.cpp:
+ (WebCore::getNamedItems):
+ (WebCore::toJS):
+ * bindings/js/JSHTMLFormElementCustom.cpp:
+ (WebCore::JSHTMLFormElement::nameGetter):
+ * bindings/js/JSHTMLInputElementBase.cpp:
+ (WebCore::JSHTMLInputElementBase::getValueProperty):
+ * bindings/js/JSHTMLOptionElementConstructor.cpp:
+ (WebCore::JSHTMLOptionElementConstructor::JSHTMLOptionElementConstructor):
+ * bindings/js/JSHTMLOptionsCollectionCustom.cpp:
+ (WebCore::JSHTMLOptionsCollection::length):
+ * bindings/js/JSInspectedObjectWrapper.cpp:
+ (WebCore::JSInspectedObjectWrapper::wrap):
+ * bindings/js/JSInspectorCallbackWrapper.cpp:
+ (WebCore::JSInspectorCallbackWrapper::wrap):
+ * bindings/js/JSLocationCustom.cpp:
+ (WebCore::JSLocation::toString):
+ * bindings/js/JSNamedNodesCollection.cpp:
+ (WebCore::JSNamedNodesCollection::lengthGetter):
+ * bindings/js/JSNavigatorCustom.cpp:
+ (WebCore::JSNavigator::appVersion):
+ * bindings/js/JSNodeCustom.cpp:
+ (WebCore::createWrapper):
+ * bindings/js/JSNodeFilterCustom.cpp:
+ (WebCore::JSNodeFilter::acceptNode):
+ * bindings/js/JSPluginElementFunctions.cpp:
+ (WebCore::getRuntimeObject):
+ * bindings/js/JSRGBColor.cpp:
+ (WebCore::getJSRGBColor):
+ * bindings/js/JSSQLResultSetRowListCustom.cpp:
+ (WebCore::JSSQLResultSetRowList::item):
+ * bindings/js/JSSVGLazyEventListener.cpp:
+ (WebCore::JSSVGLazyEventListener::eventParameterName):
+ * bindings/js/JSStorageCustom.cpp:
+ (WebCore::JSStorage::nameGetter):
+ * bindings/js/JSStyleSheetCustom.cpp:
+ (WebCore::toJS):
+ * bindings/js/JSTextCustom.cpp:
+ (WebCore::toJSNewlyCreated):
+ * bindings/js/JSXMLHttpRequestConstructor.cpp:
+ (WebCore::JSXMLHttpRequestConstructor::construct):
+ * bindings/js/JSXMLHttpRequestCustom.cpp:
+ (WebCore::JSXMLHttpRequest::setOnreadystatechange):
+ (WebCore::JSXMLHttpRequest::setOnload):
+ (WebCore::JSXMLHttpRequest::setOnprogress):
+ (WebCore::JSXMLHttpRequest::getResponseHeader):
+ (WebCore::JSXMLHttpRequest::addEventListener):
+ (WebCore::JSXMLHttpRequest::removeEventListener):
+ * bindings/js/JSXSLTProcessorConstructor.cpp:
+ (WebCore::JSXSLTProcessorConstructor::construct):
+ * bindings/js/JSXSLTProcessorCustom.cpp:
+ (WebCore::JSXSLTProcessor::getParameter):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ * bridge/c/c_instance.cpp:
+ (KJS::Bindings::CInstance::defaultValue):
+ (KJS::Bindings::CInstance::stringValue):
+ (KJS::Bindings::CInstance::numberValue):
+ (KJS::Bindings::CInstance::valueOf):
+ * bridge/c/c_instance.h:
+ * bridge/c/c_utility.cpp:
+ (KJS::Bindings::convertNPVariantToValue):
+ * bridge/jni/jni_instance.cpp:
+ (JavaInstance::stringValue):
+ (JavaInstance::numberValue):
+ (JavaInstance::invokeMethod):
+ (JavaInstance::defaultValue):
+ (JavaInstance::valueOf):
+ * bridge/jni/jni_instance.h:
+ * bridge/jni/jni_jsobject.h:
+ * bridge/jni/jni_jsobject.mm:
+ (JavaJSObject::call):
+ (JavaJSObject::setMember):
+ (JavaJSObject::setSlot):
+ (JavaJSObject::convertJObjectToValue):
+ (JavaJSObject::getListFromJArray):
+ * bridge/jni/jni_objc.mm:
+ (KJS::Bindings::dispatchJNICall):
+ * bridge/jni/jni_runtime.cpp:
+ (JavaArray::convertJObjectToArray):
+ (JavaField::dispatchValueFromInstance):
+ (JavaField::valueFromInstance):
+ (JavaField::dispatchSetValueToInstance):
+ (JavaArray::valueAt):
+ * bridge/jni/jni_utility.h:
+ * bridge/objc/objc_class.mm:
+ (KJS::Bindings::ObjcClass::fallbackObject):
+ * bridge/objc/objc_instance.h:
+ * bridge/objc/objc_instance.mm:
+ (ObjcInstance::defaultValue):
+ (ObjcInstance::stringValue):
+ (ObjcInstance::numberValue):
+ (ObjcInstance::valueOf):
+ * bridge/objc/objc_utility.h:
+ * bridge/objc/objc_utility.mm:
+ (KJS::Bindings::convertNSStringToString):
+ (KJS::Bindings::convertObjcValueToValue):
+ * bridge/runtime.cpp:
+ (KJS::Bindings::Instance::createRuntimeObject):
+ * bridge/runtime.h:
+ (KJS::Bindings::Instance::valueOf):
+ * bridge/runtime_array.cpp:
+ (RuntimeArray::lengthGetter):
+ * bridge/runtime_method.cpp:
+ (RuntimeMethod::lengthGetter):
+ * bridge/runtime_object.cpp:
+ (RuntimeObjectImp::RuntimeObjectImp):
+ (RuntimeObjectImp::methodGetter):
+ (RuntimeObjectImp::defaultValue):
+ * dom/make_names.pl:
+ * xml/XMLHttpRequest.cpp:
+ (WebCore::XMLHttpRequest::dropProtection):
+ * bridge/qt/qt_class.cpp:
+ (KJS::Bindings::QtClass::fallbackObject):
+ * bridge/qt/qt_instance.cpp:
+ (KJS::Bindings::QtRuntimeObjectImp::construct):
+ (KJS::Bindings::QtInstance::getRuntimeObject):
+ (KJS::Bindings::QtInstance::invokeDefaultMethod):
+ (KJS::Bindings::QtInstance::defaultValue):
+ (KJS::Bindings::QtInstance::stringValue):
+ (KJS::Bindings::QtInstance::numberValue):
+ (KJS::Bindings::QtInstance::valueOf):
+ * bridge/qt/qt_instance.h:
+ * bridge/qt/qt_runtime.cpp:
+ (KJS::Bindings::convertValueToQVariant):
+ (KJS::Bindings::convertQVariantToValue):
+ (KJS::Bindings::QtRuntimeMetaMethod::lengthGetter):
+ (KJS::Bindings::QtRuntimeMetaMethod::connectGetter):
+ (KJS::Bindings::QtRuntimeMetaMethod::disconnectGetter):
+ (KJS::Bindings::QtRuntimeConnectionMethod::lengthGetter):
+ (KJS::Bindings::QtConnectionObject::execute):
+ Pass ExecState* where now required.
+
2008-06-19 Timothy Hatcher <timothy@apple.com>
Update the JavaScript syntax highlight colors to match Xcode.
--- /dev/null
+#include <JavaScriptCore/JSGlobalData.h>
--- /dev/null
+#include <JavaScriptCore/completion.h>
#include "config.h"
#include "GCController.h"
+#include <kjs/JSGlobalData.h>
#include <kjs/JSLock.h>
#include <kjs/collector.h>
static void* collect(void*)
{
JSLock lock;
- Collector::collect();
+ JSGlobalData::threadInstance().heap->collect();
return 0;
}
void GCController::gcTimerFired(Timer<GCController>*)
{
JSLock lock;
- Collector::collect();
+ JSGlobalData::threadInstance().heap->collect();
}
void GCController::garbageCollectNow()
{
JSLock lock;
- Collector::collect();
+ JSGlobalData::threadInstance().heap->collect();
}
void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone)
: DOMObject(exec->lexicalGlobalObject()->objectPrototype())
, m_document(document)
{
- putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+ putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
ConstructType JSAudioConstructor::getConstructData(ConstructData&)
switch (rule->type()) {
case CSSRule::STYLE_RULE:
- ret = new JSCSSStyleRule(JSCSSRulePrototype::self(exec), static_cast<CSSStyleRule*>(rule));
+ ret = new (exec) JSCSSStyleRule(JSCSSRulePrototype::self(exec), static_cast<CSSStyleRule*>(rule));
break;
case CSSRule::MEDIA_RULE:
- ret = new JSCSSMediaRule(JSCSSMediaRulePrototype::self(exec), static_cast<CSSMediaRule*>(rule));
+ ret = new (exec) JSCSSMediaRule(JSCSSMediaRulePrototype::self(exec), static_cast<CSSMediaRule*>(rule));
break;
case CSSRule::FONT_FACE_RULE:
- ret = new JSCSSFontFaceRule(JSCSSFontFaceRulePrototype::self(exec), static_cast<CSSFontFaceRule*>(rule));
+ ret = new (exec) JSCSSFontFaceRule(JSCSSFontFaceRulePrototype::self(exec), static_cast<CSSFontFaceRule*>(rule));
break;
case CSSRule::PAGE_RULE:
- ret = new JSCSSPageRule(JSCSSPageRulePrototype::self(exec), static_cast<CSSPageRule*>(rule));
+ ret = new (exec) JSCSSPageRule(JSCSSPageRulePrototype::self(exec), static_cast<CSSPageRule*>(rule));
break;
case CSSRule::IMPORT_RULE:
- ret = new JSCSSImportRule(JSCSSImportRulePrototype::self(exec), static_cast<CSSImportRule*>(rule));
+ ret = new (exec) JSCSSImportRule(JSCSSImportRulePrototype::self(exec), static_cast<CSSImportRule*>(rule));
break;
case CSSRule::CHARSET_RULE:
- ret = new JSCSSCharsetRule(JSCSSCharsetRulePrototype::self(exec), static_cast<CSSCharsetRule*>(rule));
+ ret = new (exec) JSCSSCharsetRule(JSCSSCharsetRulePrototype::self(exec), static_cast<CSSCharsetRule*>(rule));
break;
default:
- ret = new JSCSSRule(JSCSSRulePrototype::self(exec), rule);
+ ret = new (exec) JSCSSRule(JSCSSRulePrototype::self(exec), rule);
break;
}
RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValue(prop);
if (v) {
if (pixelOrPos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
- return jsNumber(static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
- return jsStringOrNull(v->cssText());
+ return jsNumber(exec, static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
+ return jsStringOrNull(exec, v->cssText());
}
// If the property is a shorthand property (such as "padding"),
// Make the SVG 'filter' attribute undetectable, to avoid confusion with the IE 'filter' attribute.
if (propertyName == "filter")
- return new StringObjectThatMasqueradesAsUndefined(exec->lexicalGlobalObject()->stringPrototype(),
+ return new (exec) StringObjectThatMasqueradesAsUndefined(exec, exec->lexicalGlobalObject()->stringPrototype(),
thisObj->impl()->getPropertyValue(prop));
- return jsString(thisObj->impl()->getPropertyValue(prop));
+ return jsString(exec, thisObj->impl()->getPropertyValue(prop));
}
return ret;
if (value->isValueList())
- ret = new JSCSSValueList(JSCSSValueListPrototype::self(exec), static_cast<CSSValueList*>(value));
+ ret = new (exec) JSCSSValueList(JSCSSValueListPrototype::self(exec), static_cast<CSSValueList*>(value));
#if ENABLE(SVG)
else if (value->isSVGPaint())
- ret = new JSSVGPaint(JSSVGPaintPrototype::self(exec), static_cast<SVGPaint*>(value));
+ ret = new (exec) JSSVGPaint(JSSVGPaintPrototype::self(exec), static_cast<SVGPaint*>(value));
else if (value->isSVGColor())
- ret = new JSSVGColor(JSSVGColorPrototype::self(exec), static_cast<SVGColor*>(value));
+ ret = new (exec) JSSVGColor(JSSVGColorPrototype::self(exec), static_cast<SVGColor*>(value));
#endif
else if (value->isPrimitiveValue())
- ret = new JSCSSPrimitiveValue(JSCSSPrimitiveValuePrototype::self(exec), static_cast<CSSPrimitiveValue*>(value));
+ ret = new (exec) JSCSSPrimitiveValue(JSCSSPrimitiveValuePrototype::self(exec), static_cast<CSSPrimitiveValue*>(value));
else
- ret = new JSCSSValue(JSCSSValuePrototype::self(exec), value);
+ ret = new (exec) JSCSSValue(JSCSSValuePrototype::self(exec), value);
ScriptInterpreter::putDOMObject(value, ret);
return ret;
unsigned char result;
if (!array->get(index, result))
return jsUndefined();
- return jsNumber(result);
+ return jsNumber(exec, result);
}
void JSCanvasPixelArray::indexSetter(ExecState* exec, unsigned index, JSValue* value)
if (ret)
return ret;
- ret = new JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels);
+ ret = new (exec) JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels);
- Collector::reportExtraMemoryCost(pixels->length());
+ exec->heap()->reportExtraMemoryCost(pixels->length());
ScriptInterpreter::putDOMObject(pixels, ret);
return toJS(exec, style->canvasGradient());
if (style->pattern())
return toJS(exec, style->pattern());
- return jsString(style->color());
+ return jsString(exec, style->color());
}
static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue* value)
ArgList list;
HashSet<String>::const_iterator end = types.end();
for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it)
- list.append(jsString(UString(*it)));
+ list.append(jsString(exec, UString(*it)));
return exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, list);
}
if (!success)
return jsUndefined();
- return jsString(result);
+ return jsString(exec, result);
}
JSValue* JSClipboard::setData(ExecState* exec, const ArgList& args)
RefPtr<JSCustomXPathNSResolver> selfProtector(this);
ArgList args;
- args.append(jsString(prefix));
+ args.append(jsString(exec, prefix));
String result;
JSValue* retval;
Frame* frame = impl()->frame();
if (!frame)
return jsUndefined();
- RefPtr<JSUnprotectedEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(args[1], true);
+ RefPtr<JSUnprotectedEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, args[1], true);
if (!listener)
return jsUndefined();
impl()->addEventListener(args[0]->toString(exec), listener.release(), args[2]->toBoolean(exec));
Frame* frame = impl()->frame();
if (!frame)
return jsUndefined();
- JSUnprotectedEventListener* listener = toJSDOMWindow(frame)->findJSUnprotectedEventListener(args[1], true);
+ JSUnprotectedEventListener* listener = toJSDOMWindow(frame)->findJSUnprotectedEventListener(exec, args[1], true);
if (!listener)
return jsUndefined();
impl()->removeEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec));
return jsBoolean(result);
}
-void JSDOMApplicationCache::setOnchecking(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnchecking(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnCheckingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnCheckingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::onchecking(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOnerror(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnerror(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnErrorListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnErrorListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::onerror(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOnnoupdate(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnnoupdate(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnNoUpdateListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnNoUpdateListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::onnoupdate(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOndownloading(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOndownloading(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnDownloadingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnDownloadingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::ondownloading(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOnprogress(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnprogress(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnProgressListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnProgressListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::onprogress(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOnupdateready(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnupdateready(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnUpdateReadyListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnUpdateReadyListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::onupdateready(ExecState*) const
return jsNull();
}
-void JSDOMApplicationCache::setOncached(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOncached(ExecState* exec, JSValue* value)
{
if (Frame* frame = impl()->frame())
- impl()->setOnCachedListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+ impl()->setOnCachedListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
}
JSValue* JSDOMApplicationCache::oncached(ExecState*) const
}
}
-JSValue* jsStringOrNull(const String& s)
+JSValue* jsStringOrNull(ExecState* exec, const String& s)
{
if (s.isNull())
return jsNull();
- return jsString(s);
+ return jsString(exec, s);
}
-JSValue* jsOwnedStringOrNull(const KJS::UString& s)
+JSValue* jsOwnedStringOrNull(ExecState* exec, const KJS::UString& s)
{
if (s.isNull())
return jsNull();
- return jsOwnedString(s);
+ return jsOwnedString(exec, s);
}
-JSValue* jsStringOrUndefined(const String& s)
+JSValue* jsStringOrUndefined(ExecState* exec, const String& s)
{
if (s.isNull())
return jsUndefined();
- return jsString(s);
+ return jsString(exec, s);
}
-JSValue* jsStringOrFalse(const String& s)
+JSValue* jsStringOrFalse(ExecState* exec, const String& s)
{
if (s.isNull())
return jsBoolean(false);
- return jsString(s);
+ return jsString(exec, s);
}
-JSValue* jsStringOrNull(const KURL& url)
+JSValue* jsStringOrNull(ExecState* exec, const KURL& url)
{
if (url.isNull())
return jsNull();
- return jsString(url.string());
+ return jsString(exec, url.string());
}
-JSValue* jsStringOrUndefined(const KURL& url)
+JSValue* jsStringOrUndefined(ExecState* exec, const KURL& url)
{
if (url.isNull())
return jsUndefined();
- return jsString(url.string());
+ return jsString(exec, url.string());
}
-JSValue* jsStringOrFalse(const KURL& url)
+JSValue* jsStringOrFalse(ExecState* exec, const KURL& url)
{
if (url.isNull())
return jsBoolean(false);
- return jsString(url.string());
+ return jsString(exec, url.string());
}
UString valueToStringWithNullCheck(ExecState* exec, JSValue* value)
JSValue* nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
{
const HashEntry* entry = slot.staticEntry();
- return new PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
+ return new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
}
JSValue* objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
{
- return new PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString);
+ return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString);
}
} // namespace WebCore
explicit DOMObject(KJS::JSValue* prototype) // FIXME: this should take a JSObject once JSLocation has a real prototype
: JSObject(prototype)
{
- // DOMObject destruction is not thread-safe because DOMObjects wrap
- // unsafe WebCore DOM data structures.
- KJS::Collector::collectOnMainThreadOnly(this);
}
#ifndef NDEBUG
return KJS::jsNull();
if (DOMObject* ret = ScriptInterpreter::getDOMObject(domObj))
return ret;
- DOMObject* ret = new JSDOMObj(JSDOMObjPrototype::self(exec), domObj);
+ DOMObject* ret = new (exec) JSDOMObj(JSDOMObjPrototype::self(exec), domObj);
ScriptInterpreter::putDOMObject(domObj, ret);
return ret;
}
return KJS::jsNull();
if (DOMObject* ret = ScriptInterpreter::getDOMObject(domObj))
return ret;
- DOMObject* ret = new JSDOMObj(JSDOMObjPrototype::self(exec), domObj, context);
+ DOMObject* ret = new (exec) JSDOMObj(JSDOMObjPrototype::self(exec), domObj, context);
ScriptInterpreter::putDOMObject(domObj, ret);
return ret;
}
ExceptionCode m_code;
};
- KJS::JSValue* jsStringOrNull(const String&); // null if the string is null
- KJS::JSValue* jsStringOrNull(const KURL&); // null if the URL is null
+ KJS::JSValue* jsStringOrNull(KJS::ExecState*, const String&); // null if the string is null
+ KJS::JSValue* jsStringOrNull(KJS::ExecState*, const KURL&); // null if the URL is null
- KJS::JSValue* jsStringOrUndefined(const String&); // undefined if the string is null
- KJS::JSValue* jsStringOrUndefined(const KURL&); // undefined if the URL is null
+ KJS::JSValue* jsStringOrUndefined(KJS::ExecState*, const String&); // undefined if the string is null
+ KJS::JSValue* jsStringOrUndefined(KJS::ExecState*, const KURL&); // undefined if the URL is null
- KJS::JSValue* jsStringOrFalse(const String&); // boolean false if the string is null
- KJS::JSValue* jsStringOrFalse(const KURL&); // boolean false if the URL is null
+ KJS::JSValue* jsStringOrFalse(KJS::ExecState*, const String&); // boolean false if the string is null
+ KJS::JSValue* jsStringOrFalse(KJS::ExecState*, const KURL&); // boolean false if the URL is null
// See JavaScriptCore for explanation: Should be used for any UString that is already owned by another
// object, to let the engine know that collecting the JSString wrapper is unlikely to save memory.
- KJS::JSValue* jsOwnedStringOrNull(const KJS::UString&);
+ KJS::JSValue* jsOwnedStringOrNull(KJS::ExecState*, const KJS::UString&);
KJS::UString valueToStringWithNullCheck(KJS::ExecState*, KJS::JSValue*); // null if the value is null
KJS::UString valueToStringWithUndefinedOrNullCheck(KJS::ExecState*, KJS::JSValue*); // null if the value is null or undefined
{
// JSDOMWindowBase destruction is not thread-safe because of
// the non-thread-safe WebCore structures it references.
- Collector::collectOnMainThreadOnly(this);
+ Heap::heap(this)->collectOnMainThreadOnly(this);
// Time in milliseconds before the script timeout handler kicks in.
setTimeoutTime(10000);
return jsUndefined();
// FIXME: this property (and the few below) probably shouldn't create a new object every
// time
- return new JSImageConstructor(exec, impl()->frame()->document());
+ return new (exec) JSImageConstructor(exec, impl()->frame()->document());
case Option:
if (!allowsAccessFrom(exec))
return jsUndefined();
- return new JSHTMLOptionElementConstructor(exec, impl()->frame()->document());
+ return new (exec) JSHTMLOptionElementConstructor(exec, impl()->frame()->document());
case XMLHttpRequest:
if (!allowsAccessFrom(exec))
return jsUndefined();
- return new JSXMLHttpRequestConstructor(exec, impl()->frame()->document());
+ return new (exec) JSXMLHttpRequestConstructor(exec, impl()->frame()->document());
case Audio:
#if ENABLE(VIDEO)
if (!allowsAccessFrom(exec))
return jsUndefined();
if (!MediaPlayer::isAvailable())
return jsUndefined();
- return new JSAudioConstructor(exec, impl()->frame()->document());
+ return new (exec) JSAudioConstructor(exec, impl()->frame()->document());
#else
return jsUndefined();
#endif
#if ENABLE(XSLT)
if (!allowsAccessFrom(exec))
return jsUndefined();
- return new JSXSLTProcessorConstructor(exec);
+ return new (exec) JSXSLTProcessorConstructor(exec);
#else
return jsUndefined();
#endif
if (!doc)
return;
- doc->setHTMLWindowEventListener(eventType, findOrCreateJSEventListener(func, true));
+ doc->setHTMLWindowEventListener(eventType, findOrCreateJSEventListener(exec, func, true));
}
JSValue* JSDOMWindowBase::getListener(ExecState* exec, const AtomicString& eventType) const
return listeners.get(object);
}
-PassRefPtr<JSEventListener> JSDOMWindowBase::findOrCreateJSEventListener(JSValue* val, bool html)
+PassRefPtr<JSEventListener> JSDOMWindowBase::findOrCreateJSEventListener(ExecState* exec, JSValue* val, bool html)
{
JSEventListener* listener = findJSEventListener(val, html);
if (listener)
return JSEventListener::create(object, static_cast<JSDOMWindow*>(this), html).get();
}
-JSUnprotectedEventListener* JSDOMWindowBase::findJSUnprotectedEventListener(JSValue* val, bool html)
+JSUnprotectedEventListener* JSDOMWindowBase::findJSUnprotectedEventListener(ExecState* exec, JSValue* val, bool html)
{
if (!val->isObject())
return 0;
return listeners.get(object);
}
-PassRefPtr<JSUnprotectedEventListener> JSDOMWindowBase::findOrCreateJSUnprotectedEventListener(JSValue* val, bool html)
+PassRefPtr<JSUnprotectedEventListener> JSDOMWindowBase::findOrCreateJSUnprotectedEventListener(ExecState* exec, JSValue* val, bool html)
{
- JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(val, html);
+ JSUnprotectedEventListener* listener = findJSUnprotectedEventListener(exec, val, html);
if (listener)
return listener;
if (!val->isObject())
JSValue* v = args[0];
if (v->isNull())
- return jsString();
+ return jsString(exec);
UString s = v->toString(exec);
if (!s.is8Bit()) {
if (!base64Decode(in, out))
return throwError(exec, GeneralError, "Cannot decode base64");
- return jsString(String(out.data(), out.size()));
+ return jsString(exec, String(out.data(), out.size()));
}
JSValue* windowProtoFuncBToA(ExecState* exec, JSObject* thisObj, const ArgList& args)
JSValue* v = args[0];
if (v->isNull())
- return jsString();
+ return jsString(exec);
UString s = v->toString(exec);
if (!s.is8Bit()) {
base64Encode(in, out);
- return jsString(String(out.data(), out.size()));
+ return jsString(exec, String(out.data(), out.size()));
}
JSValue* windowProtoFuncOpen(ExecState* exec, JSObject* thisObj, const ArgList& args)
JSValue* v = args[0];
if (v->isString())
- return jsNumber(window->installTimeout(v->toString(exec), args[1]->toInt32(exec), true /*single shot*/));
+ return jsNumber(exec, window->installTimeout(v->toString(exec), args[1]->toInt32(exec), true /*single shot*/));
if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
ArgList argsTail;
args.getSlice(2, argsTail);
- return jsNumber(window->installTimeout(v, argsTail, args[1]->toInt32(exec), true /*single shot*/));
+ return jsNumber(exec, window->installTimeout(v, argsTail, args[1]->toInt32(exec), true /*single shot*/));
}
return jsUndefined();
JSValue* v = args[0];
int delay = args[1]->toInt32(exec);
if (v->isString())
- return jsNumber(window->installTimeout(v->toString(exec), delay, false));
+ return jsNumber(exec, window->installTimeout(v->toString(exec), delay, false));
if (v->isObject() && static_cast<JSObject*>(v)->implementsCall()) {
ArgList argsTail;
arg