+2016-11-02 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [DOMJIT] Add DOMJIT::Signature
+ https://bugs.webkit.org/show_bug.cgi?id=162980
+
+ Reviewed by Saam Barati and Sam Weinig.
+
+ * js/dom/domjit-accessor-licm.html:
+ * js/dom/domjit-function-effect-should-overlap-with-call-expected.txt: Added.
+ * js/dom/domjit-function-effect-should-overlap-with-call.html: Added.
+ * js/dom/domjit-function-expected.txt: Added.
+ * js/dom/domjit-function-licm-expected.txt: Added.
+ * js/dom/domjit-function-licm.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html.
+ * js/dom/domjit-function-type-contradiction-expected.txt: Added.
+ * js/dom/domjit-function-type-contradiction.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html.
+ * js/dom/domjit-function-type-failure-expected.txt: Added.
+ * js/dom/domjit-function-type-failure.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html.
+ * js/dom/domjit-function.html: Added.
+
2016-11-02 Ryan Haddad <ryanhaddad@apple.com>
Marking imported/mozilla/svg/paint-order-01.svg and imported/mozilla/svg/paint-order-02.svg as flaky.
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
-<meta charset="UTF-8">
-</head>
-<body>
-<script>
-
-</script>
-</body>
-</html>
<!DOCTYPE html>
<html>
<head>
--- /dev/null
+Test function calls should overlap with effects of DOMJIT functions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS test() is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="target"></div>
+</div>
+
+<script>
+description('Test function calls should overlap with effects of DOMJIT functions.');
+
+function test()
+{
+ var target = document.getElementById('target');
+ target.setAttribute("cocoa", "0");
+ for (var i = 0; i < 1e4; ++i) {
+ var ret = target.getAttribute("cocoa");
+ if (ret !== String(i))
+ return false;
+ target.setAttribute("cocoa", String(i + 1));
+ var ret = target.getAttribute("cocoa");
+ if (ret === String(i))
+ return false;
+ }
+ return true;
+}
+
+shouldBeTrue(`test()`);
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+Test DOMJIT functions work.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS All tests passed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+Test DOMJIT function will be LICM-ed.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<div id="parentNode">
+<div id="previousSibling"></div><div id="target"><div id="firstChild"></div><div id="lastChild"></div></div><div id="nextSibling"></div>
+</div>
+
+<script>
+description('Test DOMJIT function will be LICM-ed.');
+
+function test() {
+ var div = document.createElement('div');
+ var ret = "invalid";
+ div.setAttribute("cocoa", "Cocoa");
+ for (var i = 0; i < 1e4; ++i)
+ ret = div.getAttribute("cocoa");
+ return ret;
+}
+var result;
+(function () {
+ for (var i = 0; i < 100; ++i) {
+ result = test();
+ shouldBe(`result`, `"Cocoa"`, true);
+ }
+}());
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+Test DOMJIT function will cause type contradiction giving up.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<div id="parentNode">
+<div id="previousSibling"></div><div id="target"><div id="firstChild"></div><div id="lastChild"></div></div><div id="nextSibling"></div>
+</div>
+
+<script>
+description('Test DOMJIT function will cause type contradiction giving up.');
+
+var div = document.createElement('div');
+div.setAttribute("cocoa", "Cocoa");
+function test(div) {
+ var ret = "invalid";
+ for (var i = 0; i < 1e4; ++i)
+ ret = div.getAttribute(200);
+ return ret;
+}
+var result;
+(function () {
+ for (var i = 0; i < 100; ++i) {
+ result = test(div);
+ shouldBe(`result`, `null`, true);
+ }
+}());
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+Test DOMJIT function will cause BadType OSR exits.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<div id="parentNode">
+<div id="previousSibling"></div><div id="target"><div id="firstChild"></div><div id="lastChild"></div></div><div id="nextSibling"></div>
+</div>
+
+<script>
+description('Test DOMJIT function will cause BadType OSR exits.');
+
+var div = document.createElement('div');
+div.setAttribute("cocoa", "Cocoa");
+function test(div, name) {
+ var ret = "invalid";
+ for (var i = 0; i < 1e4; ++i)
+ ret = div.getAttribute(name);
+ return ret;
+}
+var result;
+(function () {
+ for (var i = 0; i < 100; ++i) {
+ result = test(div, 'cocoa');
+ shouldBe(`result`, `"Cocoa"`, true);
+ }
+ for (var i = 0; i < 100; ++i) {
+ result = test(div, 400);
+ shouldBe(`result`, `null`, true);
+ }
+}());
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<div id="target" cocoa="cocoa"><div id="firstChild"></div><div id="lastChild"></div></div>
+</div>
+
+<script>
+description('Test DOMJIT functions work.');
+var div;
+(function () {
+ div = document.getElementById('target');
+
+ function a()
+ {
+ return div.getAttribute('cocoa') === 'cocoa';
+ }
+
+ function b()
+ {
+ return div.getAttributeNode('cocoa').nodeType === Node.ATTRIBUTE_NODE;
+ }
+
+ function c()
+ {
+ return div.getElementsByTagName('div').length === 2;
+ }
+
+ function d()
+ {
+ return div.hasAttribute('cocoa') === true;
+ }
+
+ function main()
+ {
+ if (!a())
+ return false;
+ if (!b())
+ return false;
+ if (!c())
+ return false;
+ if (!d())
+ return false;
+ return true;
+ }
+
+ for (var i = 0; i < 1e4; ++i) {
+ if (!main())
+ throw new Error("error");
+ }
+ testPassed("All tests passed.");
+}());
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
+2016-11-02 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [DOMJIT] Add DOMJIT::Signature
+ https://bugs.webkit.org/show_bug.cgi?id=162980
+
+ Reviewed by Saam Barati and Sam Weinig.
+
+ This patch introduces a new mechanism called DOMJIT::Signature. We can annotate the function with DOMJIT::Signature.
+ DOMJIT::Signature has type information of that function. And it also maintains the effect of the function and the
+ pointer to the unsafe function. The unsafe function means the function without type and argument count checks.
+ By using these information, we can separate type and argument count checks from the function. And we can emit
+ these things as DFG checks and convert the function call itself to CallDOM node. CallDOM node can call the unsafe
+ function directly without any checks. Furthermore, this CallDOM node can represent its own clobberizing rules based
+ on DOMJIT::Effect maintained by DOMJIT::Signature. It allows us to make opaque Call node to a CallDOM node that
+ merely reads some part of heap. These changes (1) can drop duplicate type checks in DFG, (2) offer ability to move
+ CallDOM node to somewhere, and (3) track more detailed heap reads and writes of CallDOM nodes.
+
+ We first emit Call node with DOMJIT::Signature in DFGByteCodeParser. And in the fixup phase, we attempt to lower
+ Call node to CallDOM node with checks & edge filters. This is because we do not know the type predictions in
+ DFGByteCodeParser phase. If we always emit CallDOM node in DFGByteCodeParser, if we evaluate `div.getAttribute(true)`
+ thingy, the Uncountable OSR exits repeatedly happen because AI figures out the abstract value is cleared.
+
+ Currently, DOMJIT signature only allows the types that can reside in GPR. This is because the types of the unsafe
+ function arguments are represented as the sequence of void*. In the future, we will extend to accept other types like
+ float, double etc.
+
+ We annotate several functions in Element. In particular, we annotate Element::getAttribute. This allows us to perform
+ LICM in Dromaeo dom-attr test. In the Dromaeo dom-attr getAttribute test, we can see 32x improvement. (134974.8 v.s. 4203.4)
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/CallVariant.h:
+ (JSC::CallVariant::functionExecutable):
+ (JSC::CallVariant::nativeExecutable):
+ (JSC::CallVariant::signatureFor):
+ * bytecode/SpeculatedType.h:
+ (JSC::isNotStringSpeculation):
+ (JSC::isNotInt32Speculation):
+ (JSC::isNotBooleanSpeculation):
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::addCall):
+ (JSC::DFG::ByteCodeParser::handleCall):
+ (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+ (JSC::DFG::ByteCodeParser::handleInlining):
+ (JSC::DFG::ByteCodeParser::handleDOMJITCall):
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::attemptToMakeCallDOM):
+ (JSC::DFG::FixupPhase::fixupCheckDOM):
+ (JSC::DFG::FixupPhase::fixupCallDOM):
+ * dfg/DFGNode.cpp:
+ (JSC::DFG::Node::convertToCallDOM):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasHeapPrediction):
+ (JSC::DFG::Node::shouldSpeculateNotInt32):
+ (JSC::DFG::Node::shouldSpeculateNotBoolean):
+ (JSC::DFG::Node::shouldSpeculateNotString):
+ (JSC::DFG::Node::hasSignature):
+ (JSC::DFG::Node::signature):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileCallDOM):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * domjit/DOMJITEffect.h:
+ (JSC::DOMJIT::Effect::Effect):
+ (JSC::DOMJIT::Effect::forWrite):
+ (JSC::DOMJIT::Effect::forRead):
+ (JSC::DOMJIT::Effect::forReadWrite):
+ (JSC::DOMJIT::Effect::forPure):
+ (JSC::DOMJIT::Effect::forDef):
+ (JSC::DOMJIT::Effect::mustGenerate):
+ In clang, we cannot make this Effect constructor constexpr if we use Optional<HeapRange>.
+ So we use HeapRange::top() for Nullopt def now.
+
+ * domjit/DOMJITHeapRange.h:
+ (JSC::DOMJIT::HeapRange::fromRaw):
+ (JSC::DOMJIT::HeapRange::operator bool):
+ (JSC::DOMJIT::HeapRange::operator==):
+ (JSC::DOMJIT::HeapRange::operator!=):
+ (JSC::DOMJIT::HeapRange::fromConstant):
+ * domjit/DOMJITSignature.h: Copied from Source/JavaScriptCore/domjit/DOMJITEffect.h.
+ (JSC::DOMJIT::Signature::Signature):
+ (JSC::DOMJIT::Signature::argumentCount):
+ (JSC::DOMJIT::Signature::checkDOM):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+ (JSC::FTL::DFG::LowerDFGToB3::compileCallDOM):
+ * jit/JITOperations.h:
+ * jit/JITThunks.cpp:
+ (JSC::JITThunks::hostFunctionStub):
+ * jit/JITThunks.h:
+ * runtime/JSBoundFunction.cpp:
+ (JSC::JSBoundFunction::create):
+ * runtime/JSCell.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::create):
+ * runtime/JSFunction.h:
+ * runtime/JSNativeStdFunction.cpp:
+ (JSC::JSNativeStdFunction::create):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putDirectNativeFunction):
+ * runtime/JSObject.h:
+ * runtime/Lookup.h:
+ (JSC::HashTableValue::functionLength):
+ (JSC::HashTableValue::signature):
+ (JSC::reifyStaticProperty):
+ * runtime/NativeExecutable.cpp:
+ (JSC::NativeExecutable::create):
+ (JSC::NativeExecutable::NativeExecutable):
+ * runtime/NativeExecutable.h:
+ * runtime/PropertySlot.h:
+ * runtime/VM.cpp:
+ (JSC::VM::getHostFunction):
+ * runtime/VM.h:
+
2016-11-02 Andreas Kling <akling@apple.com>
MarkedSpace should have specialized size classes for popular engine objects.
E33F50851B8437A000413856 /* JSInternalPromiseDeferred.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50831B8437A000413856 /* JSInternalPromiseDeferred.h */; settings = {ATTRIBUTES = (Private, ); }; };
E33F50871B8449EF00413856 /* JSInternalPromiseConstructor.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */; };
E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3555B8A1DAE03A500F36921 /* DOMJITCallDOMGetterPatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterPatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
E355F3521B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E355F3501B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp */; };
E33F50861B8449EF00413856 /* JSInternalPromiseConstructor.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInternalPromiseConstructor.lut.h; sourceTree = "<group>"; };
E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = InternalPromiseConstructor.js; sourceTree = "<group>"; };
E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FrameTracers.h; sourceTree = "<group>"; };
+ E35070891DC49BB60089BCD6 /* DOMJITSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITSignature.h; sourceTree = "<group>"; };
E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; };
E3555B891DAE03A200F36921 /* DOMJITCallDOMGetterPatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITCallDOMGetterPatchpoint.h; sourceTree = "<group>"; };
E355F3501B7DC85300C50DC5 /* ModuleLoaderPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleLoaderPrototype.cpp; sourceTree = "<group>"; };
E37AD83A1DA4928000F3D412 /* DOMJITPatchpointParams.h */,
E37AD83B1DA4928000F3D412 /* DOMJITReg.h */,
E3CB1E241DA7540A00FA1E56 /* DOMJITSlowPathCalls.h */,
+ E35070891DC49BB60089BCD6 /* DOMJITSignature.h */,
E3FFC8521DAD7D1000DEA53E /* DOMJITValue.h */,
);
path = domjit;
43AB26C61C1A535900D82AE6 /* B3MathExtras.h in Headers */,
AD2FCBF31DB58DAD00B3E736 /* WebAssemblyInstancePrototype.h in Headers */,
BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
+ E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */,
1A28D4A8177B71C80007FA3C /* JSStringRefPrivate.h in Headers */,
0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
70ECA6061AFDBEA200449739 /* JSTemplateRegistryKey.h in Headers */,
#include "FunctionExecutable.h"
#include "JSCell.h"
#include "JSFunction.h"
+#include "NativeExecutable.h"
namespace JSC {
return jsDynamicCast<FunctionExecutable*>(executable);
return nullptr;
}
+
+ NativeExecutable* nativeExecutable() const
+ {
+ if (ExecutableBase* executable = this->executable())
+ return jsDynamicCast<NativeExecutable*>(executable);
+ return nullptr;
+ }
+
+ const DOMJIT::Signature* signatureFor(CodeSpecializationKind kind) const
+ {
+ if (NativeExecutable* nativeExecutable = this->nativeExecutable())
+ return nativeExecutable->signatureFor(kind);
+ return nullptr;
+ }
void dump(PrintStream& out) const;
return !!value && (value & SpecString) == value;
}
+inline bool isNotStringSpeculation(SpeculatedType value)
+{
+ return value && !(value & SpecString);
+}
+
inline bool isStringOrOtherSpeculation(SpeculatedType value)
{
return !!value && (value & (SpecString | SpecOther)) == value;
return value && !(value & ~SpecInt32Only);
}
+inline bool isNotInt32Speculation(SpeculatedType value)
+{
+ return value && !(value & SpecInt32Only);
+}
+
inline bool isInt32OrBooleanSpeculation(SpeculatedType value)
{
return value && !(value & ~(SpecBoolean | SpecInt32Only));
return value == SpecBoolean;
}
+inline bool isNotBooleanSpeculation(SpeculatedType value)
+{
+ return value && !(value & SpecBoolean);
+}
+
inline bool isOtherSpeculation(SpeculatedType value)
{
return value == SpecOther;
#include "ArrayConstructor.h"
#include "DFGAbstractInterpreter.h"
#include "DOMJITGetterSetter.h"
+#include "DOMJITSignature.h"
#include "GetByIdStatus.h"
#include "GetterSetter.h"
#include "HashMapImpl.h"
forNode(node).setType(m_graph, callDOMGetterData->domJIT->resultType());
break;
}
+ case CallDOM: {
+ const DOMJIT::Signature* signature = node->signature();
+ if (signature->effect.writes)
+ clobberWorld(node->origin.semantic, clobberLimit);
+ forNode(node).setType(m_graph, signature->result);
+ break;
+ }
case CheckArray: {
if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
m_state.setFoundConstants(true);
template<typename ChecksFunctor>
bool handleIntrinsicCall(Node* callee, int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
template<typename ChecksFunctor>
+ bool handleDOMJITCall(Node* callee, int resultOperand, const DOMJIT::Signature*, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks);
+ template<typename ChecksFunctor>
bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant& intrinsicVariant, Node* thisNode, const ChecksFunctor& insertChecks);
template<typename ChecksFunctor>
bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor& insertChecks);
}
Node* addCall(
- int result, NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset,
+ int result, NodeType op, const DOMJIT::Signature* signature, Node* callee, int argCount, int registerOffset,
SpeculatedType prediction)
{
if (op == TailCall) {
if (allInlineFramesAreTailCalls())
- return addCallWithoutSettingResult(op, OpInfo(), callee, argCount, registerOffset, OpInfo());
+ return addCallWithoutSettingResult(op, OpInfo(signature), callee, argCount, registerOffset, OpInfo());
op = TailCallInlinedCaller;
}
Node* call = addCallWithoutSettingResult(
- op, opInfo, callee, argCount, registerOffset, OpInfo(prediction));
+ op, OpInfo(signature), callee, argCount, registerOffset, OpInfo(prediction));
VirtualRegister resultReg(result);
if (resultReg.isValid())
set(resultReg, call);
// Oddly, this conflates calls that haven't executed with calls that behaved sufficiently polymorphically
// that we cannot optimize them.
- Node* callNode = addCall(result, op, OpInfo(), callTarget, argumentCountIncludingThis, registerOffset, prediction);
+ Node* callNode = addCall(result, op, nullptr, callTarget, argumentCountIncludingThis, registerOffset, prediction);
if (callNode->op() == TailCall)
return Terminal;
ASSERT(callNode->op() != TailCallVarargs && callNode->op() != TailCallForwardVarargs);
return NonTerminal;
}
- Node* callNode = addCall(result, op, OpInfo(), callTarget, argumentCountIncludingThis, registerOffset, prediction);
+ Node* callNode = addCall(result, op, nullptr, callTarget, argumentCountIncludingThis, registerOffset, prediction);
if (callNode->op() == TailCall)
return Terminal;
ASSERT(callNode->op() != TailCallVarargs && callNode->op() != TailCallForwardVarargs);
RELEASE_ASSERT(!didInsertChecks);
// We might still try to inline the Intrinsic because it might be a builtin JS function.
}
+
+ if (Options::useDOMJIT()) {
+ if (const DOMJIT::Signature* signature = callee.signatureFor(specializationKind)) {
+ if (handleDOMJITCall(callTargetNode, resultOperand, signature, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
+ RELEASE_ASSERT(didInsertChecks);
+ addToGraph(Phantom, callTargetNode);
+ emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
+ inliningBalance--;
+ return true;
+ }
+ RELEASE_ASSERT(!didInsertChecks);
+ }
+ }
}
unsigned myInliningCost = inliningCost(callee, argumentCountIncludingThis, InlineCallFrame::callModeFor(kind));
Node* myCallTargetNode = getDirect(calleeReg);
if (couldTakeSlowPath) {
addCall(
- resultOperand, callOp, OpInfo(), myCallTargetNode, argumentCountIncludingThis,
+ resultOperand, callOp, nullptr, myCallTargetNode, argumentCountIncludingThis,
registerOffset, prediction);
} else {
addToGraph(CheckBadCell);
}
template<typename ChecksFunctor>
+bool ByteCodeParser::handleDOMJITCall(Node* callTarget, int resultOperand, const DOMJIT::Signature* signature, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor& insertChecks)
+{
+ if (argumentCountIncludingThis != static_cast<int>(1 + signature->argumentCount))
+ return false;
+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
+ return false;
+
+ // FIXME: Currently, we only support functions which arguments are up to 2.
+ // Eventually, we should extend this. But possibly, 2 or 3 can cover typical use cases.
+ // https://bugs.webkit.org/show_bug.cgi?id=164346
+ ASSERT_WITH_MESSAGE(argumentCountIncludingThis <= JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS, "Currently CallDOM does not support an arbitrary length arguments.");
+
+ insertChecks();
+ addCall(resultOperand, Call, signature, callTarget, argumentCountIncludingThis, registerOffset, prediction);
+ return true;
+}
+
+
+template<typename ChecksFunctor>
bool ByteCodeParser::handleIntrinsicGetter(int resultOperand, const GetByIdVariant& variant, Node* thisNode, const ChecksFunctor& insertChecks)
{
switch (variant.intrinsic()) {
int callee = currentInstruction[2].u.operand;
int argumentCountIncludingThis = currentInstruction[3].u.operand;
int registerOffset = -currentInstruction[4].u.operand;
- addCall(result, CallEval, OpInfo(), get(VirtualRegister(callee)), argumentCountIncludingThis, registerOffset, getPrediction());
+ addCall(result, CallEval, nullptr, get(VirtualRegister(callee)), argumentCountIncludingThis, registerOffset, getPrediction());
NEXT_OPCODE(op_call_eval);
}
#include "DFGLazyNode.h"
#include "DFGPureValue.h"
#include "DOMJITCallDOMGetterPatchpoint.h"
+#include "DOMJITSignature.h"
namespace JSC { namespace DFG {
else
write(AbstractHeap(DOMState, effect.writes.rawRepresentation()));
}
- if (effect.def) {
- DOMJIT::HeapRange range = effect.def.value();
+ if (effect.def != DOMJIT::HeapRange::top()) {
+ DOMJIT::HeapRange range = effect.def;
if (range == DOMJIT::HeapRange::none())
def(PureValue(node, node->callDOMGetterData()->domJIT));
else {
// Def with heap location. We do not include "GlobalObject" for that since this information is included in the base node.
- // FIXME: When supporting the other nodes like getElementById("string"), we should include the base and the id string.
- // Currently, we only see the DOMJIT getter here. So just including "base" is ok.
+ // We only see the DOMJIT getter here. So just including "base" is ok.
def(HeapLocation(DOMStateLoc, AbstractHeap(DOMState, range.rawRepresentation()), node->child1()), LazyNode(node));
}
}
return;
}
+ case CallDOM: {
+ const DOMJIT::Signature* signature = node->signature();
+ DOMJIT::Effect effect = signature->effect;
+ if (effect.reads) {
+ if (effect.reads == DOMJIT::HeapRange::top())
+ read(World);
+ else
+ read(AbstractHeap(DOMState, effect.reads.rawRepresentation()));
+ }
+ if (effect.writes) {
+ if (effect.writes == DOMJIT::HeapRange::top())
+ write(Heap);
+ else
+ write(AbstractHeap(DOMState, effect.writes.rawRepresentation()));
+ }
+ ASSERT_WITH_MESSAGE(effect.def == DOMJIT::HeapRange::top(), "Currently, we do not accept any def for CallDOM.");
+ return;
+ }
+
case Arrayify:
case ArrayifyToStructure:
read(JSCell_structureID);
case CreateRest:
case ToLowerCase:
case CallDOMGetter:
+ case CallDOM:
return true;
case MultiPutByOffset:
break;
}
- case CheckDOM:
- fixEdge<CellUse>(node->child1());
+ case CheckDOM: {
+ fixupCheckDOM(node);
break;
+ }
case CallDOMGetter: {
DOMJIT::CallDOMGetterPatchpoint* patchpoint = node->callDOMGetterData()->patchpoint;
break;
}
+ case CallDOM: {
+ fixupCallDOM(node);
+ break;
+ }
+
+ case Call: {
+ attemptToMakeCallDOM(node);
+ break;
+ }
+
#if !ASSERT_DISABLED
// Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
case SetArgument:
case GetGlobalVar:
case GetGlobalLexicalVariable:
case NotifyWrite:
- case Call:
case DirectCall:
case CheckTypeInfoFlags:
case TailCallInlinedCaller:
OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
}
+ bool attemptToMakeCallDOM(Node* node)
+ {
+ if (m_graph.hasExitSite(node->origin.semantic, BadType))
+ return false;
+
+ const DOMJIT::Signature* signature = node->signature();
+ if (!signature)
+ return false;
+
+ {
+ unsigned index = 0;
+ bool shouldConvertToCallDOM = true;
+ m_graph.doToChildren(node, [&](Edge& edge) {
+ // Callee. Ignore this. DFGByteCodeParser already emit appropriate checks.
+ if (!index)
+ return;
+
+ if (index == 1) {
+ // DOM node case.
+ if (edge->shouldSpeculateNotCell())
+ shouldConvertToCallDOM = false;
+ } else {
+ switch (signature->arguments[index - 2]) {
+ case SpecString:
+ if (edge->shouldSpeculateNotString())
+ shouldConvertToCallDOM = false;
+ break;
+ case SpecInt32Only:
+ if (edge->shouldSpeculateNotInt32())
+ shouldConvertToCallDOM = false;
+ break;
+ case SpecBoolean:
+ if (edge->shouldSpeculateNotBoolean())
+ shouldConvertToCallDOM = false;
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+ ++index;
+ });
+ if (!shouldConvertToCallDOM)
+ return false;
+ }
+
+ Node* thisNode = m_graph.varArgChild(node, 1).node();
+ Ref<DOMJIT::Patchpoint> checkDOMPatchpoint = signature->checkDOM();
+ m_graph.m_domJITPatchpoints.append(checkDOMPatchpoint.ptr());
+ Node* checkDOM = m_insertionSet.insertNode(m_indexInBlock, SpecNone, CheckDOM, node->origin, OpInfo(checkDOMPatchpoint.ptr()), OpInfo(signature->classInfo), Edge(thisNode));
+ node->convertToCallDOM(m_graph);
+ fixupCheckDOM(checkDOM);
+ fixupCallDOM(node);
+ return true;
+ }
+
+ void fixupCheckDOM(Node* node)
+ {
+ fixEdge<CellUse>(node->child1());
+ }
+
+ void fixupCallDOM(Node* node)
+ {
+ const DOMJIT::Signature* signature = node->signature();
+ auto fixup = [&](Edge& edge, unsigned argumentIndex) {
+ if (!edge)
+ return;
+ switch (signature->arguments[argumentIndex]) {
+ case SpecString:
+ fixEdge<StringUse>(edge);
+ break;
+ case SpecInt32Only:
+ fixEdge<Int32Use>(edge);
+ break;
+ case SpecBoolean:
+ fixEdge<BooleanUse>(edge);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ };
+ fixEdge<CellUse>(node->child1()); // DOM.
+ fixup(node->child2(), 0);
+ fixup(node->child3(), 1);
+ }
+
void fixupChecksInBlock(BasicBlock* block)
{
if (!block)
m_opInfo = executable;
}
+void Node::convertToCallDOM(Graph& graph)
+{
+ ASSERT(op() == Call);
+ ASSERT(signature());
+
+ Edge edges[3];
+ // Skip the first one. This is callee.
+ RELEASE_ASSERT(numChildren() <= 4);
+ for (unsigned i = 1; i < numChildren(); ++i)
+ edges[i - 1] = graph.varArgChild(this, i);
+
+ setOpAndDefaultFlags(CallDOM);
+ children.setChild1(edges[0]);
+ children.setChild2(edges[1]);
+ children.setChild3(edges[2]);
+
+ if (!signature()->effect.mustGenerate())
+ clearFlags(NodeMustGenerate);
+}
+
String Node::tryGetString(Graph& graph)
{
if (hasConstant())
class GetterSetter;
class Patchpoint;
class CallDOMGetterPatchpoint;
+class Signature;
}
namespace Profiler {
}
void convertToDirectCall(FrozenValue*);
+
+ void convertToCallDOM(Graph&);
JSValue asJSValue()
{
case ToNumber:
case LoadFromJSMapBucket:
case CallDOMGetter:
+ case CallDOM:
return true;
default:
return false;
{
return isInt32Speculation(prediction());
}
+
+ bool shouldSpeculateNotInt32()
+ {
+ return isNotInt32Speculation(prediction());
+ }
bool sawBooleans()
{
{
return isBooleanSpeculation(prediction());
}
+
+ bool shouldSpeculateNotBoolean()
+ {
+ return isNotBooleanSpeculation(prediction());
+ }
bool shouldSpeculateOther()
{
{
return isStringSpeculation(prediction());
}
+
+ bool shouldSpeculateNotString()
+ {
+ return isNotStringSpeculation(prediction());
+ }
bool shouldSpeculateStringOrOther()
{
return m_opInfo2.as<const ClassInfo*>();
}
+ bool hasSignature() const
+ {
+ // Note that this does not include TailCall node types intentionally.
+ // CallDOM node types are always converted from Call.
+ return op() == Call || op() == CallDOM;
+ }
+
+ const DOMJIT::Signature* signature()
+ {
+ return m_opInfo.as<const DOMJIT::Signature*>();
+ }
+
Node* replacement() const
{
return m_misc.replacement;
/* Nodes for DOM JIT */\
macro(CheckDOM, NodeMustGenerate) \
macro(CallDOMGetter, NodeResultJS | NodeMustGenerate) \
+ macro(CallDOM, NodeResultJS | NodeMustGenerate) \
// This enum generates a monotonically increasing id for all Node types,
// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
case GetRegExpObjectLastIndex:
case SetRegExpObjectLastIndex:
case RecordRegExpCachedResult:
- case LazyJSConstant: {
+ case LazyJSConstant:
+ case CallDOM: {
// This node should never be visible at this stage of compilation. It is
// inserted by fixup(), which follows this phase.
DFG_CRASH(m_graph, m_currentNode, "Unexpected node during prediction propagation");
case GetExecutable:
case GetButterfly:
case CallDOMGetter:
+ case CallDOM:
case CheckDOM:
case CheckArray:
case Arrayify:
}
}
+void SpeculativeJIT::compileCallDOM(Node* node)
+{
+ const DOMJIT::Signature* signature = node->signature();
+
+ // FIXME: We should have a way to call functions with the vector of registers.
+ // https://bugs.webkit.org/show_bug.cgi?id=163099
+ Vector<Variant<SpeculateCellOperand, SpeculateInt32Operand, SpeculateBooleanOperand>, JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS> operands;
+ Vector<GPRReg, JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS> regs;
+
+ auto appendCell = [&](Edge& edge) {
+ SpeculateCellOperand operand(this, edge);
+ regs.append(operand.gpr());
+ operands.append(WTFMove(operand));
+ };
+
+ auto appendString = [&](Edge& edge) {
+ SpeculateCellOperand operand(this, edge);
+ GPRReg gpr = operand.gpr();
+ regs.append(gpr);
+ speculateString(edge, gpr);
+ operands.append(WTFMove(operand));
+ };
+
+ auto appendInt32 = [&](Edge& edge) {
+ SpeculateInt32Operand operand(this, edge);
+ regs.append(operand.gpr());
+ operands.append(WTFMove(operand));
+ };
+
+ auto appendBoolean = [&](Edge& edge) {
+ SpeculateBooleanOperand operand(this, edge);
+ regs.append(operand.gpr());
+ operands.append(WTFMove(operand));
+ };
+
+ unsigned index = 0;
+ m_jit.graph().doToChildren(node, [&](Edge edge) {
+ if (!index)
+ appendCell(edge);
+ else {
+ switch (signature->arguments[index - 1]) {
+ case SpecString:
+ appendString(edge);
+ break;
+ case SpecInt32Only:
+ appendInt32(edge);
+ break;
+ case SpecBoolean:
+ appendBoolean(edge);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+ ++index;
+ });
+
+ JSValueRegsTemporary result(this);
+ JSValueRegs resultRegs = result.regs();
+
+ flushRegisters();
+ unsigned argumentCountIncludingThis = signature->argumentCount + 1;
+ switch (argumentCountIncludingThis) {
+ case 1:
+ callOperation(reinterpret_cast<J_JITOperation_EP>(signature->unsafeFunction), extractResult(resultRegs), regs[0]);
+ break;
+ case 2:
+ callOperation(reinterpret_cast<J_JITOperation_EPP>(signature->unsafeFunction), extractResult(resultRegs), regs[0], regs[1]);
+ break;
+ case 3:
+ callOperation(reinterpret_cast<J_JITOperation_EPPP>(signature->unsafeFunction), extractResult(resultRegs), regs[0], regs[1], regs[2]);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ m_jit.exceptionCheck();
+ jsValueResult(resultRegs, node);
+}
+
void SpeculativeJIT::compileCallDOMGetter(Node* node)
{
DOMJIT::CallDOMGetterPatchpoint* patchpoint = node->callDOMGetterData()->patchpoint;
m_jit.setupArgumentsWithExecState(arg1, arg2);
return appendCallSetResult(operation, result);
}
+ JITCompiler::Call callOperation(J_JITOperation_EPPP operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallSetResult(operation, result);
+ }
JITCompiler::Call callOperation(J_JITOperation_EGP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
{
m_jit.setupArgumentsWithExecState(arg1, arg2);
m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
}
+ JITCompiler::Call callOperation(J_JITOperation_EPP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2);
+ return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+ }
+ JITCompiler::Call callOperation(J_JITOperation_EPPP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
+ {
+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
+ return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
+ }
JITCompiler::Call callOperation(J_JITOperation_EGP operation, JSValueRegs result, GPRReg arg1, GPRReg arg2)
{
m_jit.setupArgumentsWithExecState(arg1, arg2);
void compileReallocatePropertyStorage(Node*);
void compileGetButterfly(Node*);
void compileCallDOMGetter(Node*);
+ void compileCallDOM(Node*);
void compileCheckDOM(Node*);
#if USE(JSVALUE32_64)
break;
}
+ case CallDOM:
+ compileCallDOM(node);
+ break;
+
case CallDOMGetter:
compileCallDOMGetter(node);
break;
compileMaterializeNewObject(node);
break;
+ case CallDOM:
+ compileCallDOM(node);
+ break;
+
case CallDOMGetter:
compileCallDOMGetter(node);
break;
#include "DOMJITHeapRange.h"
#include <wtf/Optional.h>
-#if ENABLE(JIT)
-
namespace JSC { namespace DOMJIT {
-struct Effect {
+class Effect {
+public:
HeapRange reads { HeapRange::top() };
HeapRange writes { HeapRange::top() };
- Optional<HeapRange> def;
+ HeapRange def { HeapRange::top() };
+
+ constexpr Effect() = default;
+ constexpr Effect(HeapRange reads, HeapRange writes)
+ : reads(reads)
+ , writes(writes)
+ {
+ }
+
+ constexpr Effect(HeapRange reads, HeapRange writes, HeapRange def)
+ : reads(reads)
+ , writes(writes)
+ , def(def)
+ {
+ }
- static Effect forReadWrite(HeapRange readRange, HeapRange writeRange)
+ constexpr static Effect forWrite(HeapRange writeRange)
{
- Effect effect;
- effect.reads = readRange;
- effect.writes = writeRange;
- return effect;
+ return Effect(HeapRange::none(), writeRange);
}
- static Effect forPure()
+ constexpr static Effect forRead(HeapRange readRange)
{
- Effect effect;
- effect.reads = HeapRange::none();
- effect.writes = HeapRange::none();
- effect.def = HeapRange::none();
- return effect;
+ return Effect(readRange, HeapRange::none());
}
- static Effect forDef(HeapRange def)
+ constexpr static Effect forReadWrite(HeapRange readRange, HeapRange writeRange)
{
- Effect effect;
- effect.reads = def;
- effect.writes = HeapRange::none();
- effect.def = def;
- return effect;
+ return Effect(readRange, writeRange);
}
- static Effect forDef(HeapRange def, HeapRange readRange, HeapRange writeRange)
+ constexpr static Effect forPure()
{
- Effect effect;
- effect.reads = readRange;
- effect.writes = writeRange;
- effect.def = def;
- return effect;
+ return Effect(HeapRange::none(), HeapRange::none(), HeapRange::none());
}
- bool mustGenerate() const
+ constexpr static Effect forDef(HeapRange def)
+ {
+ return Effect(def, HeapRange::none(), def);
+ }
+
+ constexpr static Effect forDef(HeapRange def, HeapRange readRange, HeapRange writeRange)
+ {
+ return Effect(readRange, writeRange, def);
+ }
+
+ constexpr bool mustGenerate() const
{
return !!writes;
}
};
} }
-
-#endif
#include <wtf/MathExtras.h>
#include <wtf/PrintStream.h>
-#if ENABLE(JIT)
-
namespace JSC { namespace DOMJIT {
class HeapRange {
ASSERT_WITH_MESSAGE(begin <= end, "begin <= end is the invariant of this HeapRange.");
}
-private:
enum ConstExprTag { ConstExpr };
constexpr HeapRange(ConstExprTag, uint16_t begin, uint16_t end)
: m_begin(begin)
{
}
- template<uint16_t begin, uint16_t end>
- static constexpr HeapRange fromConstant()
- {
- static_assert(begin <= end, "begin <= end is the invariant of this HeapRange.");
- return HeapRange(ConstExpr, begin, end);
- }
-
-public:
enum RawRepresentationTag { RawRepresentation };
explicit constexpr HeapRange(RawRepresentationTag, uint32_t value)
: m_raw(value)
{
}
- static HeapRange fromRaw(uint32_t value)
+ constexpr static HeapRange fromRaw(uint32_t value)
{
return HeapRange(RawRepresentation, value);
}
uint16_t end() const { return m_end; }
uint32_t rawRepresentation() { return m_raw; }
- explicit operator bool() const
+ constexpr explicit operator bool() const
{
return m_begin != m_end;
}
- bool operator==(const HeapRange& other) const
+ constexpr bool operator==(const HeapRange& other) const
{
return m_begin == other.m_begin && m_end == other.m_end;
}
+ constexpr bool operator!=(const HeapRange& other) const
+ {
+ return !operator==(other);
+ }
+
+ template<uint16_t begin, uint16_t end>
+ static constexpr HeapRange fromConstant()
+ {
+ static_assert(begin < end || (begin == UINT16_MAX && end == UINT16_MAX), "begin < end or the both are UINT16_MAX is the invariant of this HeapRange.");
+ return HeapRange(ConstExpr, begin, end);
+ }
+
static constexpr HeapRange top() { return fromConstant<0, UINT16_MAX>(); }
static constexpr HeapRange none() { return fromConstant<UINT16_MAX, UINT16_MAX>(); } // Empty range.
};
} }
-
-#endif
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ClassInfo.h"
+#include "DOMJITEffect.h"
+#include "SpeculatedType.h"
+
+namespace JSC { namespace DOMJIT {
+
+// FIXME: Currently, we only support functions which arguments are up to 2.
+// Eventually, we should extend this. But possibly, 2 or 3 can cover typical use cases.
+// https://bugs.webkit.org/show_bug.cgi?id=164346
+#define JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS 2
+#define JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS (1 + JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS)
+
+class Patchpoint;
+
+typedef Ref<Patchpoint> CheckDOMGeneratorFunction(void);
+
+class Signature {
+public:
+ template<typename... Arguments>
+ constexpr Signature(uintptr_t unsafeFunction, CheckDOMGeneratorFunction* checkDOMGeneratorFunction, const ClassInfo* classInfo, Effect effect, SpeculatedType result, Arguments... arguments)
+ : unsafeFunction(unsafeFunction)
+ , checkDOMGeneratorFunction(checkDOMGeneratorFunction)
+ , classInfo(classInfo)
+ , effect(effect)
+ , result(result)
+ , arguments {static_cast<SpeculatedType>(arguments)...}
+ , argumentCount(sizeof...(Arguments))
+ {
+ }
+
+ Ref<Patchpoint> checkDOM() const
+ {
+ return checkDOMGeneratorFunction();
+ }
+
+ uintptr_t unsafeFunction;
+ CheckDOMGeneratorFunction* checkDOMGeneratorFunction;
+ const ClassInfo* const classInfo;
+ const Effect effect;
+ const SpeculatedType result;
+ const SpeculatedType arguments[JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS];
+ const unsigned argumentCount;
+};
+
+} }
case DefineAccessorProperty:
case ToLowerCase:
case CheckDOM:
+ case CallDOM:
case CallDOMGetter:
// These are OK.
break;
case CheckDOM:
compileCheckDOM();
break;
+ case CallDOM:
+ compileCallDOM();
+ break;
case CallDOMGetter:
compileCallDOMGetter();
break;
patchpoint->effects = Effects::forCheck();
}
+ void compileCallDOM()
+ {
+ const DOMJIT::Signature* signature = m_node->signature();
+
+ // FIXME: We should have a way to call functions with the vector of registers.
+ // https://bugs.webkit.org/show_bug.cgi?id=163099
+ Vector<LValue, JSC_DOMJIT_SIGNATURE_MAX_ARGUMENTS_INCLUDING_THIS> operands;
+
+ unsigned index = 0;
+ DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, [&](Node*, Edge edge) {
+ if (!index)
+ operands.append(lowCell(edge));
+ else {
+ switch (signature->arguments[index - 1]) {
+ case SpecString:
+ operands.append(lowString(edge));
+ break;
+ case SpecInt32Only:
+ operands.append(lowInt32(edge));
+ break;
+ case SpecBoolean:
+ operands.append(lowBoolean(edge));
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+ }
+ ++index;
+ });
+
+ unsigned argumentCountIncludingThis = signature->argumentCount + 1;
+ LValue result;
+ switch (argumentCountIncludingThis) {
+ case 1:
+ result = vmCall(Int64, m_out.operation(reinterpret_cast<J_JITOperation_EP>(signature->unsafeFunction)), m_callFrame, operands[0]);
+ break;
+ case 2:
+ result = vmCall(Int64, m_out.operation(reinterpret_cast<J_JITOperation_EPP>(signature->unsafeFunction)), m_callFrame, operands[0], operands[1]);
+ break;
+ case 3:
+ result = vmCall(Int64, m_out.operation(reinterpret_cast<J_JITOperation_EPPP>(signature->unsafeFunction)), m_callFrame, operands[0], operands[1], operands[2]);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ break;
+ }
+
+ setJSValue(result);
+ }
+
void compileCallDOMGetter()
{
DOMJIT::CallDOMGetterPatchpoint* domJIT = m_node->callDOMGetterData()->patchpoint;
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EGP)(ExecState*, JSGlobalObject*, void*);
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EP)(ExecState*, void*);
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EPP)(ExecState*, void*, void*);
+typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EPPP)(ExecState*, void*, void*, void*);
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EPS)(ExecState*, void*, size_t);
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EPc)(ExecState*, Instruction*);
typedef EncodedJSValue (JIT_OPERATION *J_JITOperation_EJscC)(ExecState*, JSScope*, JSCell*);
NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor, const String& name)
{
- return hostFunctionStub(vm, function, constructor, nullptr, NoIntrinsic, name);
+ return hostFunctionStub(vm, function, constructor, nullptr, NoIntrinsic, nullptr, name);
}
-NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor, ThunkGenerator generator, Intrinsic intrinsic, const String& name)
+NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, NativeFunction constructor, ThunkGenerator generator, Intrinsic intrinsic, const DOMJIT::Signature* signature, const String& name)
{
ASSERT(!isCompilationThread());
ASSERT(vm->canUseJIT());
RefPtr<JITCode> forConstruct = adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct(vm)), JITCode::HostCallThunk));
- NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall, function, forConstruct, constructor, intrinsic, name);
+ NativeExecutable* nativeExecutable = NativeExecutable::create(*vm, forCall, function, forConstruct, constructor, intrinsic, signature, name);
weakAdd(*m_hostFunctionStubMap, std::make_tuple(function, constructor, name), Weak<NativeExecutable>(nativeExecutable, this));
return nativeExecutable;
}
NativeExecutable* JITThunks::hostFunctionStub(VM* vm, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic, const String& name)
{
- return hostFunctionStub(vm, function, callHostFunctionAsConstructor, generator, intrinsic, name);
+ return hostFunctionStub(vm, function, callHostFunctionAsConstructor, generator, intrinsic, nullptr, name);
}
void JITThunks::clearHostFunctionStubs()
#include <wtf/text/StringHash.h>
namespace JSC {
+namespace DOMJIT {
+class Signature;
+}
class VM;
class NativeExecutable;
MacroAssemblerCodeRef ctiStub(VM*, ThunkGenerator);
NativeExecutable* hostFunctionStub(VM*, NativeFunction, NativeFunction constructor, const String& name);
- NativeExecutable* hostFunctionStub(VM*, NativeFunction, NativeFunction constructor, ThunkGenerator, Intrinsic, const String& name);
+ NativeExecutable* hostFunctionStub(VM*, NativeFunction, NativeFunction constructor, ThunkGenerator, Intrinsic, const DOMJIT::Signature*, const String& name);
NativeExecutable* hostFunctionStub(VM*, NativeFunction, ThunkGenerator, Intrinsic, const String& name);
void clearHostFunctionStubs();
NativeExecutable* executable = vm.getHostFunction(
slowCase ? boundFunctionCall : boundThisNoArgsFunctionCall,
slowCase ? NoIntrinsic : BoundThisNoArgsFunctionCallIntrinsic,
- canConstruct ? (slowCase ? boundFunctionConstruct : boundThisNoArgsFunctionConstruct) : callHostFunctionAsConstructor,
+ canConstruct ? (slowCase ? boundFunctionConstruct : boundThisNoArgsFunctionConstruct) : callHostFunctionAsConstructor, nullptr,
name);
Structure* structure = getBoundFunctionStructure(vm, exec, globalObject, targetFunction);
RETURN_IF_EXCEPTION(scope, nullptr);
template<typename T> void* allocateCell(Heap&, GCDeferralContext*);
template<typename T> void* allocateCell(Heap&, GCDeferralContext*, size_t);
-#define DECLARE_EXPORT_INFO \
- protected: \
- static JS_EXPORTDATA const ::JSC::ClassInfo s_info; \
- public: \
- static const ::JSC::ClassInfo* info() { return &s_info; }
-
-#define DECLARE_INFO \
- protected: \
- static const ::JSC::ClassInfo s_info; \
- public: \
- static const ::JSC::ClassInfo* info() { return &s_info; }
+#define DECLARE_EXPORT_INFO \
+ protected: \
+ static JS_EXPORTDATA const ::JSC::ClassInfo s_info; \
+ public: \
+ static constexpr const ::JSC::ClassInfo* info() { return &s_info; }
+
+#define DECLARE_INFO \
+ protected: \
+ static const ::JSC::ClassInfo s_info; \
+ public: \
+ static constexpr const ::JSC::ClassInfo* info() { return &s_info; }
class JSCell : public HeapCell {
friend class JSValue;
}
#endif
-JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
+JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor, const DOMJIT::Signature* signature)
{
- NativeExecutable* executable = vm.getHostFunction(nativeFunction, intrinsic, nativeConstructor, name);
+ NativeExecutable* executable = vm.getHostFunction(nativeFunction, intrinsic, nativeConstructor, signature, name);
JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, globalObject, globalObject->functionStructure());
// Can't do this during initialization because getHostFunction might do a GC allocation.
function->finishCreation(vm, executable, length, name);
class JITCompiler;
}
+namespace DOMJIT {
+class Signature;
+}
+
+
JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
JS_EXPORT_PRIVATE String getCalculatedDisplayName(VM&, JSObject*);
return sizeof(JSFunction);
}
- JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
+ JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor, const DOMJIT::Signature* = nullptr);
static JSFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*);
JSNativeStdFunction* JSNativeStdFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeStdFunction&& nativeStdFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
- NativeExecutable* executable = vm.getHostFunction(runStdFunction, intrinsic, nativeConstructor, name);
+ NativeExecutable* executable = vm.getHostFunction(runStdFunction, intrinsic, nativeConstructor, nullptr, name);
NativeStdFunctionCell* functionCell = NativeStdFunctionCell::create(vm, WTFMove(nativeStdFunction));
Structure* structure = globalObject->nativeStdFunctionStructure();
JSNativeStdFunction* function = new (NotNull, allocateCell<JSNativeStdFunction>(vm.heap)) JSNativeStdFunction(vm, globalObject, structure);
return putDirect(vm, propertyName, function, attributes);
}
+bool JSObject::putDirectNativeFunction(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, unsigned functionLength, NativeFunction nativeFunction, Intrinsic intrinsic, const DOMJIT::Signature* signature, unsigned attributes)
+{
+ StringImpl* name = propertyName.publicName();
+ if (!name)
+ name = vm.propertyNames->anonymous.impl();
+ ASSERT(name);
+
+ JSFunction* function = JSFunction::create(vm, globalObject, functionLength, name, nativeFunction, intrinsic, callHostFunctionAsConstructor, signature);
+ return putDirect(vm, propertyName, function, attributes);
+}
+
JSFunction* JSObject::putDirectBuiltinFunction(VM& vm, JSGlobalObject* globalObject, const PropertyName& propertyName, FunctionExecutable* functionExecutable, unsigned attributes)
{
StringImpl* name = propertyName.publicName();
#include <wtf/StdLibExtras.h>
namespace JSC {
+namespace DOMJIT {
+class Signature;
+}
inline JSCell* getJSFunction(JSValue value)
{
JS_EXPORT_PRIVATE bool putDirectNativeIntrinsicGetter(VM&, JSGlobalObject*, Identifier, NativeFunction, Intrinsic, unsigned attributes);
JS_EXPORT_PRIVATE bool putDirectNativeFunction(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
+ JS_EXPORT_PRIVATE bool putDirectNativeFunction(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, const DOMJIT::Signature*, unsigned attributes);
JS_EXPORT_PRIVATE JSFunction* putDirectBuiltinFunction(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
JSFunction* putDirectBuiltinFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, FunctionExecutable*, unsigned attributes);
JS_EXPORT_PRIVATE void putDirectNativeFunctionWithoutTransition(VM&, JSGlobalObject*, const PropertyName&, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
#include "CallFrame.h"
#include "CustomGetterSetter.h"
#include "DOMJITGetterSetter.h"
+#include "DOMJITSignature.h"
#include "Identifier.h"
#include "IdentifierInlines.h"
#include "Intrinsic.h"
Intrinsic intrinsic() const { ASSERT(m_attributes & Function); return m_intrinsic; }
BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return reinterpret_cast<BuiltinGenerator>(m_values.value1); }
NativeFunction function() const { ASSERT(m_attributes & Function); return reinterpret_cast<NativeFunction>(m_values.value1); }
- unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_values.value2); }
+ unsigned char functionLength() const
+ {
+ ASSERT(m_attributes & Function);
+ if (m_attributes & DOMJITFunction)
+ return signature()->argumentCount;
+ return static_cast<unsigned char>(m_values.value2);
+ }
GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrAccessorOrLazyPropertyOrConstant)); return reinterpret_cast<GetFunction>(m_values.value1); }
PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrAccessorOrLazyPropertyOrConstant)); return reinterpret_cast<PutFunction>(m_values.value2); }
DOMJIT::GetterSetter* domJIT() const { ASSERT(m_attributes & DOMJITAttribute); return reinterpret_cast<DOMJITGetterSetterGenerator>(m_values.value1)(); }
+ const DOMJIT::Signature* signature() const { ASSERT(m_attributes & DOMJITFunction); return reinterpret_cast<const DOMJIT::Signature*>(m_values.value2); }
NativeFunction accessorGetter() const { ASSERT(m_attributes & Accessor); return reinterpret_cast<NativeFunction>(m_values.value1); }
NativeFunction accessorSetter() const { ASSERT(m_attributes & Accessor); return reinterpret_cast<NativeFunction>(m_values.value2); }
}
if (value.attributes() & Function) {
+ if (value.attributes() & DOMJITFunction) {
+ thisObj.putDirectNativeFunction(
+ vm, thisObj.globalObject(), propertyName, value.functionLength(),
+ value.function(), value.intrinsic(), value.signature(), attributesForStructure(value.attributes()));
+ return;
+ }
thisObj.putDirectNativeFunction(
vm, thisObj.globalObject(), propertyName, value.functionLength(),
value.function(), value.intrinsic(), attributesForStructure(value.attributes()));
const ClassInfo NativeExecutable::s_info = { "NativeExecutable", &ExecutableBase::s_info, 0, CREATE_METHOD_TABLE(NativeExecutable) };
-NativeExecutable* NativeExecutable::create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic, const String& name)
+NativeExecutable* NativeExecutable::create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature, const String& name)
{
NativeExecutable* executable;
- executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor, intrinsic);
+ executable = new (NotNull, allocateCell<NativeExecutable>(vm.heap)) NativeExecutable(vm, function, constructor, intrinsic, signature);
executable->finishCreation(vm, callThunk, constructThunk, name);
return executable;
}
m_name = name;
}
-NativeExecutable::NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor, Intrinsic intrinsic)
+NativeExecutable::NativeExecutable(VM& vm, NativeFunction function, NativeFunction constructor, Intrinsic intrinsic, const DOMJIT::Signature* signature)
: ExecutableBase(vm, vm.nativeExecutableStructure.get(), NUM_PARAMETERS_IS_HOST, intrinsic)
, m_function(function)
, m_constructor(constructor)
+ , m_signature(signature)
{
}
#include "ExecutableBase.h"
namespace JSC {
+namespace DOMJIT {
+class Signature;
+}
class NativeExecutable final : public ExecutableBase {
friend class JIT;
typedef ExecutableBase Base;
static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
- static NativeExecutable* create(VM& vm, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic intrinsic, const String& name);
+ static NativeExecutable* create(VM&, PassRefPtr<JITCode> callThunk, NativeFunction function, PassRefPtr<JITCode> constructThunk, NativeFunction constructor, Intrinsic, const DOMJIT::Signature*, const String& name);
static void destroy(JSCell*);
DECLARE_INFO;
const String& name() const { return m_name; }
+ const DOMJIT::Signature* signature() const { return m_signature; }
+
+ const DOMJIT::Signature* signatureFor(CodeSpecializationKind kind) const
+ {
+ if (isCall(kind))
+ return signature();
+ return nullptr;
+ }
protected:
void finishCreation(VM&, PassRefPtr<JITCode> callThunk, PassRefPtr<JITCode> constructThunk, const String& name);
private:
friend class ExecutableBase;
- NativeExecutable(VM&, NativeFunction function, NativeFunction constructor, Intrinsic);
+ NativeExecutable(VM&, NativeFunction function, NativeFunction constructor, Intrinsic, const DOMJIT::Signature*);
NativeFunction m_function;
NativeFunction m_constructor;
+ const DOMJIT::Signature* m_signature;
String m_name;
};
ClassStructure = 1 << 12, // property is a lazy class structure - only used by static hashtables
PropertyCallback = 1 << 13, // property that is a lazy property callback - only used by static hashtables
DOMJITAttribute = 1 << 14, // property is a DOM JIT attribute - only used by static hashtables
+ DOMJITFunction = 1 << 15, // property is a DOM JIT function - only used by static hashtables
BuiltinOrFunction = Builtin | Function, // helper only used by static hashtables
BuiltinOrFunctionOrLazyProperty = Builtin | Function | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
BuiltinOrFunctionOrAccessorOrLazyProperty = Builtin | Function | Accessor | CellProperty | ClassStructure | PropertyCallback, // helper only used by static hashtables
NativeExecutable* VM::getHostFunction(NativeFunction function, NativeFunction constructor, const String& name)
{
- return getHostFunction(function, NoIntrinsic, constructor, name);
+ return getHostFunction(function, NoIntrinsic, constructor, nullptr, name);
}
-NativeExecutable* VM::getHostFunction(NativeFunction function, Intrinsic intrinsic, NativeFunction constructor, const String& name)
+NativeExecutable* VM::getHostFunction(NativeFunction function, Intrinsic intrinsic, NativeFunction constructor, const DOMJIT::Signature* signature, const String& name)
{
#if ENABLE(JIT)
if (canUseJIT()) {
return jitStubs->hostFunctionStub(
this, function, constructor,
intrinsic != NoIntrinsic ? thunkGeneratorForIntrinsic(intrinsic) : 0,
- intrinsic, name);
+ intrinsic, signature, name);
}
#else // ENABLE(JIT)
UNUSED_PARAM(intrinsic);
return NativeExecutable::create(*this,
adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_native_call_trampoline), JITCode::HostCallThunk)), function,
adoptRef(new NativeJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_native_construct_trampoline), JITCode::HostCallThunk)), constructor,
- NoIntrinsic, name);
+ NoIntrinsic, signature, name);
}
VM::ClientData::~ClientData()
std::unique_ptr<FTL::Thunks> ftlThunks;
#endif
NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor, const String& name);
- NativeExecutable* getHostFunction(NativeFunction, Intrinsic intrinsic, NativeFunction constructor, const String& name);
+ NativeExecutable* getHostFunction(NativeFunction, Intrinsic, NativeFunction constructor, const DOMJIT::Signature*, const String& name);
static ptrdiff_t exceptionOffset()
{
dom/default/PlatformMessagePortChannel.cpp
- domjit/DOMJITAbstractHeapRepository.cpp
domjit/DOMJITHelpers.cpp
domjit/JSDocumentDOMJIT.cpp
domjit/JSNodeDOMJIT.cpp
list(APPEND WebCore_DERIVED_SOURCES ${DERIVED_SOURCES_WEBCORE_DIR}/ColorData.cpp)
+# Generate DOMJITAbstractHeapRepository.h
+add_custom_command(
+ OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/DOMJITAbstractHeapRepository.h
+ MAIN_DEPENDENCY domjit/DOMJITAbstractHeapRepository.yaml
+ DEPENDS ${WEBCORE_DIR}/domjit/generate-abstract-heap.rb
+ COMMAND ${RUBY_EXECUTABLE} ${WEBCORE_DIR}/domjit/generate-abstract-heap.rb ${WEBCORE_DIR}/domjit/DOMJITAbstractHeapRepository.yaml ${DERIVED_SOURCES_WEBCORE_DIR}/DOMJITAbstractHeapRepository.h
+ VERBATIM)
+list(APPEND WebCore_DERIVED_SOURCES ${DERIVED_SOURCES_WEBCORE_DIR}/DOMJITAbstractHeapRepository.h)
+
# Generate XMLViewerCSS.h
add_custom_command(
OUTPUT ${DERIVED_SOURCES_WEBCORE_DIR}/XMLViewerCSS.h ${DERIVED_SOURCES_WEBCORE_DIR}/XMLViewer.min.css
+2016-11-02 Yusuke Suzuki <utatane.tea@gmail.com>
+
+ [DOMJIT] Add DOMJIT::Signature
+ https://bugs.webkit.org/show_bug.cgi?id=162980
+
+ Reviewed by Saam Barati and Sam Weinig.
+
+ We introduce DOMJIT::Signature. This signature object is automatically generated by IDL code generator.
+ It holds (1) types, (2) pointer to the unsafe function (the function without checks), and (3) the effect
+ of the function. We use constexpr to initialize DOMJIT::Signature without invoking global constructors.
+ Thus the content is embedded into the binary as the constant values.
+
+ We also clean up the IDL code generator related to DOMJIT part. Instead of switching things inside IDL
+ code generator, we use C++ template to dispatch things at compile time. This template meta programming
+ is highly utilized in IDL these days.
+
+ To make DOMJIT::Signature constexpr, we also need to define DOMJIT abstract heap things in the build time.
+ To do so, we introduce a tiny Ruby script to calculate the range of abstract heaps. We can offer the abstract
+ heap tree as YAML format and the script will produce a C++ header holding the calculated abstract heap ranges
+
+ * CMakeLists.txt:
+ * DerivedSources.make:
+ * ForwardingHeaders/bytecode/SpeculatedType.h: Renamed from Source/WebCore/domjit/DOMJITAbstractHeapRepository.h.
+ * ForwardingHeaders/domjit/DOMJITSignature.h: Renamed from Source/WebCore/domjit/DOMJITAbstractHeapRepository.cpp.
+ * WebCore.xcodeproj/project.pbxproj:
+ * bindings/js/JSDOMGlobalObject.h:
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateHeader):
+ (GeneratePropertiesHashTable):
+ (GetUnsafeArgumentType):
+ (GetArgumentTypeFilter):
+ (GetResultTypeFilter):
+ (GenerateImplementation):
+ (UnsafeToNative):
+ (GenerateHashTableValueArray):
+ (ComputeFunctionSpecial):
+ * bindings/scripts/IDLAttributes.txt:
+ * bindings/scripts/test/JS/JSTestDOMJIT.cpp:
+ (WebCore::BindingCaller<JSTestDOMJIT>::castForOperation):
+ (WebCore::TestDOMJITAnyAttrDOMJIT::TestDOMJITAnyAttrDOMJIT):
+ (WebCore::TestDOMJITBooleanAttrDOMJIT::TestDOMJITBooleanAttrDOMJIT):
+ (WebCore::TestDOMJITByteAttrDOMJIT::TestDOMJITByteAttrDOMJIT):
+ (WebCore::TestDOMJITOctetAttrDOMJIT::TestDOMJITOctetAttrDOMJIT):
+ (WebCore::TestDOMJITShortAttrDOMJIT::TestDOMJITShortAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedShortAttrDOMJIT::TestDOMJITUnsignedShortAttrDOMJIT):
+ (WebCore::TestDOMJITLongAttrDOMJIT::TestDOMJITLongAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedLongAttrDOMJIT::TestDOMJITUnsignedLongAttrDOMJIT):
+ (WebCore::TestDOMJITLongLongAttrDOMJIT::TestDOMJITLongLongAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedLongLongAttrDOMJIT::TestDOMJITUnsignedLongLongAttrDOMJIT):
+ (WebCore::TestDOMJITFloatAttrDOMJIT::TestDOMJITFloatAttrDOMJIT):
+ (WebCore::TestDOMJITUnrestrictedFloatAttrDOMJIT::TestDOMJITUnrestrictedFloatAttrDOMJIT):
+ (WebCore::TestDOMJITDoubleAttrDOMJIT::TestDOMJITDoubleAttrDOMJIT):
+ (WebCore::TestDOMJITUnrestrictedDoubleAttrDOMJIT::TestDOMJITUnrestrictedDoubleAttrDOMJIT):
+ (WebCore::TestDOMJITDomStringAttrDOMJIT::TestDOMJITDomStringAttrDOMJIT):
+ (WebCore::TestDOMJITByteStringAttrDOMJIT::TestDOMJITByteStringAttrDOMJIT):
+ (WebCore::TestDOMJITUsvStringAttrDOMJIT::TestDOMJITUsvStringAttrDOMJIT):
+ (WebCore::TestDOMJITNodeAttrDOMJIT::TestDOMJITNodeAttrDOMJIT):
+ (WebCore::TestDOMJITBooleanNullableAttrDOMJIT::TestDOMJITBooleanNullableAttrDOMJIT):
+ (WebCore::TestDOMJITByteNullableAttrDOMJIT::TestDOMJITByteNullableAttrDOMJIT):
+ (WebCore::TestDOMJITOctetNullableAttrDOMJIT::TestDOMJITOctetNullableAttrDOMJIT):
+ (WebCore::TestDOMJITShortNullableAttrDOMJIT::TestDOMJITShortNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedShortNullableAttrDOMJIT::TestDOMJITUnsignedShortNullableAttrDOMJIT):
+ (WebCore::TestDOMJITLongNullableAttrDOMJIT::TestDOMJITLongNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedLongNullableAttrDOMJIT::TestDOMJITUnsignedLongNullableAttrDOMJIT):
+ (WebCore::TestDOMJITLongLongNullableAttrDOMJIT::TestDOMJITLongLongNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUnsignedLongLongNullableAttrDOMJIT::TestDOMJITUnsignedLongLongNullableAttrDOMJIT):
+ (WebCore::TestDOMJITFloatNullableAttrDOMJIT::TestDOMJITFloatNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUnrestrictedFloatNullableAttrDOMJIT::TestDOMJITUnrestrictedFloatNullableAttrDOMJIT):
+ (WebCore::TestDOMJITDoubleNullableAttrDOMJIT::TestDOMJITDoubleNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT::TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT):
+ (WebCore::TestDOMJITDomStringNullableAttrDOMJIT::TestDOMJITDomStringNullableAttrDOMJIT):
+ (WebCore::TestDOMJITByteStringNullableAttrDOMJIT::TestDOMJITByteStringNullableAttrDOMJIT):
+ (WebCore::TestDOMJITUsvStringNullableAttrDOMJIT::TestDOMJITUsvStringNullableAttrDOMJIT):
+ (WebCore::TestDOMJITNodeNullableAttrDOMJIT::TestDOMJITNodeNullableAttrDOMJIT):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetAttribute):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetAttributeCaller):
+ (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetAttribute):
+ (WebCore::jsTestDOMJITPrototypeFunctionItem):
+ (WebCore::jsTestDOMJITPrototypeFunctionItemCaller):
+ (WebCore::unsafeJsTestDOMJITPrototypeFunctionItem):
+ (WebCore::jsTestDOMJITPrototypeFunctionHasAttribute):
+ (WebCore::jsTestDOMJITPrototypeFunctionHasAttributeCaller):
+ (WebCore::unsafeJsTestDOMJITPrototypeFunctionHasAttribute):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetElementById):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetElementByIdCaller):
+ (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetElementById):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetElementsByName):
+ (WebCore::jsTestDOMJITPrototypeFunctionGetElementsByNameCaller):
+ (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetElementsByName):
+ * bindings/scripts/test/TestDOMJIT.idl:
+ * dom/Element.idl:
+ * domjit/DOMJITAbstractHeapRepository.yaml: Added.
+ * domjit/DOMJITIDLConvert.h: Added.
+ (WebCore::DOMJIT::DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>):
+ * domjit/DOMJITIDLType.h: Added.
+ * domjit/DOMJITIDLTypeFilter.h: Added.
+ * domjit/JSDocumentDOMJIT.cpp:
+ (WebCore::DocumentDocumentElementDOMJIT::callDOMGetter):
+ * domjit/JSNodeDOMJIT.cpp:
+ (WebCore::NodeFirstChildDOMJIT::callDOMGetter):
+ (WebCore::NodeLastChildDOMJIT::callDOMGetter):
+ (WebCore::NodeNextSiblingDOMJIT::callDOMGetter):
+ (WebCore::NodePreviousSiblingDOMJIT::callDOMGetter):
+ (WebCore::NodeParentNodeDOMJIT::callDOMGetter):
+ (WebCore::NodeOwnerDocumentDOMJIT::callDOMGetter):
+ * domjit/generate-abstract-heap.rb: Added.
+
2016-11-02 Simon Fraser <simon.fraser@apple.com>
Followup after r208314.
PYTHON = python
PERL = perl
+RUBY = ruby
ifeq ($(OS),Windows_NT)
DELETE = cmd //C del
CSSValueKeywords.cpp \
CSSValueKeywords.h \
ColorData.cpp \
+ DOMJITAbstractHeapRepository.h \
EventInterfaces.h \
EventTargetInterfaces.h \
ExceptionCodeDescription.cpp \
# --------
+# DOMJIT Abstract Heap
+
+all : DOMJITAbstractHeapRepository.h
+
+DOMJITAbstractHeapRepository.h : $(WebCore)/domjit/generate-abstract-heap.rb $(WebCore)/domjit/DOMJITAbstractHeapRepository.yaml
+ $(RUBY) "$(WebCore)/domjit/generate-abstract-heap.rb" $(WebCore)/domjit/DOMJITAbstractHeapRepository.yaml ./DOMJITAbstractHeapRepository.h
+
+# --------
+
# XMLViewer CSS
all : XMLViewerCSS.h
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
-
-#include <domjit/DOMJITHeapRange.h>
-#include <wtf/NeverDestroyed.h>
-#include <wtf/Noncopyable.h>
-
-#if ENABLE(JIT)
-
-namespace WebCore { namespace DOMJIT {
-
-// Describe your abstract heap hierarchy here.
-// V(AbstractHeapName, Parent)
-#define DOMJIT_ABSTRACT_HEAP_LIST(V) \
- V(Node, DOM) \
- V(Node_firstChild, Node) \
- V(Node_lastChild, Node) \
- V(Node_parentNode, Node) \
- V(Node_nextSibling, Node) \
- V(Node_previousSibling, Node) \
- V(Node_ownerDocument, Node) \
- V(Document, DOM) \
- V(Document_documentElement, Document) \
-
-
-class AbstractHeapRepository {
- WTF_MAKE_NONCOPYABLE(AbstractHeapRepository);
-public:
- static const AbstractHeapRepository& shared();
-
- JSC::DOMJIT::HeapRange DOM;
-
-#define DOMJIT_DEFINE_MEMBER(name, parent) JSC::DOMJIT::HeapRange name;
- DOMJIT_ABSTRACT_HEAP_LIST(DOMJIT_DEFINE_MEMBER)
-#undef DOMJIT_DEFINE_MEMBER
-
- AbstractHeapRepository();
-};
-
-} }
-
+#ifndef WebCore_FWD_SpeculatedType_h
+#define WebCore_FWD_SpeculatedType_h
+#include <JavaScriptCore/SpeculatedType.h>
#endif
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "DOMJITAbstractHeapRepository.h"
-
-#include <domjit/DOMJITAbstractHeap.h>
-#include <wtf/DataLog.h>
-#include <wtf/NeverDestroyed.h>
-
-#if ENABLE(JIT)
-
-namespace WebCore { namespace DOMJIT {
-
-static const bool verbose = false;
-
-AbstractHeapRepository::AbstractHeapRepository()
-{
- JSC::DOMJIT::AbstractHeap DOMHeap("DOM");
-#define DOMJIT_DEFINE_HEAP(name, parent) JSC::DOMJIT::AbstractHeap name##Heap(#name);
- DOMJIT_ABSTRACT_HEAP_LIST(DOMJIT_DEFINE_HEAP)
-#undef DOMJIT_DEFINE_HEAP
-
-#define DOMJIT_INITIALIZE_HEAP(name, parent) name##Heap.setParent(&parent##Heap);
- DOMJIT_ABSTRACT_HEAP_LIST(DOMJIT_INITIALIZE_HEAP)
-#undef DOMJIT_INITIALIZE_HEAP
-
- DOMHeap.compute(0);
-
-#define DOMJIT_INITIALIZE_MEMBER(name, parent) name = name##Heap.range();
- DOMJIT_ABSTRACT_HEAP_LIST(DOMJIT_INITIALIZE_MEMBER)
-#undef DOMJIT_INITIALIZE_MEMBER
-
- if (verbose) {
- dataLog("DOMJIT Heap Repository:\n");
- DOMHeap.deepDump(WTF::dataFile());
- }
-}
-
-const AbstractHeapRepository& AbstractHeapRepository::shared()
-{
- static NeverDestroyed<AbstractHeapRepository> repository;
- return repository.get();
-}
-
-} }
-
+#ifndef WebCore_FWD_DOMJITSignature_h
+#define WebCore_FWD_DOMJITSignature_h
+#include <JavaScriptCore/DOMJITSignature.h>
#endif
E3150EA71DA7219300194012 /* DOMJITHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E3150EA51DA7218D00194012 /* DOMJITHelpers.h */; };
E318039D1DC40099009932C2 /* JSDynamicDowncast.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A5872E1DC3F52600F607A6 /* JSDynamicDowncast.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3565B7B1DC2D6C900217DBD /* JSEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EE49F1DC2D57500EAA9D3 /* JSEventCustom.h */; settings = {ATTRIBUTES = (Private, ); }; };
- E35CA14D1DBC3A3F00F83516 /* DOMJITAbstractHeapRepository.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E35CA14B1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.cpp */; };
- E35CA14E1DBC3A4200F83516 /* DOMJITAbstractHeapRepository.h in Headers */ = {isa = PBXBuildFile; fileRef = E35CA14C1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.h */; };
+ E35802B61DC8435D00A9773C /* DOMJITIDLTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
E377FE4D1DADE16500CDD025 /* NodeConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D049931DADC04500718F3C /* NodeConstants.h */; settings = {ATTRIBUTES = (Private, ); }; };
E38838981BAD145F00D62EE3 /* ScriptModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */; };
E38838991BAD145F00D62EE3 /* ScriptModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */; };
E398FC241DC32A20003C4684 /* DOMJITHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E398FC231DC32A1B003C4684 /* DOMJITHelpers.cpp */; };
+ E3A776671DC85D2800B690D8 /* DOMJITIDLConvert.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A776651DC85D2200B690D8 /* DOMJITIDLConvert.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E3A776681DC85D2800B690D8 /* DOMJITIDLType.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A776661DC85D2200B690D8 /* DOMJITIDLType.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3B2F0EB1D7F4C9D00B0C9D1 /* LoadableClassicScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */; };
E3B2F0EC1D7F4CA100B0C9D1 /* LoadableScript.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3B2F0E91D7F3D3C00B0C9D1 /* LoadableScript.cpp */; };
E3B2F0ED1D7F4CA300B0C9D1 /* LoadableScript.h in Headers */ = {isa = PBXBuildFile; fileRef = E3B2F0E71D7F35EC00B0C9D1 /* LoadableScript.h */; settings = {ATTRIBUTES = (Private, ); }; };
E1FF8F6A180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRegistry.cpp; sourceTree = "<group>"; };
E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRegistry.h; sourceTree = "<group>"; };
E3150EA51DA7218D00194012 /* DOMJITHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITHelpers.h; sourceTree = "<group>"; };
+ E334825E1DC93AA0009C9544 /* DOMJITAbstractHeapRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeapRepository.h; sourceTree = "<group>"; };
E34EE49F1DC2D57500EAA9D3 /* JSEventCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEventCustom.h; sourceTree = "<group>"; };
- E35CA14B1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAbstractHeapRepository.cpp; sourceTree = "<group>"; };
- E35CA14C1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeapRepository.h; sourceTree = "<group>"; };
+ E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITIDLTypeFilter.h; sourceTree = "<group>"; };
E38838941BAD145F00D62EE3 /* ScriptModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptModuleLoader.cpp; sourceTree = "<group>"; };
E38838951BAD145F00D62EE3 /* ScriptModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptModuleLoader.h; sourceTree = "<group>"; };
E398FC231DC32A1B003C4684 /* DOMJITHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITHelpers.cpp; sourceTree = "<group>"; };
E3A5872E1DC3F52600F607A6 /* JSDynamicDowncast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDynamicDowncast.h; sourceTree = "<group>"; };
+ E3A776651DC85D2200B690D8 /* DOMJITIDLConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITIDLConvert.h; sourceTree = "<group>"; };
+ E3A776661DC85D2200B690D8 /* DOMJITIDLType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITIDLType.h; sourceTree = "<group>"; };
E3AFA9641DA6E908002861BD /* JSNodeDOMJIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNodeDOMJIT.cpp; sourceTree = "<group>"; };
E3B2F0E31D7F35EC00B0C9D1 /* LoadableClassicScript.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LoadableClassicScript.cpp; sourceTree = "<group>"; };
E3B2F0E41D7F35EC00B0C9D1 /* LoadableClassicScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableClassicScript.h; sourceTree = "<group>"; };
6565814709D13043000E61D7 /* CSSValueKeywords.gperf */,
6565814809D13043000E61D7 /* CSSValueKeywords.h */,
9B3A8871145632F9003AE8F5 /* DOMDOMSettableTokenList.h */,
+ E334825E1DC93AA0009C9544 /* DOMJITAbstractHeapRepository.h */,
E1C6CFC21746D293007B87A1 /* DOMWindowConstructors.idl */,
970B72A5145008EB00F00A37 /* EventHeaders.h */,
970B7289144FFAC600F00A37 /* EventInterfaces.h */,
E3AFA9631DA6E8AF002861BD /* domjit */ = {
isa = PBXGroup;
children = (
- E35CA14B1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.cpp */,
- E35CA14C1DBC3A3C00F83516 /* DOMJITAbstractHeapRepository.h */,
E3C99A081DC3D41700794AD3 /* DOMJITCheckDOM.h */,
E398FC231DC32A1B003C4684 /* DOMJITHelpers.cpp */,
E3150EA51DA7218D00194012 /* DOMJITHelpers.h */,
+ E3A776651DC85D2200B690D8 /* DOMJITIDLConvert.h */,
+ E3A776661DC85D2200B690D8 /* DOMJITIDLType.h */,
+ E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */,
E3B7C0621DC3415A001FB0B8 /* JSDocumentDOMJIT.cpp */,
E3AFA9641DA6E908002861BD /* JSNodeDOMJIT.cpp */,
);
460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */,
BCBFB53D0DCD29CF0019B3E5 /* JSDOMWindowShell.h in Headers */,
65E0E9441133C89F00B4CB10 /* JSDOMWrapper.h in Headers */,
+ E3A776671DC85D2800B690D8 /* DOMJITIDLConvert.h in Headers */,
FD7868BA136B999200D403DF /* JSDynamicsCompressorNode.h in Headers */,
65DF31FA09D1CC60000BE325 /* JSElement.h in Headers */,
ADEC78F818EE5308001315C2 /* JSElementCustom.h in Headers */,
08525E631278C00100A84778 /* SVGAnimatedStaticPropertyTearOff.h in Headers */,
084DB59B128008CC002A6D64 /* SVGAnimatedString.h in Headers */,
08250939128BD4D800E2ED8E /* SVGAnimatedTransformList.h in Headers */,
+ E3A776681DC85D2800B690D8 /* DOMJITIDLType.h in Headers */,
085A15931289A8DD002710E3 /* SVGAnimatedTransformListPropertyTearOff.h in Headers */,
439D334313A6911C00C20F4F /* SVGAnimatedType.h in Headers */,
439D334413A6911C00C20F4F /* SVGAnimatedTypeAnimator.h in Headers */,
97AABD2314FA09D5007457AE /* WebSocketExtensionDispatcher.h in Headers */,
4A5A2ADC161E7E00005889DD /* WebSocketExtensionParser.h in Headers */,
97AABD2414FA09D5007457AE /* WebSocketExtensionProcessor.h in Headers */,
+ E35802B61DC8435D00A9773C /* DOMJITIDLTypeFilter.h in Headers */,
97AABD2514FA09D5007457AE /* WebSocketFrame.h in Headers */,
97AABD2714FA09D5007457AE /* WebSocketHandshake.h in Headers */,
31DEA4561B39F4D900F77178 /* WebSystemBackdropLayer.h in Headers */,
public:
~JSDOMGlobalObject();
- static const JSC::ClassInfo* info() { return &s_info; }
+ static constexpr const JSC::ClassInfo* info() { return &s_info; }
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSValue prototype)
{
push(@headerContent, "protected:\n");
push(@headerContent, " static const JSC::ClassInfo s_info;\n");
push(@headerContent, "public:\n");
- push(@headerContent, " static const JSC::ClassInfo* info() { return &s_info; }\n\n");
+ push(@headerContent, " static constexpr const JSC::ClassInfo* info() { return &s_info; }\n\n");
} else {
push(@headerContent, "\n");
push(@headerContent, " DECLARE_INFO;\n\n");
# FIXME: Remove this once we can get rid of the quirk introduced in https://bugs.webkit.org/show_bug.cgi?id=163967.
$functionLength = 3 if $interfaceName eq "Event" and $function->name eq "initEvent";
- push(@$hashValue2, $functionLength);
+ if ($function->extendedAttributes->{DOMJIT}) {
+ push(@$hashValue2, "&DOMJITSignatureFor" . $interface->type->name . $codeGenerator->WK_ucfirst($function->name));
+ } else {
+ push(@$hashValue2, $functionLength);
+ }
push(@$hashSpecials, ComputeFunctionSpecial($interface, $function));
push(@implContent, " putDirectWithoutTransition(vm, vm.propertyNames->unscopablesSymbol, &unscopables, DontEnum | ReadOnly);\n");
}
-sub GetResultTypeFilter
+sub GetUnsafeArgumentType
{
- my ($type) = @_;
+ my ($interface, $type) = @_;
- my %TypeFilters = (
- "any" => "SpecHeapTop",
- "boolean" => "SpecBoolean",
- "byte" => "SpecInt32Only",
- "octet" => "SpecInt32Only",
- "short" => "SpecInt32Only",
- "unsigned short" => "SpecInt32Only",
- "long" => "SpecInt32Only",
- "unsigned long" => "SpecBytecodeNumber",
- "long long" => "SpecBytecodeNumber",
- "unsigned long long" => "SpecBytecodeNumber",
- "float" => "SpecBytecodeNumber",
- "unrestricted float" => "SpecBytecodeNumber",
- "double" => "SpecBytecodeNumber",
- "unrestricted double" => "SpecBytecodeNumber",
- "DOMString" => "SpecString",
- "ByteString" => "SpecString",
- "USVString" => "SpecString",
- );
+ my $IDLType = GetIDLType($interface, $type);
+ return "DOMJIT::IDLJSArgumentType<${IDLType}>";
+}
- if (exists $TypeFilters{$type->name}) {
- my $resultType = "JSC::$TypeFilters{$type->name}";
- if ($type->isNullable) {
- die "\"any\" type must not become nullable." if $type->name eq "any";
- $resultType = "($resultType | JSC::SpecOther)";
- }
- return $resultType;
- }
- return "SpecHeapTop";
+sub GetArgumentTypeFilter
+{
+ my ($interface, $type) = @_;
+
+ my $IDLType = GetIDLType($interface, $type);
+ return "DOMJIT::IDLArgumentTypeFilter<${IDLType}>::value";
+}
+
+sub GetResultTypeFilter
+{
+ my ($interface, $type) = @_;
+
+ my $IDLType = GetIDLType($interface, $type);
+ return "DOMJIT::IDLResultTypeFilter<${IDLType}>::value";
}
sub GenerateImplementation
push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
my $functionName = GetFunctionName($interface, $className, $function);
push(@implContent, "JSC::EncodedJSValue JSC_HOST_CALL ${functionName}(JSC::ExecState*);\n");
+ if ($function->extendedAttributes->{DOMJIT}) {
+ $implIncludes{"DOMJITIDLType.h"} = 1;
+ my $unsafeFunctionName = "unsafe" . $codeGenerator->WK_ucfirst($functionName);
+ my $functionSignature = "JSC::EncodedJSValue JSC_HOST_CALL ${unsafeFunctionName}(JSC::ExecState*, $className*";
+ foreach my $argument (@{$function->arguments}) {
+ my $type = $argument->type;
+ my $argumentType = GetUnsafeArgumentType($interface, $type);
+ $functionSignature .= ", ${argumentType}";
+ }
+ push(@implContent, $functionSignature . ");\n");
+ }
push(@implContent, "#endif\n") if $conditionalString;
}
push(@implContent, "\n");
}
+ if ($numFunctions > 0) {
+ foreach my $function (@functions) {
+ next unless $function->extendedAttributes->{DOMJIT};
+ $implIncludes{"DOMJITIDLTypeFilter.h"} = 1;
+ $implIncludes{"DOMJITCheckDOM.h"} = 1;
+ $implIncludes{"DOMJITAbstractHeapRepository.h"} = 1;
+
+ my $isOverloaded = $function->{overloads} && @{$function->{overloads}} > 1;
+ die "Overloads is not supported in DOMJIT" if $isOverloaded;
+ die "Currently ReadDOM value is only allowed" unless $codeGenerator->ExtendedAttributeContains($function->extendedAttributes->{DOMJIT}, "ReadDOM");
+
+ my $interfaceName = $interface->type->name;
+ my $functionName = GetFunctionName($interface, $className, $function);
+ my $unsafeFunctionName = "unsafe" . $codeGenerator->WK_ucfirst($functionName);
+ my $domJITSignatureName = "DOMJITSignatureFor" . $interface->type->name . $codeGenerator->WK_ucfirst($function->name);
+ my $classInfo = "JS" . $interface->type->name . "::info()";
+ my $resultType = GetResultTypeFilter($interface, $function->type);
+ my $domJITSignature = "static const JSC::DOMJIT::Signature ${domJITSignatureName}((uintptr_t)${unsafeFunctionName}, DOMJIT::checkDOM<$interfaceName>, $classInfo, JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), ${resultType}";
+ foreach my $argument (@{$function->arguments}) {
+ my $type = $argument->type;
+ my $argumentType = GetArgumentTypeFilter($interface, $type);
+ $domJITSignature .= ", ${argumentType}";
+ }
+ my $conditionalString = $codeGenerator->GenerateConditionalString($function);
+ push(@implContent, "#if ${conditionalString}\n") if $conditionalString;
+ push(@implContent, $domJITSignature . ");\n");
+ push(@implContent, "#endif\n") if $conditionalString;
+ push(@implContent, "\n");
+ }
+ }
+
GeneratePrototypeDeclaration(\@implContent, $className, $interface) if !HeaderNeedsPrototypeDeclaration($interface);
GenerateConstructorDeclaration(\@implContent, $className, $interface) if NeedsConstructorProperty($interface);
push(@hashValue1, $functionName);
my $functionLength = GetFunctionLength($function);
- push(@hashValue2, $functionLength);
+ if ($function->extendedAttributes->{DOMJIT}) {
+ push(@hashValue2, "DOMJITFunctionFor" . $interface->type->name . $codeGenerator->WK_ucfirst($function->name));
+ } else {
+ push(@hashValue2, $functionLength);
+ }
push(@hashSpecials, ComputeFunctionSpecial($interface, $function));
if ($attribute->extendedAttributes->{"DOMJIT"}) {
$implIncludes{"<wtf/NeverDestroyed.h>"} = 1;
+ $implIncludes{"DOMJITIDLTypeFilter.h"} = 1;
my $interfaceName = $interface->type->name;
my $attributeName = $attribute->name;
my $generatorName = $interfaceName . $codeGenerator->WK_ucfirst($attribute->name);
my $domJITClassName = $generatorName . "DOMJIT";
my $getter = GetAttributeGetterName($interface, $generatorName, $attribute);
my $setter = IsReadonly($attribute) ? "nullptr" : GetAttributeSetterName($interface, $generatorName, $attribute);
- my $resultType = GetResultTypeFilter($attribute->type);
+ my $resultType = GetResultTypeFilter($interface, $attribute->type);
push(@implContent, "$domJITClassName::$domJITClassName()\n");
push(@implContent, " : JSC::DOMJIT::GetterSetter($getter, $setter, ${className}::info(), $resultType)\n");
push(@implContent, "{\n");
}
push(@implContent, "}\n\n");
+
+ if ($function->extendedAttributes->{DOMJIT}) {
+ $implIncludes{"<interpreter/FrameTracers.h>"} = 1;
+ my $unsafeFunctionName = "unsafe" . $codeGenerator->WK_ucfirst($functionName);
+ push(@implContent, "JSC::EncodedJSValue JSC_HOST_CALL ${unsafeFunctionName}(JSC::ExecState* state, $className* castedThis");
+ foreach my $argument (@{$function->arguments}) {
+ my $type = $argument->type;
+ my $argumentType = GetUnsafeArgumentType($interface, $type);
+ my $name = $argument->name;
+ my $encodedName = "encoded" . $codeGenerator->WK_ucfirst($name);
+ push(@implContent, ", ${argumentType} ${encodedName}");
+ }
+ push(@implContent, ")\n");
+ push(@implContent, "{\n");
+ push(@implContent, " UNUSED_PARAM(state);\n");
+ push(@implContent, " VM& vm = state->vm();\n");
+ push(@implContent, " JSC::NativeCallFrameTracer tracer(&vm, state);\n");
+ push(@implContent, " auto throwScope = DECLARE_THROW_SCOPE(vm);\n");
+ push(@implContent, " UNUSED_PARAM(throwScope);\n");
+ push(@implContent, " auto& impl = castedThis->wrapped();\n");
+ my @arguments;
+ my $implFunctionName;
+ my $implementedBy = $function->extendedAttributes->{ImplementedBy};
+
+ if ($implementedBy) {
+ AddToImplIncludes("${implementedBy}.h", $function->extendedAttributes->{Conditional});
+ unshift(@arguments, "impl") if !$function->isStatic;
+ $implFunctionName = "WebCore::${implementedBy}::${functionImplementationName}";
+ } elsif ($function->isStatic) {
+ $implFunctionName = "${interfaceName}::${functionImplementationName}";
+ } elsif ($svgPropertyOrListPropertyType and !$svgListPropertyType) {
+ $implFunctionName = "podImpl.${functionImplementationName}";
+ } else {
+ $implFunctionName = "impl.${functionImplementationName}";
+ }
+
+ foreach my $argument (@{$function->arguments}) {
+ my $value = "";
+ my $type = $argument->type;
+ my $name = $argument->name;
+ my $encodedName = "encoded" . $codeGenerator->WK_ucfirst($name);
+ my $nativeType = GetNativeType($interface, $argument->type);
+ my $isTearOff = $codeGenerator->IsSVGTypeNeedingTearOff($type) && $interfaceName !~ /List$/;
+ die "TearOff type is not allowed" if $isTearOff;
+ my $shouldPassByReference = ShouldPassWrapperByReference($argument, $interface);
+
+ if (!$shouldPassByReference && ($codeGenerator->IsWrapperType($type) || $codeGenerator->IsTypedArrayType($type))) {
+ $implIncludes{"<runtime/Error.h>"} = 1;
+ my ($nativeValue, $mayThrowException) = UnsafeToNative($interface, $argument, $encodedName, $function->extendedAttributes->{Conditional});
+ push(@implContent, " $nativeType $name = nullptr;\n");
+ push(@implContent, " $name = $nativeValue;\n");
+ push(@implContent, " RETURN_IF_EXCEPTION(throwScope, encodedJSValue());\n") if $mayThrowException;
+ $value = "WTFMove($name)";
+ } else {
+ my ($nativeValue, $mayThrowException) = UnsafeToNative($interface, $argument, $encodedName, $function->extendedAttributes->{Conditional});
+ push(@implContent, " auto $name = ${nativeValue};\n");
+ $value = "WTFMove($name)";
+ push(@implContent, " RETURN_IF_EXCEPTION(throwScope, encodedJSValue());\n") if $mayThrowException;
+ }
+
+ if ($shouldPassByReference) {
+ $value = "*$name";
+ }
+ push(@arguments, $value);
+ }
+ my $functionString = "$implFunctionName(" . join(", ", @arguments) . ")";
+ $functionString = "propagateException(*state, throwScope, $functionString)" if NeedsExplicitPropagateExceptionCall($function);
+ push(@implContent, " JSValue result = " . NativeToJSValueUsingPointers($function, 1, $interface, $functionString, "castedThis") . ";\n");
+ push(@implContent, " return JSValue::encode(result);\n");
+ push(@implContent, "}\n\n");
+ }
+
push(@implContent, "#endif\n\n") if $conditional;
# Generate a function dispatching call to the rest of the overloads.
return ("convert<$IDLType>(" . join(", ", @conversionArguments) . ")", 1);
}
+sub UnsafeToNative
+{
+ my ($interface, $context, $value, $conditional, $statePointer, $stateReference, $thisObjectReference) = @_;
+
+ assert("Invalid context type") if !IsValidContextForJSValueToNative($context);
+
+ my $type = $context->type;
+
+ # FIXME: Remove these 3 variables when all JSValueToNative use references.
+ $statePointer = "state" unless $statePointer;
+ $stateReference = "*state" unless $stateReference;
+ $thisObjectReference = "*castedThis" unless $thisObjectReference;
+
+ AddToImplIncludesForIDLType($type, $conditional);
+
+ # FIXME: Support more types.
+
+ if ($type->name eq "DOMString") {
+ return ("AtomicString($value->toExistingAtomicString($statePointer))", 1) if $context->extendedAttributes->{RequiresExistingAtomicString};
+ return ("$value->toAtomicString($statePointer)", 1) if $context->extendedAttributes->{AtomicString};
+ }
+
+ AddToImplIncludes("DOMJITIDLConvert.h");
+
+ my $IDLType = GetIDLType($interface, $type);
+
+ my @conversionArguments = ();
+ push(@conversionArguments, "$stateReference");
+ push(@conversionArguments, "$value");
+
+ my @conversionStaticArguments = ();
+ push(@conversionStaticArguments, GetIntegerConversionConfiguration($context)) if $codeGenerator->IsIntegerType($type);
+ push(@conversionStaticArguments, GetStringConversionConfiguration($context)) if $codeGenerator->IsStringType($type);
+
+ if (scalar(@conversionStaticArguments) > 0) {
+ return ("DOMJIT::DirectConverter<$IDLType>::directConvert<" . join(", ", @conversionStaticArguments) . ">(" . join(", ", @conversionArguments) . ")", 1);
+ }
+ return ("DOMJIT::DirectConverter<$IDLType>::directConvert(" . join(", ", @conversionArguments) . ")", 1);
+}
+
sub NativeToJSValueDOMConvertNeedsState
{
my ($type) = @_;
push(@implContent, "#if ${conditionalString}\n");
}
- if ("@$specials[$i]" =~ m/Function/) {
+ if ("@$specials[$i]" =~ m/DOMJITFunction/) {
+ $firstTargetType = "static_cast<NativeFunction>";
+ $secondTargetType = "static_cast<const JSC::DOMJIT::Signature*>";
+ } elsif ("@$specials[$i]" =~ m/Function/) {
$firstTargetType = "static_cast<NativeFunction>";
} elsif ("@$specials[$i]" =~ m/Builtin/) {
$firstTargetType = "static_cast<BuiltinGenerator>";
else {
push(@specials, "JSC::Function");
}
+ if ($function->extendedAttributes->{"DOMJIT"}) {
+ push(@specials, "DOMJITFunction") if $function->extendedAttributes->{DOMJIT};
+ }
return (@specials > 0) ? join(" | ", @specials) : "0";
}
CustomSetPrototype
CustomSetter
CustomToJSObject
-DOMJIT
+DOMJIT=|ReadDOM
DoNotCheckConstants
DoNotCheckSecurity
DoNotCheckSecurityOnGetter
#include "config.h"
#include "JSTestDOMJIT.h"
+#include "DOMJITAbstractHeapRepository.h"
+#include "DOMJITCheckDOM.h"
+#include "DOMJITIDLConvert.h"
+#include "DOMJITIDLType.h"
+#include "DOMJITIDLTypeFilter.h"
+#include "ExceptionCode.h"
#include "JSByteString.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvert.h"
+#include "JSElement.h"
+#include "JSNodeList.h"
+#include <interpreter/FrameTracers.h>
+#include <runtime/Error.h>
#include <wtf/GetPtr.h>
#include <wtf/NeverDestroyed.h>
namespace WebCore {
+// Functions
+
+JSC::EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetAttribute(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetAttribute(JSC::ExecState*, JSTestDOMJIT*, DOMJIT::IDLJSArgumentType<IDLDOMString>);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionItem(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionItem(JSC::ExecState*, JSTestDOMJIT*, DOMJIT::IDLJSArgumentType<IDLUnsignedShort>, DOMJIT::IDLJSArgumentType<IDLUnsignedShort>);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionHasAttribute(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionHasAttribute(JSC::ExecState*, JSTestDOMJIT*);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetElementById(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetElementById(JSC::ExecState*, JSTestDOMJIT*, DOMJIT::IDLJSArgumentType<IDLDOMString>);
+JSC::EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetElementsByName(JSC::ExecState*);
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetElementsByName(JSC::ExecState*, JSTestDOMJIT*, DOMJIT::IDLJSArgumentType<IDLDOMString>);
+
// Attributes
JSC::EncodedJSValue jsTestDOMJITAnyAttr(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsTestDOMJITConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSTestDOMJITConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
+static const JSC::DOMJIT::Signature DOMJITSignatureForTestDOMJITGetAttribute((uintptr_t)unsafeJsTestDOMJITPrototypeFunctionGetAttribute, DOMJIT::checkDOM<TestDOMJIT>, JSTestDOMJIT::info(), JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLDOMString>>::value, DOMJIT::IDLArgumentTypeFilter<IDLDOMString>::value);
+
+static const JSC::DOMJIT::Signature DOMJITSignatureForTestDOMJITItem((uintptr_t)unsafeJsTestDOMJITPrototypeFunctionItem, DOMJIT::checkDOM<TestDOMJIT>, JSTestDOMJIT::info(), JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), DOMJIT::IDLResultTypeFilter<IDLDOMString>::value, DOMJIT::IDLArgumentTypeFilter<IDLUnsignedShort>::value, DOMJIT::IDLArgumentTypeFilter<IDLUnsignedShort>::value);
+
+static const JSC::DOMJIT::Signature DOMJITSignatureForTestDOMJITHasAttribute((uintptr_t)unsafeJsTestDOMJITPrototypeFunctionHasAttribute, DOMJIT::checkDOM<TestDOMJIT>, JSTestDOMJIT::info(), JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), DOMJIT::IDLResultTypeFilter<IDLBoolean>::value);
+
+static const JSC::DOMJIT::Signature DOMJITSignatureForTestDOMJITGetElementById((uintptr_t)unsafeJsTestDOMJITPrototypeFunctionGetElementById, DOMJIT::checkDOM<TestDOMJIT>, JSTestDOMJIT::info(), JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), DOMJIT::IDLResultTypeFilter<IDLInterface<Element>>::value, DOMJIT::IDLArgumentTypeFilter<IDLDOMString>::value);
+
+static const JSC::DOMJIT::Signature DOMJITSignatureForTestDOMJITGetElementsByName((uintptr_t)unsafeJsTestDOMJITPrototypeFunctionGetElementsByName, DOMJIT::checkDOM<TestDOMJIT>, JSTestDOMJIT::info(), JSC::DOMJIT::Effect::forRead(DOMJIT::AbstractHeapRepository::DOM), DOMJIT::IDLResultTypeFilter<IDLInterface<NodeList>>::value, DOMJIT::IDLArgumentTypeFilter<IDLDOMString>::value);
+
class JSTestDOMJITPrototype : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
{ "byteStringNullableAttr", ReadOnly | CustomAccessor | DOMJITAttribute, NoIntrinsic, { (intptr_t)static_cast<DOMJITGetterSetterGenerator>(domJITGetterSetterForTestDOMJITByteStringNullableAttr), (intptr_t) (0) } },
{ "usvStringNullableAttr", ReadOnly | CustomAccessor | DOMJITAttribute, NoIntrinsic, { (intptr_t)static_cast<DOMJITGetterSetterGenerator>(domJITGetterSetterForTestDOMJITUsvStringNullableAttr), (intptr_t) (0) } },
{ "nodeNullableAttr", ReadOnly | CustomAccessor | DOMJITAttribute, NoIntrinsic, { (intptr_t)static_cast<DOMJITGetterSetterGenerator>(domJITGetterSetterForTestDOMJITNodeNullableAttr), (intptr_t) (0) } },
+ { "getAttribute", JSC::Function | DOMJITFunction, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestDOMJITPrototypeFunctionGetAttribute), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForTestDOMJITGetAttribute) } },
+ { "item", JSC::Function | DOMJITFunction, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestDOMJITPrototypeFunctionItem), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForTestDOMJITItem) } },
+ { "hasAttribute", JSC::Function | DOMJITFunction, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestDOMJITPrototypeFunctionHasAttribute), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForTestDOMJITHasAttribute) } },
+ { "getElementById", JSC::Function | DOMJITFunction, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestDOMJITPrototypeFunctionGetElementById), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForTestDOMJITGetElementById) } },
+ { "getElementsByName", JSC::Function | DOMJITFunction, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsTestDOMJITPrototypeFunctionGetElementsByName), (intptr_t) static_cast<const JSC::DOMJIT::Signature*>(&DOMJITSignatureForTestDOMJITGetElementsByName) } },
};
const ClassInfo JSTestDOMJITPrototype::s_info = { "TestDOMJITPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSTestDOMJITPrototype) };
return jsDynamicDowncast<JSTestDOMJIT*>(JSValue::decode(thisValue));
}
+template<> inline JSTestDOMJIT* BindingCaller<JSTestDOMJIT>::castForOperation(ExecState& state)
+{
+ return jsDynamicDowncast<JSTestDOMJIT*>(state.thisValue());
+}
+
static inline JSValue jsTestDOMJITAnyAttrGetter(ExecState&, JSTestDOMJIT&, ThrowScope& throwScope);
EncodedJSValue jsTestDOMJITAnyAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
}
TestDOMJITAnyAttrDOMJIT::TestDOMJITAnyAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITAnyAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecHeapTop)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITAnyAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLAny>::value)
{
}
}
TestDOMJITBooleanAttrDOMJIT::TestDOMJITBooleanAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITBooleanAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBoolean)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITBooleanAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLBoolean>::value)
{
}
}
TestDOMJITByteAttrDOMJIT::TestDOMJITByteAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecInt32Only)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLByte>::value)
{
}
}
TestDOMJITOctetAttrDOMJIT::TestDOMJITOctetAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITOctetAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecInt32Only)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITOctetAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLOctet>::value)
{
}
}
TestDOMJITShortAttrDOMJIT::TestDOMJITShortAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITShortAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecInt32Only)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITShortAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLShort>::value)
{
}
}
TestDOMJITUnsignedShortAttrDOMJIT::TestDOMJITUnsignedShortAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedShortAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecInt32Only)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedShortAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUnsignedShort>::value)
{
}
}
TestDOMJITLongAttrDOMJIT::TestDOMJITLongAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecInt32Only)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLLong>::value)
{
}
}
TestDOMJITUnsignedLongAttrDOMJIT::TestDOMJITUnsignedLongAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUnsignedLong>::value)
{
}
}
TestDOMJITLongLongAttrDOMJIT::TestDOMJITLongLongAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongLongAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongLongAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLLongLong>::value)
{
}
}
TestDOMJITUnsignedLongLongAttrDOMJIT::TestDOMJITUnsignedLongLongAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongLongAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongLongAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUnsignedLongLong>::value)
{
}
}
TestDOMJITFloatAttrDOMJIT::TestDOMJITFloatAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITFloatAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITFloatAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLFloat>::value)
{
}
}
TestDOMJITUnrestrictedFloatAttrDOMJIT::TestDOMJITUnrestrictedFloatAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedFloatAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedFloatAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUnrestrictedFloat>::value)
{
}
}
TestDOMJITDoubleAttrDOMJIT::TestDOMJITDoubleAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITDoubleAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITDoubleAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLDouble>::value)
{
}
}
TestDOMJITUnrestrictedDoubleAttrDOMJIT::TestDOMJITUnrestrictedDoubleAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedDoubleAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecBytecodeNumber)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedDoubleAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUnrestrictedDouble>::value)
{
}
}
TestDOMJITDomStringAttrDOMJIT::TestDOMJITDomStringAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITDomStringAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecString)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITDomStringAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLDOMString>::value)
{
}
}
TestDOMJITByteStringAttrDOMJIT::TestDOMJITByteStringAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteStringAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecString)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteStringAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLByteString>::value)
{
}
}
TestDOMJITUsvStringAttrDOMJIT::TestDOMJITUsvStringAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUsvStringAttr, nullptr, JSTestDOMJIT::info(), JSC::SpecString)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUsvStringAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLUSVString>::value)
{
}
}
TestDOMJITNodeAttrDOMJIT::TestDOMJITNodeAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITNodeAttr, nullptr, JSTestDOMJIT::info(), SpecHeapTop)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITNodeAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLInterface<Node>>::value)
{
}
}
TestDOMJITBooleanNullableAttrDOMJIT::TestDOMJITBooleanNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITBooleanNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBoolean | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITBooleanNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLBoolean>>::value)
{
}
}
TestDOMJITByteNullableAttrDOMJIT::TestDOMJITByteNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecInt32Only | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLByte>>::value)
{
}
}
TestDOMJITOctetNullableAttrDOMJIT::TestDOMJITOctetNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITOctetNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecInt32Only | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITOctetNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLOctet>>::value)
{
}
}
TestDOMJITShortNullableAttrDOMJIT::TestDOMJITShortNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITShortNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecInt32Only | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITShortNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLShort>>::value)
{
}
}
TestDOMJITUnsignedShortNullableAttrDOMJIT::TestDOMJITUnsignedShortNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedShortNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecInt32Only | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedShortNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUnsignedShort>>::value)
{
}
}
TestDOMJITLongNullableAttrDOMJIT::TestDOMJITLongNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecInt32Only | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLLong>>::value)
{
}
}
TestDOMJITUnsignedLongNullableAttrDOMJIT::TestDOMJITUnsignedLongNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUnsignedLong>>::value)
{
}
}
TestDOMJITLongLongNullableAttrDOMJIT::TestDOMJITLongLongNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongLongNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITLongLongNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLLongLong>>::value)
{
}
}
TestDOMJITUnsignedLongLongNullableAttrDOMJIT::TestDOMJITUnsignedLongLongNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongLongNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnsignedLongLongNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUnsignedLongLong>>::value)
{
}
}
TestDOMJITFloatNullableAttrDOMJIT::TestDOMJITFloatNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITFloatNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITFloatNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLFloat>>::value)
{
}
}
TestDOMJITUnrestrictedFloatNullableAttrDOMJIT::TestDOMJITUnrestrictedFloatNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedFloatNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedFloatNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUnrestrictedFloat>>::value)
{
}
}
TestDOMJITDoubleNullableAttrDOMJIT::TestDOMJITDoubleNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITDoubleNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITDoubleNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLDouble>>::value)
{
}
}
TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT::TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedDoubleNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecBytecodeNumber | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUnrestrictedDoubleNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUnrestrictedDouble>>::value)
{
}
}
TestDOMJITDomStringNullableAttrDOMJIT::TestDOMJITDomStringNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITDomStringNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecString | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITDomStringNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLDOMString>>::value)
{
}
}
TestDOMJITByteStringNullableAttrDOMJIT::TestDOMJITByteStringNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteStringNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecString | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITByteStringNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLByteString>>::value)
{
}
}
TestDOMJITUsvStringNullableAttrDOMJIT::TestDOMJITUsvStringNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITUsvStringNullableAttr, nullptr, JSTestDOMJIT::info(), (JSC::SpecString | JSC::SpecOther))
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITUsvStringNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLUSVString>>::value)
{
}
}
TestDOMJITNodeNullableAttrDOMJIT::TestDOMJITNodeNullableAttrDOMJIT()
- : JSC::DOMJIT::GetterSetter(jsTestDOMJITNodeNullableAttr, nullptr, JSTestDOMJIT::info(), SpecHeapTop)
+ : JSC::DOMJIT::GetterSetter(jsTestDOMJITNodeNullableAttr, nullptr, JSTestDOMJIT::info(), DOMJIT::IDLResultTypeFilter<IDLNullable<IDLInterface<Node>>>::value)
{
}
return getDOMConstructor<JSTestDOMJITConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetAttributeCaller(JSC::ExecState*, JSTestDOMJIT*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetAttribute(ExecState* state)
+{
+ return BindingCaller<JSTestDOMJIT>::callOperation<jsTestDOMJITPrototypeFunctionGetAttributeCaller>(state, "getAttribute");
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetAttributeCaller(JSC::ExecState* state, JSTestDOMJIT* castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 1))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto name = convert<IDLDOMString>(*state, state->uncheckedArgument(0), StringConversionConfiguration::Normal);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLNullable<IDLDOMString>>(*state, impl.getAttribute(WTFMove(name)));
+ return JSValue::encode(result);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetAttribute(JSC::ExecState* state, JSTestDOMJIT* castedThis, DOMJIT::IDLJSArgumentType<IDLDOMString> encodedName)
+{
+ UNUSED_PARAM(state);
+ VM& vm = state->vm();
+ JSC::NativeCallFrameTracer tracer(&vm, state);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto name = DOMJIT::DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>(*state, encodedName);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLNullable<IDLDOMString>>(*state, impl.getAttribute(WTFMove(name)));
+ return JSValue::encode(result);
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionItemCaller(JSC::ExecState*, JSTestDOMJIT*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionItem(ExecState* state)
+{
+ return BindingCaller<JSTestDOMJIT>::callOperation<jsTestDOMJITPrototypeFunctionItemCaller>(state, "item");
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionItemCaller(JSC::ExecState* state, JSTestDOMJIT* castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 2))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto x = convert<IDLUnsignedShort>(*state, state->uncheckedArgument(0), IntegerConversionConfiguration::Normal);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ auto y = convert<IDLUnsignedShort>(*state, state->uncheckedArgument(1), IntegerConversionConfiguration::Normal);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLDOMString>(*state, impl.item(WTFMove(x), WTFMove(y)));
+ return JSValue::encode(result);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionItem(JSC::ExecState* state, JSTestDOMJIT* castedThis, DOMJIT::IDLJSArgumentType<IDLUnsignedShort> encodedX, DOMJIT::IDLJSArgumentType<IDLUnsignedShort> encodedY)
+{
+ UNUSED_PARAM(state);
+ VM& vm = state->vm();
+ JSC::NativeCallFrameTracer tracer(&vm, state);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto x = DOMJIT::DirectConverter<IDLUnsignedShort>::directConvert<IntegerConversionConfiguration::Normal>(*state, encodedX);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ auto y = DOMJIT::DirectConverter<IDLUnsignedShort>::directConvert<IntegerConversionConfiguration::Normal>(*state, encodedY);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLDOMString>(*state, impl.item(WTFMove(x), WTFMove(y)));
+ return JSValue::encode(result);
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionHasAttributeCaller(JSC::ExecState*, JSTestDOMJIT*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionHasAttribute(ExecState* state)
+{
+ return BindingCaller<JSTestDOMJIT>::callOperation<jsTestDOMJITPrototypeFunctionHasAttributeCaller>(state, "hasAttribute");
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionHasAttributeCaller(JSC::ExecState* state, JSTestDOMJIT* castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ JSValue result = toJS<IDLBoolean>(impl.hasAttribute());
+ return JSValue::encode(result);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionHasAttribute(JSC::ExecState* state, JSTestDOMJIT* castedThis)
+{
+ UNUSED_PARAM(state);
+ VM& vm = state->vm();
+ JSC::NativeCallFrameTracer tracer(&vm, state);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ JSValue result = toJS<IDLBoolean>(impl.hasAttribute());
+ return JSValue::encode(result);
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetElementByIdCaller(JSC::ExecState*, JSTestDOMJIT*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetElementById(ExecState* state)
+{
+ return BindingCaller<JSTestDOMJIT>::callOperation<jsTestDOMJITPrototypeFunctionGetElementByIdCaller>(state, "getElementById");
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetElementByIdCaller(JSC::ExecState* state, JSTestDOMJIT* castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 1))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto elementId = AtomicString(state->uncheckedArgument(0).toString(state)->toExistingAtomicString(state));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLInterface<Element>>(*state, *castedThis->globalObject(), impl.getElementById(WTFMove(elementId)));
+ return JSValue::encode(result);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetElementById(JSC::ExecState* state, JSTestDOMJIT* castedThis, DOMJIT::IDLJSArgumentType<IDLDOMString> encodedElementId)
+{
+ UNUSED_PARAM(state);
+ VM& vm = state->vm();
+ JSC::NativeCallFrameTracer tracer(&vm, state);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto elementId = AtomicString(encodedElementId->toExistingAtomicString(state));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLInterface<Element>>(*state, *castedThis->globalObject(), impl.getElementById(WTFMove(elementId)));
+ return JSValue::encode(result);
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetElementsByNameCaller(JSC::ExecState*, JSTestDOMJIT*, JSC::ThrowScope&);
+
+EncodedJSValue JSC_HOST_CALL jsTestDOMJITPrototypeFunctionGetElementsByName(ExecState* state)
+{
+ return BindingCaller<JSTestDOMJIT>::callOperation<jsTestDOMJITPrototypeFunctionGetElementsByNameCaller>(state, "getElementsByName");
+}
+
+static inline JSC::EncodedJSValue jsTestDOMJITPrototypeFunctionGetElementsByNameCaller(JSC::ExecState* state, JSTestDOMJIT* castedThis, JSC::ThrowScope& throwScope)
+{
+ UNUSED_PARAM(state);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ if (UNLIKELY(state->argumentCount() < 1))
+ return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
+ auto elementName = state->uncheckedArgument(0).toString(state)->toAtomicString(state);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLInterface<NodeList>>(*state, *castedThis->globalObject(), impl.getElementsByName(WTFMove(elementName)));
+ return JSValue::encode(result);
+}
+
+JSC::EncodedJSValue JSC_HOST_CALL unsafeJsTestDOMJITPrototypeFunctionGetElementsByName(JSC::ExecState* state, JSTestDOMJIT* castedThis, DOMJIT::IDLJSArgumentType<IDLDOMString> encodedElementName)
+{
+ UNUSED_PARAM(state);
+ VM& vm = state->vm();
+ JSC::NativeCallFrameTracer tracer(&vm, state);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ UNUSED_PARAM(throwScope);
+ auto& impl = castedThis->wrapped();
+ auto elementName = encodedElementName->toAtomicString(state);
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+ JSValue result = toJS<IDLInterface<NodeList>>(*state, *castedThis->globalObject(), impl.getElementsByName(WTFMove(elementName)));
+ return JSValue::encode(result);
+}
+
void JSTestDOMJIT::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
auto* thisObject = jsCast<JSTestDOMJIT*>(cell);
[DOMJIT] readonly attribute ByteString? byteStringNullableAttr;
[DOMJIT] readonly attribute USVString? usvStringNullableAttr;
[DOMJIT] readonly attribute Node? nodeNullableAttr;
+
+ [DOMJIT=ReadDOM] DOMString? getAttribute(DOMString name);
+ [DOMJIT=ReadDOM] DOMString item(unsigned short x, unsigned short y);
+ [DOMJIT=ReadDOM] boolean hasAttribute();
+ [DOMJIT=ReadDOM] Element getElementById([RequiresExistingAtomicString] DOMString elementId);
+ [DOMJIT=ReadDOM] NodeList getElementsByName([AtomicString] DOMString elementName);
};
] interface Element : Node {
readonly attribute DOMString? tagName;
- DOMString? getAttribute(DOMString name);
+ [DOMJIT=ReadDOM] DOMString? getAttribute(DOMString name);
[CEReactions, MayThrowException] void setAttribute(DOMString name, DOMString value);
[CEReactions] void removeAttribute(DOMString name);
- Attr? getAttributeNode(DOMString name);
+ [DOMJIT=ReadDOM] Attr? getAttributeNode(DOMString name);
[CEReactions, MayThrowException] Attr? setAttributeNode(Attr newAttr);
[CEReactions, MayThrowException] Attr removeAttributeNode(Attr oldAttr);
- HTMLCollection getElementsByTagName(DOMString name);
+ [DOMJIT=ReadDOM] HTMLCollection getElementsByTagName(DOMString name);
readonly attribute NamedNodeMap attributes;
- boolean hasAttributes();
+ [DOMJIT=ReadDOM] boolean hasAttributes();
DOMString? getAttributeNS(DOMString? namespaceURI, DOMString localName);
--- /dev/null
+DOM:
+ Tree:
+ Node:
+ - Node_firstChild
+ - Node_lastChild
+ - Node_parentNode
+ - Node_nextSibling
+ - Node_previousSibling
+ - Node_ownerDocument
+ Document:
+ - Document_documentElement
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include <bytecode/SpeculatedType.h>
+#include <domjit/DOMJITSignature.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct DirectConverter;
+
+template<>
+struct DirectConverter<IDLDOMString> {
+ template<StringConversionConfiguration>
+ static String directConvert(JSC::ExecState&, JSC::JSString*);
+};
+
+template<>
+inline String DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>(JSC::ExecState& state, JSC::JSString* string)
+{
+ return string->value(&state);
+}
+
+} }
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "IDLTypes.h"
+#include <bytecode/SpeculatedType.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct IDLJSArgumentTypeSelect;
+
+template<> struct IDLJSArgumentTypeSelect<IDLBoolean> { typedef bool type; };
+template<> struct IDLJSArgumentTypeSelect<IDLByte> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLOctet> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLShort> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLUnsignedShort> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLLong> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLDOMString> { typedef JSC::JSString* type; };
+
+template<typename IDLType>
+using IDLJSArgumentType = typename IDLJSArgumentTypeSelect<IDLType>::type;
+
+} }
--- /dev/null
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <bytecode/SpeculatedType.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct IDLArgumentTypeFilter;
+
+template<> struct IDLArgumentTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; };
+template<> struct IDLArgumentTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+
+template<typename IDLType>
+struct IDLResultTypeFilter {
+ static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop;
+};
+
+template<> struct IDLResultTypeFilter<IDLAny> { static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop; };
+template<> struct IDLResultTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; };
+template<> struct IDLResultTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLUnsignedLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnsignedLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnrestrictedFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnrestrictedDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+template<> struct IDLResultTypeFilter<IDLByteString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+template<> struct IDLResultTypeFilter<IDLUSVString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+
+template<typename T>
+struct IDLResultTypeFilter<IDLNullable<T>> {
+ static const constexpr JSC::SpeculatedType value = JSC::SpecOther | IDLResultTypeFilter<T>::value;
+};
+
+} }
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentDocumentElementDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
patchpoint->numGPScratchRegisters = 1;
patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
return CCallHelpers::JumpList();
});
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Document_documentElement);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_documentElement);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeFirstChildDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::firstChildMemoryOffset(), IsContainerGuardRequirement::Required);
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_firstChild);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_firstChild);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeLastChildDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::lastChildMemoryOffset(), IsContainerGuardRequirement::Required);
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_lastChild);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_lastChild);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeNextSiblingDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::nextSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_nextSibling);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_nextSibling);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodePreviousSiblingDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::previousSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_previousSibling);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_previousSibling);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeParentNodeDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
auto patchpoint = createCallDOMGetterForOffsetAccess<ContainerNode>(Node::parentNodeMemoryOffset(), IsContainerGuardRequirement::NotRequired);
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_parentNode);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_parentNode);
return patchpoint;
}
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeOwnerDocumentDOMJIT::callDOMGetter()
{
- const auto& heap = DOMJIT::AbstractHeapRepository::shared();
Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
patchpoint->numGPScratchRegisters = 1;
patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
done.link(&jit);
return CCallHelpers::JumpList();
});
- patchpoint->effect = JSC::DOMJIT::Effect::forDef(heap.Node_ownerDocument);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_ownerDocument);
return patchpoint;
}
--- /dev/null
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+# Copyright (C) 2016 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+require "yaml"
+
+class HeapRange
+ attr_reader :first, :last
+ def initialize(first, last)
+ @first = first
+ @last = last
+ end
+end
+
+class AbstractHeap
+ attr_reader :range, :name, :parent
+ def initialize(name, tree)
+ @name = name
+ @parent = nil
+ if tree.nil?
+ @children = []
+ else
+ @children = tree.map {|key, value| AbstractHeap.new(key, value) }
+ end
+ @range = nil
+ end
+
+ def setParent(parent)
+ parent.children.push(self)
+ @parent = parent
+ end
+
+ def compute(start)
+ current = start
+ if @children.empty?
+ @range = HeapRange.new(start, current + 1)
+ return
+ end
+
+ @children.each {|child|
+ child.compute(current)
+ current = child.range.last
+ }
+
+ @range = HeapRange.new(start, current)
+ end
+
+ def dump output
+ shallowDump(output)
+ if @parent
+ output.print "-> "
+ @parent.dump(output)
+ end
+ end
+
+ def shallowDump(output)
+ output.print "#{@name}<#{@range.first},#{@range.last}>"
+ end
+
+ def deepDump output, indent
+ printIndent(output, indent)
+ shallowDump(output)
+ if @children.empty?
+ output.print "\n"
+ return
+ end
+
+ output.print ":\n"
+ @children.each {|child|
+ child.deepDump(output, indent + 1)
+ }
+ end
+
+ def generate output
+ output.puts "constexpr JSC::DOMJIT::HeapRange #{@name}(JSC::DOMJIT::HeapRange::ConstExpr, #{@range.first}, #{@range.last});"
+ @children.each {|child|
+ child.generate(output)
+ }
+ end
+
+private
+ def printIndent output, indent
+ indent.times {
+ output.print " "
+ }
+ end
+end
+
+header = <<-EOS
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+// Auto-generated file. Do not modify.
+
+#pragma once
+
+#include <domjit/DOMJITHeapRange.h>
+
+namespace WebCore { namespace DOMJIT { namespace AbstractHeapRepository {
+EOS
+
+footer = <<-EOS
+} } }
+EOS
+
+$inputFileName = ARGV.shift
+$outputFileName = ARGV.shift
+File.open($outputFileName, "w") {|output|
+ File.open($inputFileName, "rb") {|file|
+ tree = YAML::load(file.read())
+ heap = tree.map {|key, value|
+ AbstractHeap.new(key, value)
+ }.first
+ heap.compute(0)
+
+ output.print(header)
+ output.puts("/* DOMJIT Abstract Heap Tree.")
+ heap.deepDump(output, 0)
+ output.puts("*/")
+ heap.generate(output)
+ output.print(footer)
+ }
+}