2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
4 * Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
25 #include "ArrayPrototype.h"
26 #include "ButterflyInlines.h"
27 #include "BytecodeGenerator.h"
28 #include "CodeBlock.h"
29 #include "Completion.h"
30 #include "CopiedSpaceInlines.h"
31 #include "Disassembler.h"
32 #include "Exception.h"
33 #include "ExceptionHelpers.h"
34 #include "HeapStatistics.h"
35 #include "InitializeThreading.h"
36 #include "Interpreter.h"
38 #include "JSArrayBuffer.h"
39 #include "JSCInlines.h"
40 #include "JSFunction.h"
42 #include "JSONObject.h"
45 #include "ProfilerDatabase.h"
46 #include "SamplingTool.h"
47 #include "StackVisitor.h"
48 #include "StructureInlines.h"
49 #include "StructureRareDataInlines.h"
50 #include "TestRunnerUtils.h"
51 #include "TypeProfilerLog.h"
57 #include <wtf/CurrentTime.h>
58 #include <wtf/MainThread.h>
59 #include <wtf/StringPrintStream.h>
60 #include <wtf/text/StringBuilder.h>
67 // readline/history.h has a Function typedef which conflicts with the WTF::Function template from WTF/Forward.h
68 // We #define it to something else to avoid this conflict.
69 #define Function ReadlineFunction
70 #include <readline/history.h>
71 #include <readline/readline.h>
89 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
102 WTF_IMPORT
extern const struct HashTable globalObjectTable
;
107 NO_RETURN_WITH_VALUE
static void jscExit(int status
)
109 waitForAsynchronousDisassembly();
112 if (DFG::isCrashing()) {
121 #endif // ENABLE(DFG_JIT)
126 class ElementHandleOwner
;
131 class Element
: public JSNonFinalObject
{
133 Element(VM
& vm
, Structure
* structure
)
134 : Base(vm
, structure
)
138 typedef JSNonFinalObject Base
;
139 static const bool needsDestruction
= false;
141 Root
* root() const { return m_root
.get(); }
142 void setRoot(VM
& vm
, Root
* root
) { m_root
.set(vm
, this, root
); }
144 static Element
* create(VM
& vm
, JSGlobalObject
* globalObject
, Root
* root
)
146 Structure
* structure
= createStructure(vm
, globalObject
, jsNull());
147 Element
* element
= new (NotNull
, allocateCell
<Element
>(vm
.heap
, sizeof(Element
))) Element(vm
, structure
);
148 element
->finishCreation(vm
, root
);
152 void finishCreation(VM
&, Root
*);
154 static void visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
156 Element
* thisObject
= jsCast
<Element
*>(cell
);
157 ASSERT_GC_OBJECT_INHERITS(thisObject
, info());
158 Base::visitChildren(thisObject
, visitor
);
159 visitor
.append(&thisObject
->m_root
);
162 static ElementHandleOwner
* handleOwner();
164 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
166 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info());
172 WriteBarrier
<Root
> m_root
;
175 class ElementHandleOwner
: public WeakHandleOwner
{
177 virtual bool isReachableFromOpaqueRoots(Handle
<JSC::Unknown
> handle
, void*, SlotVisitor
& visitor
)
179 Element
* element
= jsCast
<Element
*>(handle
.slot()->asCell());
180 return visitor
.containsOpaqueRoot(element
->root());
184 class Masquerader
: public JSNonFinalObject
{
186 Masquerader(VM
& vm
, Structure
* structure
)
187 : Base(vm
, structure
)
191 typedef JSNonFinalObject Base
;
192 static const unsigned StructureFlags
= Base::StructureFlags
| JSC::MasqueradesAsUndefined
;
194 static Masquerader
* create(VM
& vm
, JSGlobalObject
* globalObject
)
196 globalObject
->masqueradesAsUndefinedWatchpoint()->fireAll("Masquerading object allocated");
197 Structure
* structure
= createStructure(vm
, globalObject
, jsNull());
198 Masquerader
* result
= new (NotNull
, allocateCell
<Masquerader
>(vm
.heap
, sizeof(Masquerader
))) Masquerader(vm
, structure
);
199 result
->finishCreation(vm
);
203 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
205 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info());
211 class Root
: public JSDestructibleObject
{
213 Root(VM
& vm
, Structure
* structure
)
214 : Base(vm
, structure
)
220 return m_element
.get();
223 void setElement(Element
* element
)
225 Weak
<Element
> newElement(element
, Element::handleOwner());
226 m_element
.swap(newElement
);
229 static Root
* create(VM
& vm
, JSGlobalObject
* globalObject
)
231 Structure
* structure
= createStructure(vm
, globalObject
, jsNull());
232 Root
* root
= new (NotNull
, allocateCell
<Root
>(vm
.heap
, sizeof(Root
))) Root(vm
, structure
);
233 root
->finishCreation(vm
);
237 typedef JSDestructibleObject Base
;
240 static const bool needsDestruction
= true;
242 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
244 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info());
247 static void visitChildren(JSCell
* thisObject
, SlotVisitor
& visitor
)
249 Base::visitChildren(thisObject
, visitor
);
250 visitor
.addOpaqueRoot(thisObject
);
254 Weak
<Element
> m_element
;
257 class ImpureGetter
: public JSNonFinalObject
{
259 ImpureGetter(VM
& vm
, Structure
* structure
)
260 : Base(vm
, structure
)
265 typedef JSNonFinalObject Base
;
266 static const unsigned StructureFlags
= Base::StructureFlags
| JSC::HasImpureGetOwnPropertySlot
| JSC::OverridesGetOwnPropertySlot
;
268 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
270 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info());
273 static ImpureGetter
* create(VM
& vm
, Structure
* structure
, JSObject
* delegate
)
275 ImpureGetter
* getter
= new (NotNull
, allocateCell
<ImpureGetter
>(vm
.heap
, sizeof(ImpureGetter
))) ImpureGetter(vm
, structure
);
276 getter
->finishCreation(vm
, delegate
);
280 void finishCreation(VM
& vm
, JSObject
* delegate
)
282 Base::finishCreation(vm
);
284 m_delegate
.set(vm
, this, delegate
);
287 static bool getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName name
, PropertySlot
& slot
)
289 ImpureGetter
* thisObject
= jsCast
<ImpureGetter
*>(object
);
291 if (thisObject
->m_delegate
&& thisObject
->m_delegate
->getPropertySlot(exec
, name
, slot
))
294 return Base::getOwnPropertySlot(object
, exec
, name
, slot
);
297 static void visitChildren(JSCell
* cell
, SlotVisitor
& visitor
)
299 Base::visitChildren(cell
, visitor
);
300 ImpureGetter
* thisObject
= jsCast
<ImpureGetter
*>(cell
);
301 visitor
.append(&thisObject
->m_delegate
);
304 void setDelegate(VM
& vm
, JSObject
* delegate
)
306 m_delegate
.set(vm
, this, delegate
);
310 WriteBarrier
<JSObject
> m_delegate
;
313 class RuntimeArray
: public JSArray
{
315 typedef JSArray Base
;
316 static const unsigned StructureFlags
= Base::StructureFlags
| OverridesGetOwnPropertySlot
| InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero
| OverridesGetPropertyNames
;
318 static RuntimeArray
* create(ExecState
* exec
)
321 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
322 Structure
* structure
= createStructure(vm
, globalObject
, createPrototype(vm
, globalObject
));
323 RuntimeArray
* runtimeArray
= new (NotNull
, allocateCell
<RuntimeArray
>(*exec
->heap())) RuntimeArray(exec
, structure
);
324 runtimeArray
->finishCreation(exec
);
325 vm
.heap
.addFinalizer(runtimeArray
, destroy
);
331 static void destroy(JSCell
* cell
)
333 static_cast<RuntimeArray
*>(cell
)->RuntimeArray::~RuntimeArray();
336 static const bool needsDestruction
= false;
338 static bool getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
340 RuntimeArray
* thisObject
= jsCast
<RuntimeArray
*>(object
);
341 if (propertyName
== exec
->propertyNames().length
) {
342 slot
.setCacheableCustom(thisObject
, DontDelete
| ReadOnly
| DontEnum
, thisObject
->lengthGetter
);
346 Optional
<uint32_t> index
= parseIndex(propertyName
);
347 if (index
&& index
.value() < thisObject
->getLength()) {
348 slot
.setValue(thisObject
, DontDelete
| DontEnum
, jsNumber(thisObject
->m_vector
[index
.value()]));
352 return JSObject::getOwnPropertySlot(thisObject
, exec
, propertyName
, slot
);
355 static bool getOwnPropertySlotByIndex(JSObject
* object
, ExecState
* exec
, unsigned index
, PropertySlot
& slot
)
357 RuntimeArray
* thisObject
= jsCast
<RuntimeArray
*>(object
);
358 if (index
< thisObject
->getLength()) {
359 slot
.setValue(thisObject
, DontDelete
| DontEnum
, jsNumber(thisObject
->m_vector
[index
]));
363 return JSObject::getOwnPropertySlotByIndex(thisObject
, exec
, index
, slot
);
366 static NO_RETURN_DUE_TO_CRASH
void put(JSCell
*, ExecState
*, PropertyName
, JSValue
, PutPropertySlot
&)
368 RELEASE_ASSERT_NOT_REACHED();
371 static NO_RETURN_DUE_TO_CRASH
bool deleteProperty(JSCell
*, ExecState
*, PropertyName
)
373 RELEASE_ASSERT_NOT_REACHED();
376 unsigned getLength() const { return m_vector
.size(); }
380 static ArrayPrototype
* createPrototype(VM
&, JSGlobalObject
* globalObject
)
382 return globalObject
->arrayPrototype();
385 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
387 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info(), ArrayClass
);
391 void finishCreation(ExecState
* exec
)
393 Base::finishCreation(exec
->vm());
394 ASSERT(inherits(info()));
396 for (size_t i
= 0; i
< exec
->argumentCount(); i
++)
397 m_vector
.append(exec
->argument(i
).toInt32(exec
));
401 RuntimeArray(ExecState
* exec
, Structure
* structure
)
402 : JSArray(exec
->vm(), structure
, 0)
406 static EncodedJSValue
lengthGetter(ExecState
* exec
, JSObject
*, EncodedJSValue thisValue
, PropertyName
)
408 RuntimeArray
* thisObject
= jsDynamicCast
<RuntimeArray
*>(JSValue::decode(thisValue
));
410 return throwVMTypeError(exec
);
411 return JSValue::encode(jsNumber(thisObject
->getLength()));
414 Vector
<int> m_vector
;
417 const ClassInfo
Element::s_info
= { "Element", &Base::s_info
, 0, CREATE_METHOD_TABLE(Element
) };
418 const ClassInfo
Masquerader::s_info
= { "Masquerader", &Base::s_info
, 0, CREATE_METHOD_TABLE(Masquerader
) };
419 const ClassInfo
Root::s_info
= { "Root", &Base::s_info
, 0, CREATE_METHOD_TABLE(Root
) };
420 const ClassInfo
ImpureGetter::s_info
= { "ImpureGetter", &Base::s_info
, 0, CREATE_METHOD_TABLE(ImpureGetter
) };
421 const ClassInfo
RuntimeArray::s_info
= { "RuntimeArray", &Base::s_info
, 0, CREATE_METHOD_TABLE(RuntimeArray
) };
423 ElementHandleOwner
* Element::handleOwner()
425 static ElementHandleOwner
* owner
= 0;
427 owner
= new ElementHandleOwner();
431 void Element::finishCreation(VM
& vm
, Root
* root
)
433 Base::finishCreation(vm
);
435 m_root
->setElement(this);
440 static bool fillBufferWithContentsOfFile(const String
& fileName
, Vector
<char>& buffer
);
442 static EncodedJSValue JSC_HOST_CALL
functionCreateProxy(ExecState
*);
443 static EncodedJSValue JSC_HOST_CALL
functionCreateRuntimeArray(ExecState
*);
444 static EncodedJSValue JSC_HOST_CALL
functionCreateImpureGetter(ExecState
*);
445 static EncodedJSValue JSC_HOST_CALL
functionSetImpureGetterDelegate(ExecState
*);
447 static EncodedJSValue JSC_HOST_CALL
functionSetElementRoot(ExecState
*);
448 static EncodedJSValue JSC_HOST_CALL
functionCreateRoot(ExecState
*);
449 static EncodedJSValue JSC_HOST_CALL
functionCreateElement(ExecState
*);
450 static EncodedJSValue JSC_HOST_CALL
functionGetElement(ExecState
*);
451 static EncodedJSValue JSC_HOST_CALL
functionPrint(ExecState
*);
452 static EncodedJSValue JSC_HOST_CALL
functionDebug(ExecState
*);
453 static EncodedJSValue JSC_HOST_CALL
functionDescribe(ExecState
*);
454 static EncodedJSValue JSC_HOST_CALL
functionDescribeArray(ExecState
*);
455 static EncodedJSValue JSC_HOST_CALL
functionJSCStack(ExecState
*);
456 static EncodedJSValue JSC_HOST_CALL
functionGCAndSweep(ExecState
*);
457 static EncodedJSValue JSC_HOST_CALL
functionFullGC(ExecState
*);
458 static EncodedJSValue JSC_HOST_CALL
functionEdenGC(ExecState
*);
459 static EncodedJSValue JSC_HOST_CALL
functionHeapSize(ExecState
*);
460 static EncodedJSValue JSC_HOST_CALL
functionDeleteAllCompiledCode(ExecState
*);
461 static EncodedJSValue JSC_HOST_CALL
functionAddressOf(ExecState
*);
463 static EncodedJSValue JSC_HOST_CALL
functionReleaseExecutableMemory(ExecState
*);
464 static EncodedJSValue JSC_HOST_CALL
functionDumpCallFrame(ExecState
*);
466 static EncodedJSValue JSC_HOST_CALL
functionVersion(ExecState
*);
467 static EncodedJSValue JSC_HOST_CALL
functionRun(ExecState
*);
468 static EncodedJSValue JSC_HOST_CALL
functionLoad(ExecState
*);
469 static EncodedJSValue JSC_HOST_CALL
functionReadFile(ExecState
*);
470 static EncodedJSValue JSC_HOST_CALL
functionCheckSyntax(ExecState
*);
471 static EncodedJSValue JSC_HOST_CALL
functionReadline(ExecState
*);
472 static EncodedJSValue JSC_HOST_CALL
functionPreciseTime(ExecState
*);
473 static EncodedJSValue JSC_HOST_CALL
functionNeverInlineFunction(ExecState
*);
474 static EncodedJSValue JSC_HOST_CALL
functionOptimizeNextInvocation(ExecState
*);
475 static EncodedJSValue JSC_HOST_CALL
functionNumberOfDFGCompiles(ExecState
*);
476 static EncodedJSValue JSC_HOST_CALL
functionReoptimizationRetryCount(ExecState
*);
477 static EncodedJSValue JSC_HOST_CALL
functionTransferArrayBuffer(ExecState
*);
478 static NO_RETURN_WITH_VALUE EncodedJSValue JSC_HOST_CALL
functionQuit(ExecState
*);
479 static EncodedJSValue JSC_HOST_CALL
functionFalse1(ExecState
*);
480 static EncodedJSValue JSC_HOST_CALL
functionFalse2(ExecState
*);
481 static EncodedJSValue JSC_HOST_CALL
functionUndefined1(ExecState
*);
482 static EncodedJSValue JSC_HOST_CALL
functionUndefined2(ExecState
*);
483 static EncodedJSValue JSC_HOST_CALL
functionIsInt32(ExecState
*);
484 static EncodedJSValue JSC_HOST_CALL
functionEffectful42(ExecState
*);
485 static EncodedJSValue JSC_HOST_CALL
functionIdentity(ExecState
*);
486 static EncodedJSValue JSC_HOST_CALL
functionMakeMasquerader(ExecState
*);
487 static EncodedJSValue JSC_HOST_CALL
functionHasCustomProperties(ExecState
*);
488 static EncodedJSValue JSC_HOST_CALL
functionDumpTypesForAllVariables(ExecState
*);
489 static EncodedJSValue JSC_HOST_CALL
functionFindTypeForExpression(ExecState
*);
490 static EncodedJSValue JSC_HOST_CALL
functionReturnTypeFor(ExecState
*);
491 static EncodedJSValue JSC_HOST_CALL
functionDumpBasicBlockExecutionRanges(ExecState
*);
492 static EncodedJSValue JSC_HOST_CALL
functionHasBasicBlockExecuted(ExecState
*);
493 static EncodedJSValue JSC_HOST_CALL
functionEnableExceptionFuzz(ExecState
*);
495 #if ENABLE(SAMPLING_FLAGS)
496 static EncodedJSValue JSC_HOST_CALL
functionSetSamplingFlags(ExecState
*);
497 static EncodedJSValue JSC_HOST_CALL
functionClearSamplingFlags(ExecState
*);
504 Script(bool isFile
, char *argument
)
513 CommandLine(int argc
, char** argv
)
514 : m_interactive(false)
519 parseArguments(argc
, argv
);
525 Vector
<Script
> m_scripts
;
526 Vector
<String
> m_arguments
;
528 String m_profilerOutput
;
530 void parseArguments(int, char**);
533 static const char interactivePrompt
[] = ">>> ";
539 long getElapsedMS(); // call stop() first
546 void StopWatch::start()
548 m_startTime
= monotonicallyIncreasingTime();
551 void StopWatch::stop()
553 m_stopTime
= monotonicallyIncreasingTime();
556 long StopWatch::getElapsedMS()
558 return static_cast<long>((m_stopTime
- m_startTime
) * 1000);
561 class GlobalObject
: public JSGlobalObject
{
563 GlobalObject(VM
&, Structure
*);
566 typedef JSGlobalObject Base
;
568 static GlobalObject
* create(VM
& vm
, Structure
* structure
, const Vector
<String
>& arguments
)
570 GlobalObject
* object
= new (NotNull
, allocateCell
<GlobalObject
>(vm
.heap
)) GlobalObject(vm
, structure
);
571 object
->finishCreation(vm
, arguments
);
572 vm
.heap
.addFinalizer(object
, destroy
);
576 static const bool needsDestruction
= false;
579 static const GlobalObjectMethodTable s_globalObjectMethodTable
;
581 static Structure
* createStructure(VM
& vm
, JSValue prototype
)
583 return Structure::create(vm
, 0, prototype
, TypeInfo(GlobalObjectType
, StructureFlags
), info());
586 static RuntimeFlags
javaScriptRuntimeFlags(const JSGlobalObject
*) { return RuntimeFlags::createAllEnabled(); }
589 void finishCreation(VM
& vm
, const Vector
<String
>& arguments
)
591 Base::finishCreation(vm
);
593 addFunction(vm
, "debug", functionDebug
, 1);
594 addFunction(vm
, "describe", functionDescribe
, 1);
595 addFunction(vm
, "describeArray", functionDescribeArray
, 1);
596 addFunction(vm
, "print", functionPrint
, 1);
597 addFunction(vm
, "quit", functionQuit
, 0);
598 addFunction(vm
, "gc", functionGCAndSweep
, 0);
599 addFunction(vm
, "fullGC", functionFullGC
, 0);
600 addFunction(vm
, "edenGC", functionEdenGC
, 0);
601 addFunction(vm
, "gcHeapSize", functionHeapSize
, 0);
602 addFunction(vm
, "deleteAllCompiledCode", functionDeleteAllCompiledCode
, 0);
603 addFunction(vm
, "addressOf", functionAddressOf
, 1);
605 addFunction(vm
, "dumpCallFrame", functionDumpCallFrame
, 0);
606 addFunction(vm
, "releaseExecutableMemory", functionReleaseExecutableMemory
, 0);
608 addFunction(vm
, "version", functionVersion
, 1);
609 addFunction(vm
, "run", functionRun
, 1);
610 addFunction(vm
, "load", functionLoad
, 1);
611 addFunction(vm
, "readFile", functionReadFile
, 1);
612 addFunction(vm
, "checkSyntax", functionCheckSyntax
, 1);
613 addFunction(vm
, "jscStack", functionJSCStack
, 1);
614 addFunction(vm
, "readline", functionReadline
, 0);
615 addFunction(vm
, "preciseTime", functionPreciseTime
, 0);
616 addFunction(vm
, "neverInlineFunction", functionNeverInlineFunction
, 1);
617 addFunction(vm
, "noInline", functionNeverInlineFunction
, 1);
618 addFunction(vm
, "numberOfDFGCompiles", functionNumberOfDFGCompiles
, 1);
619 addFunction(vm
, "optimizeNextInvocation", functionOptimizeNextInvocation
, 1);
620 addFunction(vm
, "reoptimizationRetryCount", functionReoptimizationRetryCount
, 1);
621 addFunction(vm
, "transferArrayBuffer", functionTransferArrayBuffer
, 1);
622 #if ENABLE(SAMPLING_FLAGS)
623 addFunction(vm
, "setSamplingFlags", functionSetSamplingFlags
, 1);
624 addFunction(vm
, "clearSamplingFlags", functionClearSamplingFlags
, 1);
626 addConstructableFunction(vm
, "Root", functionCreateRoot
, 0);
627 addConstructableFunction(vm
, "Element", functionCreateElement
, 1);
628 addFunction(vm
, "getElement", functionGetElement
, 1);
629 addFunction(vm
, "setElementRoot", functionSetElementRoot
, 2);
631 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "DFGTrue"), 0, functionFalse1
, DFGTrueIntrinsic
, DontEnum
| JSC::Function
);
632 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "OSRExit"), 0, functionUndefined1
, OSRExitIntrinsic
, DontEnum
| JSC::Function
);
633 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "isFinalTier"), 0, functionFalse2
, IsFinalTierIntrinsic
, DontEnum
| JSC::Function
);
634 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "predictInt32"), 0, functionUndefined2
, SetInt32HeapPredictionIntrinsic
, DontEnum
| JSC::Function
);
635 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "isInt32"), 0, functionIsInt32
, CheckInt32Intrinsic
, DontEnum
| JSC::Function
);
636 putDirectNativeFunction(vm
, this, Identifier::fromString(&vm
, "fiatInt52"), 0, functionIdentity
, FiatInt52Intrinsic
, DontEnum
| JSC::Function
);
638 addFunction(vm
, "effectful42", functionEffectful42
, 0);
639 addFunction(vm
, "makeMasquerader", functionMakeMasquerader
, 0);
640 addFunction(vm
, "hasCustomProperties", functionHasCustomProperties
, 0);
642 addFunction(vm
, "createProxy", functionCreateProxy
, 1);
643 addFunction(vm
, "createRuntimeArray", functionCreateRuntimeArray
, 0);
645 addFunction(vm
, "createImpureGetter", functionCreateImpureGetter
, 1);
646 addFunction(vm
, "setImpureGetterDelegate", functionSetImpureGetterDelegate
, 2);
648 addFunction(vm
, "dumpTypesForAllVariables", functionDumpTypesForAllVariables
, 0);
649 addFunction(vm
, "findTypeForExpression", functionFindTypeForExpression
, 2);
650 addFunction(vm
, "returnTypeFor", functionReturnTypeFor
, 1);
652 addFunction(vm
, "dumpBasicBlockExecutionRanges", functionDumpBasicBlockExecutionRanges
, 0);
653 addFunction(vm
, "hasBasicBlockExecuted", functionHasBasicBlockExecuted
, 2);
655 addFunction(vm
, "enableExceptionFuzz", functionEnableExceptionFuzz
, 0);
657 JSArray
* array
= constructEmptyArray(globalExec(), 0);
658 for (size_t i
= 0; i
< arguments
.size(); ++i
)
659 array
->putDirectIndex(globalExec(), i
, jsString(globalExec(), arguments
[i
]));
660 putDirect(vm
, Identifier::fromString(globalExec(), "arguments"), array
);
662 putDirect(vm
, Identifier::fromString(globalExec(), "console"), jsUndefined());
665 void addFunction(VM
& vm
, const char* name
, NativeFunction function
, unsigned arguments
)
667 Identifier identifier
= Identifier::fromString(&vm
, name
);
668 putDirect(vm
, identifier
, JSFunction::create(vm
, this, arguments
, identifier
.string(), function
));
671 void addConstructableFunction(VM
& vm
, const char* name
, NativeFunction function
, unsigned arguments
)
673 Identifier identifier
= Identifier::fromString(&vm
, name
);
674 putDirect(vm
, identifier
, JSFunction::create(vm
, this, arguments
, identifier
.string(), function
, NoIntrinsic
, function
));
678 const ClassInfo
GlobalObject::s_info
= { "global", &JSGlobalObject::s_info
, &globalObjectTable
, CREATE_METHOD_TABLE(GlobalObject
) };
679 const GlobalObjectMethodTable
GlobalObject::s_globalObjectMethodTable
= { &allowsAccessFrom
, &supportsProfiling
, &supportsRichSourceInfo
, &shouldInterruptScript
, &javaScriptRuntimeFlags
, 0, &shouldInterruptScriptBeforeTimeout
};
682 GlobalObject::GlobalObject(VM
& vm
, Structure
* structure
)
683 : JSGlobalObject(vm
, structure
, &s_globalObjectMethodTable
)
687 static inline String
stringFromUTF(const char* utf8
)
689 return String::fromUTF8WithLatin1Fallback(utf8
, strlen(utf8
));
692 static inline SourceCode
jscSource(const char* utf8
, const String
& filename
)
694 String str
= stringFromUTF(utf8
);
695 return makeSource(str
, filename
);
698 EncodedJSValue JSC_HOST_CALL
functionPrint(ExecState
* exec
)
700 for (unsigned i
= 0; i
< exec
->argumentCount(); ++i
) {
704 printf("%s", exec
->uncheckedArgument(i
).toString(exec
)->view(exec
).get().utf8().data());
709 return JSValue::encode(jsUndefined());
713 EncodedJSValue JSC_HOST_CALL
functionDumpCallFrame(ExecState
* exec
)
715 VMEntryFrame
* topVMEntryFrame
= exec
->vm().topVMEntryFrame
;
716 ExecState
* callerFrame
= exec
->callerFrame(topVMEntryFrame
);
718 exec
->vm().interpreter
->dumpCallFrame(callerFrame
);
719 return JSValue::encode(jsUndefined());
723 EncodedJSValue JSC_HOST_CALL
functionDebug(ExecState
* exec
)
725 fprintf(stderr
, "--> %s\n", exec
->argument(0).toString(exec
)->view(exec
).get().utf8().data());
726 return JSValue::encode(jsUndefined());
729 EncodedJSValue JSC_HOST_CALL
functionDescribe(ExecState
* exec
)
731 if (exec
->argumentCount() < 1)
732 return JSValue::encode(jsUndefined());
733 return JSValue::encode(jsString(exec
, toString(exec
->argument(0))));
736 EncodedJSValue JSC_HOST_CALL
functionDescribeArray(ExecState
* exec
)
738 if (exec
->argumentCount() < 1)
739 return JSValue::encode(jsUndefined());
740 JSObject
* object
= jsDynamicCast
<JSObject
*>(exec
->argument(0));
742 return JSValue::encode(jsNontrivialString(exec
, ASCIILiteral("<not object>")));
743 return JSValue::encode(jsNontrivialString(exec
, toString("<Public length: ", object
->getArrayLength(), "; vector length: ", object
->getVectorLength(), ">")));
746 class FunctionJSCStackFunctor
{
748 FunctionJSCStackFunctor(StringBuilder
& trace
)
753 StackVisitor::Status
operator()(StackVisitor
& visitor
)
755 m_trace
.append(String::format(" %zu %s\n", visitor
->index(), visitor
->toString().utf8().data()));
756 return StackVisitor::Continue
;
760 StringBuilder
& m_trace
;
763 EncodedJSValue JSC_HOST_CALL
functionJSCStack(ExecState
* exec
)
766 trace
.appendLiteral("--> Stack trace:\n");
768 FunctionJSCStackFunctor
functor(trace
);
769 exec
->iterate(functor
);
770 fprintf(stderr
, "%s", trace
.toString().utf8().data());
771 return JSValue::encode(jsUndefined());
774 EncodedJSValue JSC_HOST_CALL
functionCreateRoot(ExecState
* exec
)
776 JSLockHolder
lock(exec
);
777 return JSValue::encode(Root::create(exec
->vm(), exec
->lexicalGlobalObject()));
780 EncodedJSValue JSC_HOST_CALL
functionCreateElement(ExecState
* exec
)
782 JSLockHolder
lock(exec
);
783 JSValue arg
= exec
->argument(0);
784 return JSValue::encode(Element::create(exec
->vm(), exec
->lexicalGlobalObject(), arg
.isNull() ? nullptr : jsCast
<Root
*>(exec
->argument(0))));
787 EncodedJSValue JSC_HOST_CALL
functionGetElement(ExecState
* exec
)
789 JSLockHolder
lock(exec
);
790 Element
* result
= jsCast
<Root
*>(exec
->argument(0).asCell())->element();
791 return JSValue::encode(result
? result
: jsUndefined());
794 EncodedJSValue JSC_HOST_CALL
functionSetElementRoot(ExecState
* exec
)
796 JSLockHolder
lock(exec
);
797 Element
* element
= jsCast
<Element
*>(exec
->argument(0));
798 Root
* root
= jsCast
<Root
*>(exec
->argument(1));
799 element
->setRoot(exec
->vm(), root
);
800 return JSValue::encode(jsUndefined());
803 EncodedJSValue JSC_HOST_CALL
functionCreateProxy(ExecState
* exec
)
805 JSLockHolder
lock(exec
);
806 JSValue target
= exec
->argument(0);
807 if (!target
.isObject())
808 return JSValue::encode(jsUndefined());
809 JSObject
* jsTarget
= asObject(target
.asCell());
810 Structure
* structure
= JSProxy::createStructure(exec
->vm(), exec
->lexicalGlobalObject(), jsTarget
->prototype());
811 JSProxy
* proxy
= JSProxy::create(exec
->vm(), structure
, jsTarget
);
812 return JSValue::encode(proxy
);
815 EncodedJSValue JSC_HOST_CALL
functionCreateRuntimeArray(ExecState
* exec
)
817 JSLockHolder
lock(exec
);
818 RuntimeArray
* array
= RuntimeArray::create(exec
);
819 return JSValue::encode(array
);
822 EncodedJSValue JSC_HOST_CALL
functionCreateImpureGetter(ExecState
* exec
)
824 JSLockHolder
lock(exec
);
825 JSValue target
= exec
->argument(0);
826 JSObject
* delegate
= nullptr;
827 if (target
.isObject())
828 delegate
= asObject(target
.asCell());
829 Structure
* structure
= ImpureGetter::createStructure(exec
->vm(), exec
->lexicalGlobalObject(), jsNull());
830 ImpureGetter
* result
= ImpureGetter::create(exec
->vm(), structure
, delegate
);
831 return JSValue::encode(result
);
834 EncodedJSValue JSC_HOST_CALL
functionSetImpureGetterDelegate(ExecState
* exec
)
836 JSLockHolder
lock(exec
);
837 JSValue base
= exec
->argument(0);
838 if (!base
.isObject())
839 return JSValue::encode(jsUndefined());
840 JSValue delegate
= exec
->argument(1);
841 if (!delegate
.isObject())
842 return JSValue::encode(jsUndefined());
843 ImpureGetter
* impureGetter
= jsCast
<ImpureGetter
*>(asObject(base
.asCell()));
844 impureGetter
->setDelegate(exec
->vm(), asObject(delegate
.asCell()));
845 return JSValue::encode(jsUndefined());
848 EncodedJSValue JSC_HOST_CALL
functionGCAndSweep(ExecState
* exec
)
850 JSLockHolder
lock(exec
);
851 exec
->heap()->collectAllGarbage();
852 return JSValue::encode(jsNumber(exec
->heap()->sizeAfterLastFullCollection()));
855 EncodedJSValue JSC_HOST_CALL
functionFullGC(ExecState
* exec
)
857 JSLockHolder
lock(exec
);
858 exec
->heap()->collect(FullCollection
);
859 return JSValue::encode(jsNumber(exec
->heap()->sizeAfterLastFullCollection()));
862 EncodedJSValue JSC_HOST_CALL
functionEdenGC(ExecState
* exec
)
864 JSLockHolder
lock(exec
);
865 exec
->heap()->collect(EdenCollection
);
866 return JSValue::encode(jsNumber(exec
->heap()->sizeAfterLastEdenCollection()));
869 EncodedJSValue JSC_HOST_CALL
functionHeapSize(ExecState
* exec
)
871 JSLockHolder
lock(exec
);
872 return JSValue::encode(jsNumber(exec
->heap()->size()));
875 EncodedJSValue JSC_HOST_CALL
functionDeleteAllCompiledCode(ExecState
* exec
)
877 JSLockHolder
lock(exec
);
878 exec
->heap()->deleteAllCompiledCode();
879 return JSValue::encode(jsUndefined());
882 // This function is not generally very helpful in 64-bit code as the tag and payload
883 // share a register. But in 32-bit JITed code the tag may not be checked if an
884 // optimization removes type checking requirements, such as in ===.
885 EncodedJSValue JSC_HOST_CALL
functionAddressOf(ExecState
* exec
)
887 JSValue value
= exec
->argument(0);
889 return JSValue::encode(jsUndefined());
890 // Need to cast to uint64_t so bitwise_cast will play along.
891 uint64_t asNumber
= reinterpret_cast<uint64_t>(value
.asCell());
892 EncodedJSValue returnValue
= JSValue::encode(jsNumber(bitwise_cast
<double>(asNumber
)));
898 EncodedJSValue JSC_HOST_CALL
functionReleaseExecutableMemory(ExecState
* exec
)
900 JSLockHolder
lock(exec
);
901 exec
->vm().releaseExecutableMemory();
902 return JSValue::encode(jsUndefined());
906 EncodedJSValue JSC_HOST_CALL
functionVersion(ExecState
*)
908 // We need this function for compatibility with the Mozilla JS tests but for now
909 // we don't actually do any version-specific handling
910 return JSValue::encode(jsUndefined());
913 EncodedJSValue JSC_HOST_CALL
functionRun(ExecState
* exec
)
915 String fileName
= exec
->argument(0).toString(exec
)->value(exec
);
917 if (!fillBufferWithContentsOfFile(fileName
, script
))
918 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Could not open file."))));
920 GlobalObject
* globalObject
= GlobalObject::create(exec
->vm(), GlobalObject::createStructure(exec
->vm(), jsNull()), Vector
<String
>());
922 JSArray
* array
= constructEmptyArray(globalObject
->globalExec(), 0);
923 for (unsigned i
= 1; i
< exec
->argumentCount(); ++i
)
924 array
->putDirectIndex(globalObject
->globalExec(), i
- 1, exec
->uncheckedArgument(i
));
925 globalObject
->putDirect(
926 exec
->vm(), Identifier::fromString(globalObject
->globalExec(), "arguments"), array
);
928 NakedPtr
<Exception
> exception
;
931 evaluate(globalObject
->globalExec(), jscSource(script
.data(), fileName
), JSValue(), exception
);
935 exec
->vm().throwException(globalObject
->globalExec(), exception
);
936 return JSValue::encode(jsUndefined());
939 return JSValue::encode(jsNumber(stopWatch
.getElapsedMS()));
942 EncodedJSValue JSC_HOST_CALL
functionLoad(ExecState
* exec
)
944 String fileName
= exec
->argument(0).toString(exec
)->value(exec
);
946 if (!fillBufferWithContentsOfFile(fileName
, script
))
947 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Could not open file."))));
949 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
951 NakedPtr
<Exception
> evaluationException
;
952 JSValue result
= evaluate(globalObject
->globalExec(), jscSource(script
.data(), fileName
), JSValue(), evaluationException
);
953 if (evaluationException
)
954 exec
->vm().throwException(exec
, evaluationException
);
955 return JSValue::encode(result
);
958 EncodedJSValue JSC_HOST_CALL
functionReadFile(ExecState
* exec
)
960 String fileName
= exec
->argument(0).toString(exec
)->value(exec
);
962 if (!fillBufferWithContentsOfFile(fileName
, script
))
963 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Could not open file."))));
965 return JSValue::encode(jsString(exec
, stringFromUTF(script
.data())));
968 EncodedJSValue JSC_HOST_CALL
functionCheckSyntax(ExecState
* exec
)
970 String fileName
= exec
->argument(0).toString(exec
)->value(exec
);
972 if (!fillBufferWithContentsOfFile(fileName
, script
))
973 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Could not open file."))));
975 JSGlobalObject
* globalObject
= exec
->lexicalGlobalObject();
980 JSValue syntaxException
;
981 bool validSyntax
= checkSyntax(globalObject
->globalExec(), jscSource(script
.data(), fileName
), &syntaxException
);
985 exec
->vm().throwException(exec
, syntaxException
);
986 return JSValue::encode(jsNumber(stopWatch
.getElapsedMS()));
989 #if ENABLE(SAMPLING_FLAGS)
990 EncodedJSValue JSC_HOST_CALL
functionSetSamplingFlags(ExecState
* exec
)
992 for (unsigned i
= 0; i
< exec
->argumentCount(); ++i
) {
993 unsigned flag
= static_cast<unsigned>(exec
->uncheckedArgument(i
).toNumber(exec
));
994 if ((flag
>= 1) && (flag
<= 32))
995 SamplingFlags::setFlag(flag
);
997 return JSValue::encode(jsNull());
1000 EncodedJSValue JSC_HOST_CALL
functionClearSamplingFlags(ExecState
* exec
)
1002 for (unsigned i
= 0; i
< exec
->argumentCount(); ++i
) {
1003 unsigned flag
= static_cast<unsigned>(exec
->uncheckedArgument(i
).toNumber(exec
));
1004 if ((flag
>= 1) && (flag
<= 32))
1005 SamplingFlags::clearFlag(flag
);
1007 return JSValue::encode(jsNull());
1011 EncodedJSValue JSC_HOST_CALL
functionReadline(ExecState
* exec
)
1013 Vector
<char, 256> line
;
1015 while ((c
= getchar()) != EOF
) {
1016 // FIXME: Should we also break on \r?
1022 return JSValue::encode(jsString(exec
, line
.data()));
1025 EncodedJSValue JSC_HOST_CALL
functionPreciseTime(ExecState
*)
1027 return JSValue::encode(jsNumber(currentTime()));
1030 EncodedJSValue JSC_HOST_CALL
functionNeverInlineFunction(ExecState
* exec
)
1032 return JSValue::encode(setNeverInline(exec
));
1035 EncodedJSValue JSC_HOST_CALL
functionOptimizeNextInvocation(ExecState
* exec
)
1037 return JSValue::encode(optimizeNextInvocation(exec
));
1040 EncodedJSValue JSC_HOST_CALL
functionNumberOfDFGCompiles(ExecState
* exec
)
1042 return JSValue::encode(numberOfDFGCompiles(exec
));
1045 EncodedJSValue JSC_HOST_CALL
functionReoptimizationRetryCount(ExecState
* exec
)
1047 if (exec
->argumentCount() < 1)
1048 return JSValue::encode(jsUndefined());
1050 CodeBlock
* block
= getSomeBaselineCodeBlockForFunction(exec
->argument(0));
1052 return JSValue::encode(jsNumber(0));
1054 return JSValue::encode(jsNumber(block
->reoptimizationRetryCounter()));
1057 EncodedJSValue JSC_HOST_CALL
functionTransferArrayBuffer(ExecState
* exec
)
1059 if (exec
->argumentCount() < 1)
1060 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Not enough arguments"))));
1062 JSArrayBuffer
* buffer
= jsDynamicCast
<JSArrayBuffer
*>(exec
->argument(0));
1064 return JSValue::encode(exec
->vm().throwException(exec
, createError(exec
, ASCIILiteral("Expected an array buffer"))));
1066 ArrayBufferContents dummyContents
;
1067 buffer
->impl()->transfer(dummyContents
);
1069 return JSValue::encode(jsUndefined());
1072 EncodedJSValue JSC_HOST_CALL
functionQuit(ExecState
*)
1074 jscExit(EXIT_SUCCESS
);
1077 // Without this, Visual Studio will complain that this method does not return a value.
1078 return JSValue::encode(jsUndefined());
1082 EncodedJSValue JSC_HOST_CALL
functionFalse1(ExecState
*) { return JSValue::encode(jsBoolean(false)); }
1083 EncodedJSValue JSC_HOST_CALL
functionFalse2(ExecState
*) { return JSValue::encode(jsBoolean(false)); }
1085 EncodedJSValue JSC_HOST_CALL
functionUndefined1(ExecState
*) { return JSValue::encode(jsUndefined()); }
1086 EncodedJSValue JSC_HOST_CALL
functionUndefined2(ExecState
*) { return JSValue::encode(jsUndefined()); }
1087 EncodedJSValue JSC_HOST_CALL
functionIsInt32(ExecState
* exec
)
1089 for (size_t i
= 0; i
< exec
->argumentCount(); ++i
) {
1090 if (!exec
->argument(i
).isInt32())
1091 return JSValue::encode(jsBoolean(false));
1093 return JSValue::encode(jsBoolean(true));
1096 EncodedJSValue JSC_HOST_CALL
functionIdentity(ExecState
* exec
) { return JSValue::encode(exec
->argument(0)); }
1098 EncodedJSValue JSC_HOST_CALL
functionEffectful42(ExecState
*)
1100 return JSValue::encode(jsNumber(42));
1103 EncodedJSValue JSC_HOST_CALL
functionMakeMasquerader(ExecState
* exec
)
1105 return JSValue::encode(Masquerader::create(exec
->vm(), exec
->lexicalGlobalObject()));
1108 EncodedJSValue JSC_HOST_CALL
functionHasCustomProperties(ExecState
* exec
)
1110 JSValue value
= exec
->argument(0);
1111 if (value
.isObject())
1112 return JSValue::encode(jsBoolean(asObject(value
)->hasCustomProperties()));
1113 return JSValue::encode(jsBoolean(false));
1116 EncodedJSValue JSC_HOST_CALL
functionDumpTypesForAllVariables(ExecState
* exec
)
1118 exec
->vm().dumpTypeProfilerData();
1119 return JSValue::encode(jsUndefined());
1122 EncodedJSValue JSC_HOST_CALL
functionFindTypeForExpression(ExecState
* exec
)
1124 RELEASE_ASSERT(exec
->vm().typeProfiler());
1125 exec
->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionFindTypeForExpression"));
1127 JSValue functionValue
= exec
->argument(0);
1128 RELEASE_ASSERT(functionValue
.isFunction());
1129 FunctionExecutable
* executable
= (jsDynamicCast
<JSFunction
*>(functionValue
.asCell()->getObject()))->jsExecutable();
1131 RELEASE_ASSERT(exec
->argument(1).isString());
1132 String substring
= exec
->argument(1).getString(exec
);
1133 String sourceCodeText
= executable
->source().toString();
1134 unsigned offset
= static_cast<unsigned>(sourceCodeText
.find(substring
) + executable
->source().startOffset());
1136 String jsonString
= exec
->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal
, offset
, executable
->sourceID(), exec
->vm());
1137 return JSValue::encode(JSONParse(exec
, jsonString
));
1140 EncodedJSValue JSC_HOST_CALL
functionReturnTypeFor(ExecState
* exec
)
1142 RELEASE_ASSERT(exec
->vm().typeProfiler());
1143 exec
->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("jsc Testing API: functionReturnTypeFor"));
1145 JSValue functionValue
= exec
->argument(0);
1146 RELEASE_ASSERT(functionValue
.isFunction());
1147 FunctionExecutable
* executable
= (jsDynamicCast
<JSFunction
*>(functionValue
.asCell()->getObject()))->jsExecutable();
1149 unsigned offset
= executable
->source().startOffset();
1150 String jsonString
= exec
->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorFunctionReturn
, offset
, executable
->sourceID(), exec
->vm());
1151 return JSValue::encode(JSONParse(exec
, jsonString
));
1154 EncodedJSValue JSC_HOST_CALL
functionDumpBasicBlockExecutionRanges(ExecState
* exec
)
1156 RELEASE_ASSERT(exec
->vm().controlFlowProfiler());
1157 exec
->vm().controlFlowProfiler()->dumpData();
1158 return JSValue::encode(jsUndefined());
1161 EncodedJSValue JSC_HOST_CALL
functionHasBasicBlockExecuted(ExecState
* exec
)
1163 RELEASE_ASSERT(exec
->vm().controlFlowProfiler());
1165 JSValue functionValue
= exec
->argument(0);
1166 RELEASE_ASSERT(functionValue
.isFunction());
1167 FunctionExecutable
* executable
= (jsDynamicCast
<JSFunction
*>(functionValue
.asCell()->getObject()))->jsExecutable();
1169 RELEASE_ASSERT(exec
->argument(1).isString());
1170 String substring
= exec
->argument(1).getString(exec
);
1171 String sourceCodeText
= executable
->source().toString();
1172 RELEASE_ASSERT(sourceCodeText
.contains(substring
));
1173 int offset
= sourceCodeText
.find(substring
) + executable
->source().startOffset();
1175 bool hasExecuted
= exec
->vm().controlFlowProfiler()->hasBasicBlockAtTextOffsetBeenExecuted(offset
, executable
->sourceID(), exec
->vm());
1176 return JSValue::encode(jsBoolean(hasExecuted
));
1179 EncodedJSValue JSC_HOST_CALL
functionEnableExceptionFuzz(ExecState
*)
1181 Options::enableExceptionFuzz() = true;
1182 return JSValue::encode(jsUndefined());
1185 // Use SEH for Release builds only to get rid of the crash report dialog
1186 // (luckily the same tests fail in Release and Debug builds so far). Need to
1187 // be in a separate main function because the jscmain function requires object
1190 #if COMPILER(MSVC) && !defined(_DEBUG)
1192 #define EXCEPT(x) } __except (EXCEPTION_EXECUTE_HANDLER) { x; }
1198 int jscmain(int argc
, char** argv
);
1200 static double s_desiredTimeout
;
1202 static NO_RETURN_DUE_TO_CRASH
void timeoutThreadMain(void*)
1204 auto timeout
= std::chrono::microseconds(static_cast<std::chrono::microseconds::rep
>(s_desiredTimeout
* 1000000));
1205 std::this_thread::sleep_for(timeout
);
1207 dataLog("Timed out after ", s_desiredTimeout
, " seconds!\n");
1211 int main(int argc
, char** argv
)
1213 #if PLATFORM(IOS) && CPU(ARM_THUMB2)
1214 // Enabled IEEE754 denormal support.
1217 env
.__fpscr
&= ~0x01000000u
;
1221 #if OS(WINDOWS) && (defined(_M_X64) || defined(__x86_64__))
1222 // The VS2013 runtime has a bug where it mis-detects AVX-capable processors
1223 // if the feature has been disabled in firmware. This causes us to crash
1224 // in some of the math functions. For now, we disable those optimizations
1225 // because Microsoft is not going to fix the problem in VS2013.
1226 // FIXME: http://webkit.org/b/141449: Remove this workaround when we switch to VS2015+.
1227 _set_FMA3_enable(0);
1229 // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
1230 // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
1231 // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
1235 _CrtSetReportFile(_CRT_WARN
, _CRTDBG_FILE_STDERR
);
1236 _CrtSetReportMode(_CRT_WARN
, _CRTDBG_MODE_FILE
);
1237 _CrtSetReportFile(_CRT_ERROR
, _CRTDBG_FILE_STDERR
);
1238 _CrtSetReportMode(_CRT_ERROR
, _CRTDBG_MODE_FILE
);
1239 _CrtSetReportFile(_CRT_ASSERT
, _CRTDBG_FILE_STDERR
);
1240 _CrtSetReportMode(_CRT_ASSERT
, _CRTDBG_MODE_FILE
);
1250 // Need to initialize WTF threading before we start any threads. Cannot initialize JSC
1251 // threading yet, since that would do somethings that we'd like to defer until after we
1252 // have a chance to parse options.
1253 WTF::initializeThreading();
1255 if (char* timeoutString
= getenv("JSC_timeout")) {
1256 if (sscanf(timeoutString
, "%lf", &s_desiredTimeout
) != 1) {
1258 "WARNING: timeout string is malformed, got ", timeoutString
,
1259 " but expected a number. Not using a timeout.\n");
1261 createThread(timeoutThreadMain
, 0, "jsc Timeout Thread");
1265 Options::crashIfCantAllocateJITMemory() = true;
1268 // We can't use destructors in the following code because it uses Windows
1269 // Structured Exception Handling
1272 res
= jscmain(argc
, argv
);
1274 if (Options::logHeapStatisticsAtExit())
1275 HeapStatistics::reportSuccess();
1284 static bool runWithScripts(GlobalObject
* globalObject
, const Vector
<Script
>& scripts
, bool dump
)
1288 Vector
<char> scriptBuffer
;
1291 JSC::Options::dumpGeneratedBytecodes() = true;
1293 VM
& vm
= globalObject
->vm();
1295 #if ENABLE(SAMPLING_FLAGS)
1296 SamplingFlags::start();
1299 bool success
= true;
1300 for (size_t i
= 0; i
< scripts
.size(); i
++) {
1301 if (scripts
[i
].isFile
) {
1302 fileName
= scripts
[i
].argument
;
1303 if (!fillBufferWithContentsOfFile(fileName
, scriptBuffer
))
1304 return false; // fail early so we can catch missing files
1305 script
= scriptBuffer
.data();
1307 script
= scripts
[i
].argument
;
1308 fileName
= ASCIILiteral("[Command Line]");
1313 NakedPtr
<Exception
> evaluationException
;
1314 JSValue returnValue
= evaluate(globalObject
->globalExec(), jscSource(script
, fileName
), JSValue(), evaluationException
);
1315 success
= success
&& !evaluationException
;
1316 if (dump
&& !evaluationException
)
1317 printf("End: %s\n", returnValue
.toString(globalObject
->globalExec())->value(globalObject
->globalExec()).utf8().data());
1318 if (evaluationException
) {
1319 printf("Exception: %s\n", evaluationException
->value().toString(globalObject
->globalExec())->value(globalObject
->globalExec()).utf8().data());
1320 Identifier stackID
= Identifier::fromString(globalObject
->globalExec(), "stack");
1321 JSValue stackValue
= evaluationException
->value().get(globalObject
->globalExec(), stackID
);
1322 if (!stackValue
.isUndefinedOrNull())
1323 printf("%s\n", stackValue
.toString(globalObject
->globalExec())->value(globalObject
->globalExec()).utf8().data());
1327 globalObject
->globalExec()->clearException();
1330 #if ENABLE(SAMPLING_FLAGS)
1331 SamplingFlags::stop();
1333 #if ENABLE(SAMPLING_REGIONS)
1334 SamplingRegion::dump();
1336 vm
.dumpSampleData(globalObject
->globalExec());
1337 #if ENABLE(SAMPLING_COUNTERS)
1338 AbstractSamplingCounter::dump();
1340 #if ENABLE(REGEXP_TRACING)
1341 vm
.dumpRegExpTrace();
1346 #define RUNNING_FROM_XCODE 0
1348 static void runInteractive(GlobalObject
* globalObject
)
1350 String
interpreterName(ASCIILiteral("Interpreter"));
1352 bool shouldQuit
= false;
1353 while (!shouldQuit
) {
1354 #if HAVE(READLINE) && !RUNNING_FROM_XCODE
1358 error
= ParserError();
1359 char* line
= readline(source
.isEmpty() ? interactivePrompt
: "... ");
1363 source
= source
+ line
;
1364 source
= source
+ '\n';
1365 checkSyntax(globalObject
->vm(), makeSource(source
, interpreterName
), error
);
1369 } while (error
.syntaxErrorType() == ParserError::SyntaxErrorRecoverable
);
1371 if (error
.isValid()) {
1372 printf("%s:%d\n", error
.message().utf8().data(), error
.line());
1377 NakedPtr
<Exception
> evaluationException
;
1378 JSValue returnValue
= evaluate(globalObject
->globalExec(), makeSource(source
, interpreterName
), JSValue(), evaluationException
);
1380 printf("%s", interactivePrompt
);
1381 Vector
<char, 256> line
;
1383 while ((c
= getchar()) != EOF
) {
1384 // FIXME: Should we also break on \r?
1393 NakedPtr
<Exception
> evaluationException
;
1394 JSValue returnValue
= evaluate(globalObject
->globalExec(), jscSource(line
.data(), interpreterName
), JSValue(), evaluationException
);
1396 if (evaluationException
)
1397 printf("Exception: %s\n", evaluationException
->value().toString(globalObject
->globalExec())->value(globalObject
->globalExec()).utf8().data());
1399 printf("%s\n", returnValue
.toString(globalObject
->globalExec())->value(globalObject
->globalExec()).utf8().data());
1401 globalObject
->globalExec()->clearException();
1406 static NO_RETURN
void printUsageStatement(bool help
= false)
1408 fprintf(stderr
, "Usage: jsc [options] [files] [-- arguments]\n");
1409 fprintf(stderr
, " -d Dumps bytecode (debug builds only)\n");
1410 fprintf(stderr
, " -e Evaluate argument as script code\n");
1411 fprintf(stderr
, " -f Specifies a source file (deprecated)\n");
1412 fprintf(stderr
, " -h|--help Prints this help message\n");
1413 fprintf(stderr
, " -i Enables interactive mode (default if no files are specified)\n");
1415 fprintf(stderr
, " -s Installs signal handlers that exit on a crash (Unix platforms only)\n");
1417 fprintf(stderr
, " -p <file> Outputs profiling data to a file\n");
1418 fprintf(stderr
, " -x Output exit code before terminating\n");
1419 fprintf(stderr
, "\n");
1420 fprintf(stderr
, " --options Dumps all JSC VM options and exits\n");
1421 fprintf(stderr
, " --dumpOptions Dumps all JSC VM options before continuing\n");
1422 fprintf(stderr
, " --<jsc VM option>=<value> Sets the specified JSC VM option\n");
1423 fprintf(stderr
, "\n");
1425 jscExit(help
? EXIT_SUCCESS
: EXIT_FAILURE
);
1428 void CommandLine::parseArguments(int argc
, char** argv
)
1430 Options::initialize();
1433 bool needToDumpOptions
= false;
1434 bool needToExit
= false;
1436 for (; i
< argc
; ++i
) {
1437 const char* arg
= argv
[i
];
1438 if (!strcmp(arg
, "-f")) {
1440 printUsageStatement();
1441 m_scripts
.append(Script(true, argv
[i
]));
1444 if (!strcmp(arg
, "-e")) {
1446 printUsageStatement();
1447 m_scripts
.append(Script(false, argv
[i
]));
1450 if (!strcmp(arg
, "-i")) {
1451 m_interactive
= true;
1454 if (!strcmp(arg
, "-d")) {
1458 if (!strcmp(arg
, "-p")) {
1460 printUsageStatement();
1462 m_profilerOutput
= argv
[i
];
1465 if (!strcmp(arg
, "-s")) {
1467 signal(SIGILL
, _exit
);
1468 signal(SIGFPE
, _exit
);
1469 signal(SIGBUS
, _exit
);
1470 signal(SIGSEGV
, _exit
);
1474 if (!strcmp(arg
, "-x")) {
1478 if (!strcmp(arg
, "--")) {
1482 if (!strcmp(arg
, "-h") || !strcmp(arg
, "--help"))
1483 printUsageStatement(true);
1485 if (!strcmp(arg
, "--options")) {
1486 needToDumpOptions
= true;
1490 if (!strcmp(arg
, "--dumpOptions")) {
1491 needToDumpOptions
= true;
1495 // See if the -- option is a JSC VM option.
1496 if (strstr(arg
, "--") == arg
&& JSC::Options::setOption(&arg
[2])) {
1497 // The arg was recognized as a VM option and has been parsed.
1498 continue; // Just continue with the next arg.
1501 // This arg is not recognized by the VM nor by jsc. Pass it on to the
1503 m_scripts
.append(Script(true, argv
[i
]));
1506 if (m_scripts
.isEmpty())
1507 m_interactive
= true;
1509 for (; i
< argc
; ++i
)
1510 m_arguments
.append(argv
[i
]);
1512 if (needToDumpOptions
)
1513 JSC::Options::dumpAllOptions(JSC::Options::DumpLevel::Verbose
, "All JSC runtime options:", stderr
);
1514 JSC::Options::ensureOptionsAreCoherent();
1516 jscExit(EXIT_SUCCESS
);
1519 int jscmain(int argc
, char** argv
)
1521 // Note that the options parsing can affect VM creation, and thus
1523 CommandLine
options(argc
, argv
);
1525 // Initialize JSC before getting VM.
1526 #if ENABLE(SAMPLING_REGIONS)
1527 WTF::initializeMainThread();
1529 JSC::initializeThreading();
1531 VM
* vm
= &VM::create(LargeHeap
).leakRef();
1534 JSLockHolder
locker(vm
);
1536 if (options
.m_profile
&& !vm
->m_perBytecodeProfiler
)
1537 vm
->m_perBytecodeProfiler
= std::make_unique
<Profiler::Database
>(*vm
);
1539 GlobalObject
* globalObject
= GlobalObject::create(*vm
, GlobalObject::createStructure(*vm
, jsNull()), options
.m_arguments
);
1540 bool success
= runWithScripts(globalObject
, options
.m_scripts
, options
.m_dump
);
1541 if (options
.m_interactive
&& success
)
1542 runInteractive(globalObject
);
1544 result
= success
? 0 : 3;
1546 if (options
.m_exitCode
)
1547 printf("jsc exiting %d\n", result
);
1549 if (options
.m_profile
) {
1550 if (!vm
->m_perBytecodeProfiler
->save(options
.m_profilerOutput
.utf8().data()))
1551 fprintf(stderr
, "could not save profiler output.\n");
1555 if (Options::enableExceptionFuzz())
1556 printf("JSC EXCEPTION FUZZ: encountered %u checks.\n", numberOfExceptionFuzzChecks());
1557 bool fireAtEnabled
=
1558 Options::fireExecutableAllocationFuzzAt() || Options::fireExecutableAllocationFuzzAtOrAfter();
1559 if (Options::enableExecutableAllocationFuzz() && (!fireAtEnabled
|| Options::verboseExecutableAllocationFuzz()))
1560 printf("JSC EXECUTABLE ALLOCATION FUZZ: encountered %u checks.\n", numberOfExecutableAllocationFuzzChecks());
1561 if (Options::enableOSRExitFuzz()) {
1562 printf("JSC OSR EXIT FUZZ: encountered %u static checks.\n", numberOfStaticOSRExitFuzzChecks());
1563 printf("JSC OSR EXIT FUZZ: encountered %u dynamic checks.\n", numberOfOSRExitFuzzChecks());
1571 static bool fillBufferWithContentsOfFile(const String
& fileName
, Vector
<char>& buffer
)
1573 FILE* f
= fopen(fileName
.utf8().data(), "r");
1575 fprintf(stderr
, "Could not open file: %s\n", fileName
.utf8().data());
1579 size_t bufferSize
= 0;
1580 size_t bufferCapacity
= 1024;
1582 buffer
.resize(bufferCapacity
);
1584 while (!feof(f
) && !ferror(f
)) {
1585 bufferSize
+= fread(buffer
.data() + bufferSize
, 1, bufferCapacity
- bufferSize
, f
);
1586 if (bufferSize
== bufferCapacity
) { // guarantees space for trailing '\0'
1587 bufferCapacity
*= 2;
1588 buffer
.resize(bufferCapacity
);
1592 buffer
[bufferSize
] = '\0';
1594 if (buffer
[0] == '#' && buffer
[1] == '!')
1595 buffer
[0] = buffer
[1] = '/';
1601 extern "C" __declspec(dllexport
) int WINAPI
dllLauncherEntryPoint(int argc
, const char* argv
[])
1603 return main(argc
, const_cast<char**>(argv
));