| 1 | /* | 
| 2 |  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. | 
| 3 |  * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca) | 
| 4 |  * | 
| 5 |  * Redistribution and use in source and binary forms, with or without | 
| 6 |  * modification, are permitted provided that the following conditions | 
| 7 |  * are met: | 
| 8 |  * | 
| 9 |  * 1.  Redistributions of source code must retain the above copyright | 
| 10 |  *     notice, this list of conditions and the following disclaimer.  | 
| 11 |  * 2.  Redistributions in binary form must reproduce the above copyright | 
| 12 |  *     notice, this list of conditions and the following disclaimer in the | 
| 13 |  *     documentation and/or other materials provided with the distribution.  | 
| 14 |  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of | 
| 15 |  *     its contributors may be used to endorse or promote products derived | 
| 16 |  *     from this software without specific prior written permission.  | 
| 17 |  * | 
| 18 |  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 
| 19 |  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
| 20 |  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
| 21 |  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | 
| 22 |  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
| 23 |  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
| 24 |  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
| 25 |  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 26 |  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
| 27 |  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 28 |  */ | 
| 29 |  | 
| 30 | #include "config.h" | 
| 31 | #include "JSGlobalObject.h" | 
| 32 |  | 
| 33 | #include "JSCallbackConstructor.h" | 
| 34 | #include "JSCallbackFunction.h" | 
| 35 | #include "JSCallbackObject.h" | 
| 36 |  | 
| 37 | #include "Arguments.h" | 
| 38 | #include "ArrayConstructor.h" | 
| 39 | #include "ArrayPrototype.h" | 
| 40 | #include "BooleanConstructor.h" | 
| 41 | #include "BooleanPrototype.h" | 
| 42 | #include "CodeBlock.h" | 
| 43 | #include "DateConstructor.h" | 
| 44 | #include "DatePrototype.h" | 
| 45 | #include "ErrorConstructor.h" | 
| 46 | #include "ErrorPrototype.h" | 
| 47 | #include "FunctionConstructor.h" | 
| 48 | #include "FunctionPrototype.h" | 
| 49 | #include "GlobalEvalFunction.h" | 
| 50 | #include "JSFunction.h" | 
| 51 | #include "JSGlobalObjectFunctions.h" | 
| 52 | #include "JSLock.h" | 
| 53 | #include "JSONObject.h" | 
| 54 | #include "Interpreter.h" | 
| 55 | #include "MathObject.h" | 
| 56 | #include "NativeErrorConstructor.h" | 
| 57 | #include "NativeErrorPrototype.h" | 
| 58 | #include "NumberConstructor.h" | 
| 59 | #include "NumberPrototype.h" | 
| 60 | #include "ObjectConstructor.h" | 
| 61 | #include "ObjectPrototype.h" | 
| 62 | #include "Profiler.h" | 
| 63 | #include "PrototypeFunction.h" | 
| 64 | #include "RegExpConstructor.h" | 
| 65 | #include "RegExpMatchesArray.h" | 
| 66 | #include "RegExpObject.h" | 
| 67 | #include "RegExpPrototype.h" | 
| 68 | #include "ScopeChainMark.h" | 
| 69 | #include "StringConstructor.h" | 
| 70 | #include "StringPrototype.h" | 
| 71 | #include "Debugger.h" | 
| 72 |  | 
| 73 | namespace JSC { | 
| 74 |  | 
| 75 | ASSERT_CLASS_FITS_IN_CELL(JSGlobalObject); | 
| 76 |  | 
| 77 | // Default number of ticks before a timeout check should be done. | 
| 78 | static const int initialTickCountThreshold = 255; | 
| 79 |  | 
| 80 | // Preferred number of milliseconds between each timeout check | 
| 81 | static const int preferredScriptCheckTimeInterval = 1000; | 
| 82 |  | 
| 83 | static inline void markIfNeeded(MarkStack& markStack, JSValue v) | 
| 84 | { | 
| 85 |     if (v) | 
| 86 |         markStack.append(value: v); | 
| 87 | } | 
| 88 |  | 
| 89 | static inline void markIfNeeded(MarkStack& markStack, const RefPtr<Structure>& s) | 
| 90 | { | 
| 91 |     if (s) | 
| 92 |         markIfNeeded(markStack, v: s->storedPrototype()); | 
| 93 | } | 
| 94 |  | 
| 95 | JSGlobalObject::~JSGlobalObject() | 
| 96 | { | 
| 97 |     ASSERT(JSLock::currentThreadIsHoldingLock()); | 
| 98 |  | 
| 99 |     if (d()->debugger) | 
| 100 |         d()->debugger->detach(this); | 
| 101 |  | 
| 102 |     Profiler** profiler = Profiler::enabledProfilerReference(); | 
| 103 |     if (UNLIKELY(*profiler != 0)) { | 
| 104 |         (*profiler)->stopProfiling(globalExec(), title: UString()); | 
| 105 |     } | 
| 106 |  | 
| 107 |     d()->next->d()->prev = d()->prev; | 
| 108 |     d()->prev->d()->next = d()->next; | 
| 109 |     JSGlobalObject*& headObject = head(); | 
| 110 |     if (headObject == this) | 
| 111 |         headObject = d()->next; | 
| 112 |     if (headObject == this) | 
| 113 |         headObject = 0; | 
| 114 |  | 
| 115 |     HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); | 
| 116 |     for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) | 
| 117 |         (*it)->clearGlobalObject(); | 
| 118 |          | 
| 119 |     RegisterFile& registerFile = globalData()->interpreter->registerFile(); | 
| 120 |     if (registerFile.globalObject() == this) { | 
| 121 |         registerFile.setGlobalObject(0); | 
| 122 |         registerFile.setNumGlobals(0); | 
| 123 |     } | 
| 124 |     d()->destructor(d()); | 
| 125 | } | 
| 126 |  | 
| 127 | void JSGlobalObject::init(JSObject* thisValue) | 
| 128 | { | 
| 129 |     ASSERT(JSLock::currentThreadIsHoldingLock()); | 
| 130 |  | 
| 131 |     structure()->disableSpecificFunctionTracking(); | 
| 132 |  | 
| 133 |     d()->globalData = Heap::heap(c: this)->globalData(); | 
| 134 |     d()->globalScopeChain = ScopeChain(this, d()->globalData.get(), this, thisValue); | 
| 135 |  | 
| 136 |     JSGlobalObject::globalExec()->init(codeBlock: 0, vPC: 0, scopeChain: d()->globalScopeChain.node(), callerFrame: CallFrame::noCaller(), returnValueRegister: 0, argc: 0, callee: 0); | 
| 137 |  | 
| 138 |     if (JSGlobalObject*& headObject = head()) { | 
| 139 |         d()->prev = headObject; | 
| 140 |         d()->next = headObject->d()->next; | 
| 141 |         headObject->d()->next->d()->prev = this; | 
| 142 |         headObject->d()->next = this; | 
| 143 |     } else | 
| 144 |         headObject = d()->next = d()->prev = this; | 
| 145 |  | 
| 146 |     d()->recursion = 0; | 
| 147 |     d()->debugger = 0; | 
| 148 |  | 
| 149 |     d()->profileGroup = 0; | 
| 150 |  | 
| 151 |     reset(prototype: prototype()); | 
| 152 | } | 
| 153 |  | 
| 154 | void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) | 
| 155 | { | 
| 156 |     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); | 
| 157 |  | 
| 158 |     if (symbolTablePut(propertyName, value)) | 
| 159 |         return; | 
| 160 |     JSVariableObject::put(exec, propertyName, value, slot); | 
| 161 | } | 
| 162 |  | 
| 163 | void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes) | 
| 164 | { | 
| 165 |     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); | 
| 166 |  | 
| 167 |     if (symbolTablePutWithAttributes(propertyName, value, attributes)) | 
| 168 |         return; | 
| 169 |  | 
| 170 |     JSValue valueBefore = getDirect(propertyName); | 
| 171 |     PutPropertySlot slot; | 
| 172 |     JSVariableObject::put(exec, propertyName, value, slot); | 
| 173 |     if (!valueBefore) { | 
| 174 |         JSValue valueAfter = getDirect(propertyName); | 
| 175 |         if (valueAfter) | 
| 176 |             JSObject::putWithAttributes(exec, propertyName, value: valueAfter, attributes); | 
| 177 |     } | 
| 178 | } | 
| 179 |  | 
| 180 | void JSGlobalObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes) | 
| 181 | { | 
| 182 |     PropertySlot slot; | 
| 183 |     if (!symbolTableGet(propertyName, slot)) | 
| 184 |         JSVariableObject::defineGetter(exec, propertyName, getterFunction: getterFunc, attributes); | 
| 185 | } | 
| 186 |  | 
| 187 | void JSGlobalObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes) | 
| 188 | { | 
| 189 |     PropertySlot slot; | 
| 190 |     if (!symbolTableGet(propertyName, slot)) | 
| 191 |         JSVariableObject::defineSetter(exec, propertyName, setterFunction: setterFunc, attributes); | 
| 192 | } | 
| 193 |  | 
| 194 | static inline JSObject* lastInPrototypeChain(JSObject* object) | 
| 195 | { | 
| 196 |     JSObject* o = object; | 
| 197 |     while (o->prototype().isObject()) | 
| 198 |         o = asObject(value: o->prototype()); | 
| 199 |     return o; | 
| 200 | } | 
| 201 |  | 
| 202 | void JSGlobalObject::reset(JSValue prototype) | 
| 203 | { | 
| 204 |     ExecState* exec = JSGlobalObject::globalExec(); | 
| 205 |  | 
| 206 |     // Prototypes | 
| 207 |  | 
| 208 |     d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructure(proto: jsNull())); // The real prototype will be set once ObjectPrototype is created. | 
| 209 |     d()->prototypeFunctionStructure = PrototypeFunction::createStructure(proto: d()->functionPrototype); | 
| 210 |     NativeFunctionWrapper* callFunction = 0; | 
| 211 |     NativeFunctionWrapper* applyFunction = 0; | 
| 212 |     d()->functionPrototype->addFunctionProperties(exec, prototypeFunctionStructure: d()->prototypeFunctionStructure.get(), callFunction: &callFunction, applyFunction: &applyFunction); | 
| 213 |     d()->callFunction = callFunction; | 
| 214 |     d()->applyFunction = applyFunction; | 
| 215 |     d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(prototype: jsNull()), d()->prototypeFunctionStructure.get()); | 
| 216 |     d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype); | 
| 217 |  | 
| 218 |     d()->emptyObjectStructure = d()->objectPrototype->inheritorID(); | 
| 219 |  | 
| 220 |     d()->functionStructure = JSFunction::createStructure(prototype: d()->functionPrototype); | 
| 221 |     d()->callbackFunctionStructure = JSCallbackFunction::createStructure(proto: d()->functionPrototype); | 
| 222 |     d()->argumentsStructure = Arguments::createStructure(prototype: d()->objectPrototype); | 
| 223 |     d()->callbackConstructorStructure = JSCallbackConstructor::createStructure(proto: d()->objectPrototype); | 
| 224 |     d()->callbackObjectStructure = JSCallbackObject<JSObject>::createStructure(proto: d()->objectPrototype); | 
| 225 |  | 
| 226 |     d()->arrayPrototype = new (exec) ArrayPrototype(ArrayPrototype::createStructure(prototype: d()->objectPrototype)); | 
| 227 |     d()->arrayStructure = JSArray::createStructure(prototype: d()->arrayPrototype); | 
| 228 |     d()->regExpMatchesArrayStructure = RegExpMatchesArray::createStructure(prototype: d()->arrayPrototype); | 
| 229 |  | 
| 230 |     d()->stringPrototype = new (exec) StringPrototype(exec, StringPrototype::createStructure(prototype: d()->objectPrototype)); | 
| 231 |     d()->stringObjectStructure = StringObject::createStructure(prototype: d()->stringPrototype); | 
| 232 |  | 
| 233 |     d()->booleanPrototype = new (exec) BooleanPrototype(exec, BooleanPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); | 
| 234 |     d()->booleanObjectStructure = BooleanObject::createStructure(prototype: d()->booleanPrototype); | 
| 235 |  | 
| 236 |     d()->numberPrototype = new (exec) NumberPrototype(exec, NumberPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); | 
| 237 |     d()->numberObjectStructure = NumberObject::createStructure(prototype: d()->numberPrototype); | 
| 238 |  | 
| 239 |     d()->datePrototype = new (exec) DatePrototype(exec, DatePrototype::createStructure(prototype: d()->objectPrototype)); | 
| 240 |     d()->dateStructure = DateInstance::createStructure(prototype: d()->datePrototype); | 
| 241 |  | 
| 242 |     d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); | 
| 243 |     d()->regExpStructure = RegExpObject::createStructure(prototype: d()->regExpPrototype); | 
| 244 |  | 
| 245 |     d()->methodCallDummy = constructEmptyObject(exec); | 
| 246 |  | 
| 247 |     ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(prototype: d()->objectPrototype), d()->prototypeFunctionStructure.get()); | 
| 248 |     d()->errorStructure = ErrorInstance::createStructure(prototype: errorPrototype); | 
| 249 |  | 
| 250 |     RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(prototype: errorPrototype); | 
| 251 |  | 
| 252 |     NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError" , "EvalError" ); | 
| 253 |     NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError" , "RangeError" ); | 
| 254 |     NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError" , "ReferenceError" ); | 
| 255 |     NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError" , "SyntaxError" ); | 
| 256 |     NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError" , "TypeError" ); | 
| 257 |     NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError" , "URIError" ); | 
| 258 |  | 
| 259 |     // Constructors | 
| 260 |  | 
| 261 |     JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(proto: d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get()); | 
| 262 |     JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(proto: d()->functionPrototype), d()->functionPrototype); | 
| 263 |     JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(proto: d()->functionPrototype), d()->arrayPrototype, d()->prototypeFunctionStructure.get()); | 
| 264 |     JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(proto: d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype); | 
| 265 |     JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(proto: d()->functionPrototype), d()->booleanPrototype); | 
| 266 |     JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(proto: d()->functionPrototype), d()->numberPrototype); | 
| 267 |     JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(proto: d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype); | 
| 268 |  | 
| 269 |     d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(prototype: d()->functionPrototype), d()->regExpPrototype); | 
| 270 |  | 
| 271 |     d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(proto: d()->functionPrototype), errorPrototype); | 
| 272 |  | 
| 273 |     RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(proto: d()->functionPrototype); | 
| 274 |  | 
| 275 |     d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype); | 
| 276 |     d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype); | 
| 277 |     d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype); | 
| 278 |     d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype); | 
| 279 |     d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype); | 
| 280 |     d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype); | 
| 281 |  | 
| 282 |     d()->objectPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: objectConstructor, attributes: DontEnum); | 
| 283 |     d()->functionPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: functionConstructor, attributes: DontEnum); | 
| 284 |     d()->arrayPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: arrayConstructor, attributes: DontEnum); | 
| 285 |     d()->booleanPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: booleanConstructor, attributes: DontEnum); | 
| 286 |     d()->stringPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: stringConstructor, attributes: DontEnum); | 
| 287 |     d()->numberPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: numberConstructor, attributes: DontEnum); | 
| 288 |     d()->datePrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: dateConstructor, attributes: DontEnum); | 
| 289 |     d()->regExpPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: d()->regExpConstructor, attributes: DontEnum); | 
| 290 |     errorPrototype->putDirectFunctionWithoutTransition(propertyName: exec->propertyNames().constructor, value: d()->errorConstructor, attributes: DontEnum); | 
| 291 |  | 
| 292 |     evalErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->evalErrorConstructor, attributes: DontEnum); | 
| 293 |     rangeErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->rangeErrorConstructor, attributes: DontEnum); | 
| 294 |     referenceErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->referenceErrorConstructor, attributes: DontEnum); | 
| 295 |     syntaxErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->syntaxErrorConstructor, attributes: DontEnum); | 
| 296 |     typeErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->typeErrorConstructor, attributes: DontEnum); | 
| 297 |     URIErrorPrototype->putDirect(propertyName: exec->propertyNames().constructor, value: d()->URIErrorConstructor, attributes: DontEnum); | 
| 298 |  | 
| 299 |     // Set global constructors | 
| 300 |  | 
| 301 |     // FIXME: These properties could be handled by a static hash table. | 
| 302 |  | 
| 303 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Object" ), value: objectConstructor, attributes: DontEnum); | 
| 304 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Function" ), value: functionConstructor, attributes: DontEnum); | 
| 305 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Array" ), value: arrayConstructor, attributes: DontEnum); | 
| 306 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Boolean" ), value: booleanConstructor, attributes: DontEnum); | 
| 307 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "String" ), value: stringConstructor, attributes: DontEnum); | 
| 308 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Number" ), value: numberConstructor, attributes: DontEnum); | 
| 309 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Date" ), value: dateConstructor, attributes: DontEnum); | 
| 310 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "RegExp" ), value: d()->regExpConstructor, attributes: DontEnum); | 
| 311 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "Error" ), value: d()->errorConstructor, attributes: DontEnum); | 
| 312 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "EvalError" ), value: d()->evalErrorConstructor, attributes: DontEnum); | 
| 313 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "RangeError" ), value: d()->rangeErrorConstructor, attributes: DontEnum); | 
| 314 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "ReferenceError" ), value: d()->referenceErrorConstructor, attributes: DontEnum); | 
| 315 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "SyntaxError" ), value: d()->syntaxErrorConstructor, attributes: DontEnum); | 
| 316 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "TypeError" ), value: d()->typeErrorConstructor, attributes: DontEnum); | 
| 317 |     putDirectFunctionWithoutTransition(propertyName: Identifier(exec, "URIError" ), value: d()->URIErrorConstructor, attributes: DontEnum); | 
| 318 |  | 
| 319 |     // Set global values. | 
| 320 |     GlobalPropertyInfo staticGlobals[] = { | 
| 321 |         GlobalPropertyInfo(Identifier(exec, "Math" ), new (exec) MathObject(exec, MathObject::createStructure(prototype: d()->objectPrototype)), DontEnum | DontDelete), | 
| 322 |         GlobalPropertyInfo(Identifier(exec, "NaN" ), jsNaN(exec), DontEnum | DontDelete), | 
| 323 |         GlobalPropertyInfo(Identifier(exec, "Infinity" ), jsNumber(exec, d: Inf), DontEnum | DontDelete), | 
| 324 |         GlobalPropertyInfo(Identifier(exec, "undefined" ), jsUndefined(), DontEnum | DontDelete), | 
| 325 |         GlobalPropertyInfo(Identifier(exec, "JSON" ), new (exec) JSONObject(JSONObject::createStructure(prototype: d()->objectPrototype)), DontEnum | DontDelete) | 
| 326 |     }; | 
| 327 |  | 
| 328 |     addStaticGlobals(globals: staticGlobals, count: sizeof(staticGlobals) / sizeof(GlobalPropertyInfo)); | 
| 329 |  | 
| 330 |     // Set global functions. | 
| 331 |  | 
| 332 |     d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(prototype: d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this); | 
| 333 |     putDirectFunctionWithoutTransition(exec, function: d()->evalFunction, attr: DontEnum); | 
| 334 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt" ), globalFuncParseInt), attr: DontEnum); | 
| 335 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat" ), globalFuncParseFloat), attr: DontEnum); | 
| 336 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN" ), globalFuncIsNaN), attr: DontEnum); | 
| 337 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite" ), globalFuncIsFinite), attr: DontEnum); | 
| 338 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape" ), globalFuncEscape), attr: DontEnum); | 
| 339 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape" ), globalFuncUnescape), attr: DontEnum); | 
| 340 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI" ), globalFuncDecodeURI), attr: DontEnum); | 
| 341 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent" ), globalFuncDecodeURIComponent), attr: DontEnum); | 
| 342 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI" ), globalFuncEncodeURI), attr: DontEnum); | 
| 343 |     putDirectFunctionWithoutTransition(exec, function: new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent" ), globalFuncEncodeURIComponent), attr: DontEnum); | 
| 344 | #ifndef NDEBUG | 
| 345 | #ifndef QT_BUILD_SCRIPT_LIB | 
| 346 |     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint" ), globalFuncJSCPrint), DontEnum); | 
| 347 | #endif | 
| 348 | #endif | 
| 349 |  | 
| 350 |     resetPrototype(prototype); | 
| 351 | } | 
| 352 |  | 
| 353 | // Set prototype, and also insert the object prototype at the end of the chain. | 
| 354 | void JSGlobalObject::resetPrototype(JSValue prototype) | 
| 355 | { | 
| 356 |     setPrototype(prototype); | 
| 357 |  | 
| 358 |     JSObject* oldLastInPrototypeChain = lastInPrototypeChain(object: this); | 
| 359 |     JSObject* objectPrototype = d()->objectPrototype; | 
| 360 |     if (oldLastInPrototypeChain != objectPrototype) | 
| 361 |         oldLastInPrototypeChain->setPrototype(objectPrototype); | 
| 362 | } | 
| 363 |  | 
| 364 | void JSGlobalObject::markChildren(MarkStack& markStack) | 
| 365 | { | 
| 366 |     JSVariableObject::markChildren(markStack); | 
| 367 |      | 
| 368 |     HashSet<GlobalCodeBlock*>::const_iterator end = codeBlocks().end(); | 
| 369 |     for (HashSet<GlobalCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it) | 
| 370 |         (*it)->markAggregate(markStack); | 
| 371 |  | 
| 372 |     RegisterFile& registerFile = globalData()->interpreter->registerFile(); | 
| 373 |     if (registerFile.globalObject() == this) | 
| 374 |         registerFile.markGlobals(markStack, heap: &globalData()->heap); | 
| 375 |  | 
| 376 |     markIfNeeded(markStack, v: d()->regExpConstructor); | 
| 377 |     markIfNeeded(markStack, v: d()->errorConstructor); | 
| 378 |     markIfNeeded(markStack, v: d()->evalErrorConstructor); | 
| 379 |     markIfNeeded(markStack, v: d()->rangeErrorConstructor); | 
| 380 |     markIfNeeded(markStack, v: d()->referenceErrorConstructor); | 
| 381 |     markIfNeeded(markStack, v: d()->syntaxErrorConstructor); | 
| 382 |     markIfNeeded(markStack, v: d()->typeErrorConstructor); | 
| 383 |     markIfNeeded(markStack, v: d()->URIErrorConstructor); | 
| 384 |  | 
| 385 |     markIfNeeded(markStack, v: d()->evalFunction); | 
| 386 |     markIfNeeded(markStack, v: d()->callFunction); | 
| 387 |     markIfNeeded(markStack, v: d()->applyFunction); | 
| 388 |  | 
| 389 |     markIfNeeded(markStack, v: d()->objectPrototype); | 
| 390 |     markIfNeeded(markStack, v: d()->functionPrototype); | 
| 391 |     markIfNeeded(markStack, v: d()->arrayPrototype); | 
| 392 |     markIfNeeded(markStack, v: d()->booleanPrototype); | 
| 393 |     markIfNeeded(markStack, v: d()->stringPrototype); | 
| 394 |     markIfNeeded(markStack, v: d()->numberPrototype); | 
| 395 |     markIfNeeded(markStack, v: d()->datePrototype); | 
| 396 |     markIfNeeded(markStack, v: d()->regExpPrototype); | 
| 397 |  | 
| 398 |     markIfNeeded(markStack, v: d()->methodCallDummy); | 
| 399 |  | 
| 400 |     markIfNeeded(markStack, s: d()->errorStructure); | 
| 401 |     markIfNeeded(markStack, s: d()->argumentsStructure); | 
| 402 |     markIfNeeded(markStack, s: d()->arrayStructure); | 
| 403 |     markIfNeeded(markStack, s: d()->booleanObjectStructure); | 
| 404 |     markIfNeeded(markStack, s: d()->callbackConstructorStructure); | 
| 405 |     markIfNeeded(markStack, s: d()->callbackFunctionStructure); | 
| 406 |     markIfNeeded(markStack, s: d()->callbackObjectStructure); | 
| 407 |     markIfNeeded(markStack, s: d()->dateStructure); | 
| 408 |     markIfNeeded(markStack, s: d()->emptyObjectStructure); | 
| 409 |     markIfNeeded(markStack, s: d()->errorStructure); | 
| 410 |     markIfNeeded(markStack, s: d()->functionStructure); | 
| 411 |     markIfNeeded(markStack, s: d()->numberObjectStructure); | 
| 412 |     markIfNeeded(markStack, s: d()->prototypeFunctionStructure); | 
| 413 |     markIfNeeded(markStack, s: d()->regExpMatchesArrayStructure); | 
| 414 |     markIfNeeded(markStack, s: d()->regExpStructure); | 
| 415 |     markIfNeeded(markStack, s: d()->stringObjectStructure); | 
| 416 |  | 
| 417 |     // No need to mark the other structures, because their prototypes are all | 
| 418 |     // guaranteed to be referenced elsewhere. | 
| 419 |  | 
| 420 |     Register* registerArray = d()->registerArray.get(); | 
| 421 |     if (!registerArray) | 
| 422 |         return; | 
| 423 |  | 
| 424 |     size_t size = d()->registerArraySize; | 
| 425 |     markStack.appendValues(values: reinterpret_cast<JSValue*>(registerArray), count: size); | 
| 426 | } | 
| 427 |  | 
| 428 | ExecState* JSGlobalObject::globalExec() | 
| 429 | { | 
| 430 |     return CallFrame::create(callFrameBase: d()->globalCallFrame + RegisterFile::CallFrameHeaderSize); | 
| 431 | } | 
| 432 |  | 
| 433 | bool JSGlobalObject::isDynamicScope() const | 
| 434 | { | 
| 435 |     return true; | 
| 436 | } | 
| 437 |  | 
| 438 | void JSGlobalObject::copyGlobalsFrom(RegisterFile& registerFile) | 
| 439 | { | 
| 440 |     ASSERT(!d()->registerArray); | 
| 441 |     ASSERT(!d()->registerArraySize); | 
| 442 |  | 
| 443 |     int numGlobals = registerFile.numGlobals(); | 
| 444 |     if (!numGlobals) { | 
| 445 |         d()->registers = 0; | 
| 446 |         return; | 
| 447 |     } | 
| 448 |      | 
| 449 |     Register* registerArray = copyRegisterArray(src: registerFile.lastGlobal(), count: numGlobals); | 
| 450 |     setRegisters(registers: registerArray + numGlobals, registerArray, count: numGlobals); | 
| 451 | } | 
| 452 |  | 
| 453 | void JSGlobalObject::copyGlobalsTo(RegisterFile& registerFile) | 
| 454 | { | 
| 455 |     JSGlobalObject* lastGlobalObject = registerFile.globalObject(); | 
| 456 |     if (lastGlobalObject && lastGlobalObject != this) | 
| 457 |         lastGlobalObject->copyGlobalsFrom(registerFile); | 
| 458 |  | 
| 459 |     registerFile.setGlobalObject(this); | 
| 460 |     registerFile.setNumGlobals(symbolTable().size()); | 
| 461 |  | 
| 462 |     if (d()->registerArray) { | 
| 463 |         memcpy(dest: registerFile.start() - d()->registerArraySize, src: d()->registerArray.get(), n: d()->registerArraySize * sizeof(Register)); | 
| 464 |         setRegisters(registers: registerFile.start(), registerArray: 0, count: 0); | 
| 465 |     } | 
| 466 | } | 
| 467 |  | 
| 468 | void* JSGlobalObject::operator new(size_t size, JSGlobalData* globalData) | 
| 469 | { | 
| 470 |     return globalData->heap.allocate(size); | 
| 471 | } | 
| 472 |  | 
| 473 | void JSGlobalObject::destroyJSGlobalObjectData(void* jsGlobalObjectData) | 
| 474 | { | 
| 475 |     delete static_cast<JSGlobalObjectData*>(jsGlobalObjectData); | 
| 476 | } | 
| 477 |  | 
| 478 | } // namespace JSC | 
| 479 |  |