Title: [206778] trunk/Source/_javascript_Core
Revision
206778
Author
utatane....@gmail.com
Date
2016-10-04 12:31:24 -0700 (Tue, 04 Oct 2016)

Log Message

[JSC] Add a new byte code op_define_property instead of calling defineProperty
https://bugs.webkit.org/show_bug.cgi?id=162108

Reviewed by Saam Barati.

To construct ES6 class, we emitted bytecode that performs the following operations.

    1. construct a new object
    2. put "configurable", "enumerable" etc. fields
    3. call "defineProperty" function

However, this approach has problems. Every time we define a class method, we need to create
a new object to represent property descriptor. This can be removed if we can introduce
a special bytecode or special function.

This patch introduces new bytecodes, op_define_data_property and op_define_accessor_property.
Instead of taking an object, they takes several registers to avoid object allocations.
We're planning to use this bytecode to implement Object.defineProperty in builtin JS next.
This allows us to leverage object allocation sinking. And it also gives us a chance to use
faster ::get and ::hasProperty in JS.

Originally, I attempted to create one bytecode, op_define_property. However, it takes too many
children in DFG and uses so many registers in DFG. This leads tricky program in 32bit platforms.
Furthermore, it does not fit to the number of x64 argument registers. So instead, we introduce
two bytecodes.

And for op_define_accessor_property, we perform CellUse edge filter to getter and setter children.
This edge filter makes us possible to use SpeculateCellOperand and reduce the number of used registers
in comparison with JSValueOperand. To make children Cells even if we do not specify some accessors (for
example, { get: func, set: null } case), we fill registers with special throwTypeErrorFunction.
The attributes bitset keep information like "This property descriptor only has getter slot".

In these two bytecodes, we take attributes (configurable, enumerable, writable, hasGetter etc.) as
register instead of embedding constant int value because we will use these bytecodes to implement
Object.defineProperty next. In Object.defineProperty case, an attributes are not statically defined
at bytecode compiling time.

Run ES6SampleBench/Air 20 times. The result shows ~2% performance improvement.

Baseline:
    firstIteration:     84.05 ms +- 4.37 ms
    averageWorstCase:   40.54 ms +- 2.81 ms
    steadyState:        3317.49 ms +- 48.25 ms
    summary:            223.51 ms +- 5.07 ms

Patched:
    firstIteration:     84.46 ms +- 4.22 ms
    averageWorstCase:   41.48 ms +- 2.33 ms
    steadyState:        3253.48 ms +- 29.31 ms
    summary:            224.40 ms +- 4.72 ms

* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
* bytecode/SpecialPointer.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitMoveLinkTimeConstant):
(JSC::BytecodeGenerator::emitCallDefineProperty):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::PropertyListNode::emitPutConstantProperty):
(JSC::BitwiseNotNode::emitBytecode):
(JSC::ClassExprNode::emitBytecode):
(JSC::ObjectPatternNode::bindValue):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
* dfg/DFGPredictionPropagationPhase.cpp:
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileDefineDataProperty):
(JSC::DFG::SpeculativeJIT::compileDefineAccessorProperty):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileDefineDataProperty):
(JSC::FTL::DFG::LowerDFGToB3::compileDefineAccessorProperty):
(JSC::FTL::DFG::LowerDFGToB3::compilePutByValWithThis): Deleted.
* jit/CCallHelpers.cpp:
(JSC::CCallHelpers::setupFourStubArgsGPR): Deleted.
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupFourStubArgsGPR):
(JSC::CCallHelpers::setupFiveStubArgsGPR):
(JSC::CCallHelpers::setupArgumentsWithExecState):
(JSC::CCallHelpers::setupStubArgsGPR):
(JSC::CCallHelpers::prepareForTailCallSlow): Deleted.
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITOperations.h:
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emit_op_define_data_property):
(JSC::JIT::emit_op_define_accessor_property):
* llint/LowLevelInterpreter.asm:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/CommonSlowPaths.h:
* runtime/DefinePropertyAttributes.h: Added.
(JSC::DefinePropertyAttributes::DefinePropertyAttributes):
(JSC::DefinePropertyAttributes::rawRepresentation):
(JSC::DefinePropertyAttributes::hasValue):
(JSC::DefinePropertyAttributes::setValue):
(JSC::DefinePropertyAttributes::hasGet):
(JSC::DefinePropertyAttributes::setGet):
(JSC::DefinePropertyAttributes::hasSet):
(JSC::DefinePropertyAttributes::setSet):
(JSC::DefinePropertyAttributes::writable):
(JSC::DefinePropertyAttributes::configurable):
(JSC::DefinePropertyAttributes::enumerable):
(JSC::DefinePropertyAttributes::setWritable):
(JSC::DefinePropertyAttributes::setConfigurable):
(JSC::DefinePropertyAttributes::setEnumerable):
(JSC::DefinePropertyAttributes::fillWithTriState):
(JSC::DefinePropertyAttributes::extractTriState):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::throwTypeErrorFunction):
(JSC::JSGlobalObject::definePropertyFunction): Deleted.
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructor::addDefineProperty): Deleted.
* runtime/ObjectConstructor.h:
* runtime/PropertyDescriptor.h:
(JSC::toPropertyDescriptor):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (206777 => 206778)


--- trunk/Source/_javascript_Core/ChangeLog	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1,3 +1,155 @@
+2016-09-27  Yusuke Suzuki  <utatane....@gmail.com>
+
+        [JSC] Add a new byte code op_define_property instead of calling defineProperty
+        https://bugs.webkit.org/show_bug.cgi?id=162108
+
+        Reviewed by Saam Barati.
+
+        To construct ES6 class, we emitted bytecode that performs the following operations.
+
+            1. construct a new object
+            2. put "configurable", "enumerable" etc. fields
+            3. call "defineProperty" function
+
+        However, this approach has problems. Every time we define a class method, we need to create
+        a new object to represent property descriptor. This can be removed if we can introduce
+        a special bytecode or special function.
+
+        This patch introduces new bytecodes, op_define_data_property and op_define_accessor_property.
+        Instead of taking an object, they takes several registers to avoid object allocations.
+        We're planning to use this bytecode to implement Object.defineProperty in builtin JS next.
+        This allows us to leverage object allocation sinking. And it also gives us a chance to use
+        faster ::get and ::hasProperty in JS.
+
+        Originally, I attempted to create one bytecode, op_define_property. However, it takes too many
+        children in DFG and uses so many registers in DFG. This leads tricky program in 32bit platforms.
+        Furthermore, it does not fit to the number of x64 argument registers. So instead, we introduce
+        two bytecodes.
+
+        And for op_define_accessor_property, we perform CellUse edge filter to getter and setter children.
+        This edge filter makes us possible to use SpeculateCellOperand and reduce the number of used registers
+        in comparison with JSValueOperand. To make children Cells even if we do not specify some accessors (for
+        example, { get: func, set: null } case), we fill registers with special throwTypeErrorFunction.
+        The attributes bitset keep information like "This property descriptor only has getter slot".
+
+        In these two bytecodes, we take attributes (configurable, enumerable, writable, hasGetter etc.) as
+        register instead of embedding constant int value because we will use these bytecodes to implement
+        Object.defineProperty next. In Object.defineProperty case, an attributes are not statically defined
+        at bytecode compiling time.
+
+        Run ES6SampleBench/Air 20 times. The result shows ~2% performance improvement.
+
+        Baseline:
+            firstIteration:     84.05 ms +- 4.37 ms
+            averageWorstCase:   40.54 ms +- 2.81 ms
+            steadyState:        3317.49 ms +- 48.25 ms
+            summary:            223.51 ms +- 5.07 ms
+
+        Patched:
+            firstIteration:     84.46 ms +- 4.22 ms
+            averageWorstCase:   41.48 ms +- 2.33 ms
+            steadyState:        3253.48 ms +- 29.31 ms
+            summary:            224.40 ms +- 4.72 ms
+
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        * bytecode/SpecialPointer.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitMoveLinkTimeConstant):
+        (JSC::BytecodeGenerator::emitCallDefineProperty):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PropertyListNode::emitPutConstantProperty):
+        (JSC::BitwiseNotNode::emitBytecode):
+        (JSC::ClassExprNode::emitBytecode):
+        (JSC::ObjectPatternNode::bindValue):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGOperations.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileDefineDataProperty):
+        (JSC::DFG::SpeculativeJIT::compileDefineAccessorProperty):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileDefineDataProperty):
+        (JSC::FTL::DFG::LowerDFGToB3::compileDefineAccessorProperty):
+        (JSC::FTL::DFG::LowerDFGToB3::compilePutByValWithThis): Deleted.
+        * jit/CCallHelpers.cpp:
+        (JSC::CCallHelpers::setupFourStubArgsGPR): Deleted.
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupFourStubArgsGPR):
+        (JSC::CCallHelpers::setupFiveStubArgsGPR):
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        (JSC::CCallHelpers::setupStubArgsGPR):
+        (JSC::CCallHelpers::prepareForTailCallSlow): Deleted.
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITOperations.h:
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emit_op_define_data_property):
+        (JSC::JIT::emit_op_define_accessor_property):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/CommonSlowPaths.h:
+        * runtime/DefinePropertyAttributes.h: Added.
+        (JSC::DefinePropertyAttributes::DefinePropertyAttributes):
+        (JSC::DefinePropertyAttributes::rawRepresentation):
+        (JSC::DefinePropertyAttributes::hasValue):
+        (JSC::DefinePropertyAttributes::setValue):
+        (JSC::DefinePropertyAttributes::hasGet):
+        (JSC::DefinePropertyAttributes::setGet):
+        (JSC::DefinePropertyAttributes::hasSet):
+        (JSC::DefinePropertyAttributes::setSet):
+        (JSC::DefinePropertyAttributes::writable):
+        (JSC::DefinePropertyAttributes::configurable):
+        (JSC::DefinePropertyAttributes::enumerable):
+        (JSC::DefinePropertyAttributes::setWritable):
+        (JSC::DefinePropertyAttributes::setConfigurable):
+        (JSC::DefinePropertyAttributes::setEnumerable):
+        (JSC::DefinePropertyAttributes::fillWithTriState):
+        (JSC::DefinePropertyAttributes::extractTriState):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::throwTypeErrorFunction):
+        (JSC::JSGlobalObject::definePropertyFunction): Deleted.
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::addDefineProperty): Deleted.
+        * runtime/ObjectConstructor.h:
+        * runtime/PropertyDescriptor.h:
+        (JSC::toPropertyDescriptor):
+
 2016-10-04  Saam Barati  <sbar...@apple.com>
 
         Follow up fix to GetMapBucket and MapHash speculating on child node types.

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (206777 => 206778)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-10-04 19:31:24 UTC (rev 206778)
@@ -2178,6 +2178,7 @@
 		FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
 		FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 169948EDE68D4054B01EF797 /* DefinePropertyAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -4518,6 +4519,7 @@
 		FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
 		FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
 		FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
+		169948EDE68D4054B01EF797 /* DefinePropertyAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DefinePropertyAttributes.h; path = DefinePropertyAttributes.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -6269,6 +6271,7 @@
 				709FB8661AE335C60039D069 /* WeakSetPrototype.h */,
 				A7DCB77912E3D90500911940 /* WriteBarrier.h */,
 				C2B6D75218A33793004A9301 /* WriteBarrierInlines.h */,
+				169948EDE68D4054B01EF797 /* DefinePropertyAttributes.h */,
 			);
 			path = runtime;
 			sourceTree = "<group>";
@@ -8412,6 +8415,7 @@
 				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
 				A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
 				D9722752DC54459B9125B539 /* JSModuleLoader.h in Headers */,
+				473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.json (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecode/BytecodeList.json	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.json	2016-10-04 19:31:24 UTC (rev 206778)
@@ -81,6 +81,8 @@
             { "name" : "op_put_getter_setter_by_id", "length" : 6 },
             { "name" : "op_put_getter_by_val", "length" : 5 },
             { "name" : "op_put_setter_by_val", "length" : 5 },
+            { "name" : "op_define_data_property", "length" : 5 },
+            { "name" : "op_define_accessor_property", "length" : 6 },
             { "name" : "op_jmp", "length" : 2 },
             { "name" : "op_jtrue", "length" : 3 },
             { "name" : "op_jfalse", "length" : 3 },

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -143,6 +143,23 @@
         functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
         return;
     }
+    case op_define_data_property: {
+        ASSERT(opcodeLengths[opcodeID] > 4);
+        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
+        return;
+    }
+    case op_define_accessor_property: {
+        ASSERT(opcodeLengths[opcodeID] > 5);
+        functor(codeBlock, instruction, opcodeID, instruction[1].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[2].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[3].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[4].u.operand);
+        functor(codeBlock, instruction, opcodeID, instruction[5].u.operand);
+        return;
+    }
     case op_get_property_enumerator:
     case op_get_enumerable_length:
     case op_new_func_exp:
@@ -331,6 +348,8 @@
     case op_put_by_val:
     case op_put_by_val_direct:
     case op_put_by_index:
+    case op_define_data_property:
+    case op_define_accessor_property:
     case op_profile_type:
     case op_profile_control_flow:
     case op_put_to_arguments:

Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1235,6 +1235,25 @@
             out.printf("%s, %s, %d, %s", registerName(r0).data(), registerName(r1).data(), n0, registerName(r2).data());
             break;
         }
+        case op_define_data_property: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int r2 = (++it)->u.operand;
+            int r3 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "define_data_property");
+            out.printf("%s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data());
+            break;
+        }
+        case op_define_accessor_property: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int r2 = (++it)->u.operand;
+            int r3 = (++it)->u.operand;
+            int r4 = (++it)->u.operand;
+            printLocationAndOp(out, exec, location, it, "define_accessor_property");
+            out.printf("%s, %s, %s, %s, %s", registerName(r0).data(), registerName(r1).data(), registerName(r2).data(), registerName(r3).data(), registerName(r4).data());
+            break;
+        }
         case op_del_by_id: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;

Modified: trunk/Source/_javascript_Core/bytecode/SpecialPointer.h (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecode/SpecialPointer.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecode/SpecialPointer.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -41,7 +41,7 @@
 } // namespace Special
 
 enum class LinkTimeConstant {
-    DefinePropertyFunction,
+    ThrowTypeErrorFunction,
 };
 const unsigned LinkTimeConstantCount = 1;
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -35,6 +35,7 @@
 #include "BuiltinExecutables.h"
 #include "BytecodeGeneratorification.h"
 #include "BytecodeLivenessAnalysis.h"
+#include "DefinePropertyAttributes.h"
 #include "Interpreter.h"
 #include "JSFunction.h"
 #include "JSGeneratorFunction.h"
@@ -1543,6 +1544,9 @@
         m_linkTimeConstantRegisters[constantIndex] = &m_constantPoolRegisters[index];
     }
 
+    if (!dst)
+        return m_linkTimeConstantRegisters[constantIndex];
+
     emitOpcode(op_mov);
     instructions().append(dst->index());
     instructions().append(m_linkTimeConstantRegisters[constantIndex]->index());
@@ -3274,38 +3278,59 @@
 }
 
 void BytecodeGenerator::emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
-    RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition& position)
+    RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options)
 {
-    RefPtr<RegisterID> descriptorRegister = emitNewObject(newTemporary());
+    DefinePropertyAttributes attributes;
+    if (options & PropertyConfigurable)
+        attributes.setConfigurable(true);
 
-    RefPtr<RegisterID> trueRegister = emitLoad(newTemporary(), true);
-    if (options & PropertyConfigurable)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().configurable, trueRegister.get(), PropertyNode::Unknown);
     if (options & PropertyWritable)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().writable, trueRegister.get(), PropertyNode::Unknown);
-    else if (valueRegister) {
-        RefPtr<RegisterID> falseRegister = emitLoad(newTemporary(), false);
-        emitDirectPutById(descriptorRegister.get(), propertyNames().writable, falseRegister.get(), PropertyNode::Unknown);
-    }
+        attributes.setWritable(true);
+    else if (valueRegister)
+        attributes.setWritable(false);
+
     if (options & PropertyEnumerable)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().enumerable, trueRegister.get(), PropertyNode::Unknown);
+        attributes.setEnumerable(true);
 
     if (valueRegister)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().value, valueRegister, PropertyNode::Unknown);
+        attributes.setValue();
     if (getterRegister)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().get, getterRegister, PropertyNode::Unknown);
+        attributes.setGet();
     if (setterRegister)
-        emitDirectPutById(descriptorRegister.get(), propertyNames().set, setterRegister, PropertyNode::Unknown);
+        attributes.setSet();
 
-    RefPtr<RegisterID> definePropertyRegister = emitMoveLinkTimeConstant(newTemporary(), LinkTimeConstant::DefinePropertyFunction);
+    ASSERT(!valueRegister || (!getterRegister && !setterRegister));
 
-    CallArguments callArguments(*this, nullptr, 3);
-    emitLoad(callArguments.thisRegister(), jsUndefined());
-    emitMove(callArguments.argumentRegister(0), newObj);
-    emitMove(callArguments.argumentRegister(1), propertyNameRegister);
-    emitMove(callArguments.argumentRegister(2), descriptorRegister.get());
+    if (attributes.hasGet() || attributes.hasSet()) {
+        RefPtr<RegisterID> throwTypeErrorFunction;
+        if (!attributes.hasGet() || !attributes.hasSet())
+            throwTypeErrorFunction = emitMoveLinkTimeConstant(nullptr, LinkTimeConstant::ThrowTypeErrorFunction);
 
-    emitCall(newTemporary(), definePropertyRegister.get(), NoExpectedFunction, callArguments, position, position, position, DebuggableCall::No);
+        RefPtr<RegisterID> getter;
+        if (attributes.hasGet())
+            getter = getterRegister;
+        else
+            getter = throwTypeErrorFunction;
+
+        RefPtr<RegisterID> setter;
+        if (attributes.hasSet())
+            setter = setterRegister;
+        else
+            setter = throwTypeErrorFunction;
+
+        emitOpcode(op_define_accessor_property);
+        instructions().append(newObj->index());
+        instructions().append(propertyNameRegister->index());
+        instructions().append(getter->index());
+        instructions().append(setter->index());
+        instructions().append(emitLoad(nullptr, jsNumber(attributes.rawRepresentation()))->index());
+    } else {
+        emitOpcode(op_define_data_property);
+        instructions().append(newObj->index());
+        instructions().append(propertyNameRegister->index());
+        instructions().append(valueRegister->index());
+        instructions().append(emitLoad(nullptr, jsNumber(attributes.rawRepresentation()))->index());
+    }
 }
 
 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -588,7 +588,7 @@
             PropertyEnumerable   = 1 << 2,
         };
         void emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
-            RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&);
+            RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options);
 
         void emitEnumeration(ThrowableExpressionData* enumerationNode, ExpressionNode* subjectNode, const std::function<void(BytecodeGenerator&, RegisterID*)>& callBack, ForOfNode* = nullptr, RegisterID* forLoopSymbolTable = nullptr);
 

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -590,12 +590,12 @@
         ASSERT(node.needsSuperBinding());
         RefPtr<RegisterID> propertyNameRegister;
         if (node.name())
-            propertyNameRegister = generator.emitLoad(generator.newTemporary(), *node.name());
+            propertyNameRegister = generator.emitLoad(nullptr, *node.name());
         else
             propertyNameRegister = generator.emitNode(node.m_expression);
 
         generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyNameRegister.get());
-        generator.emitCallDefineProperty(newObj, propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
+        generator.emitCallDefineProperty(newObj, propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable);
         return;
     }
     if (const auto* identifier = node.name()) {
@@ -605,7 +605,7 @@
             return;
         }
 
-        RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
+        RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
         generator.emitDirectPutByVal(newObj, index.get(), value.get());
         return;
     }
@@ -1623,7 +1623,7 @@
  
 RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
+    RefPtr<RegisterID> src2 = generator.emitLoad(nullptr, jsNumber(-1));
     RefPtr<RegisterID> src1 = generator.emitNode(m_expr);
     return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1.get()), src1.get(), src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
 }
@@ -3609,12 +3609,12 @@
         emitPutHomeObject(generator, constructor.get(), prototype.get());
     }
 
-    RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.constructor);
+    RefPtr<RegisterID> constructorNameRegister = generator.emitLoad(nullptr, propertyNames.constructor);
     generator.emitCallDefineProperty(prototype.get(), constructorNameRegister.get(), constructor.get(), nullptr, nullptr,
-        BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
+        BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable);
 
-    RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(generator.newTemporary(), propertyNames.prototype);
-    generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0, m_position);
+    RefPtr<RegisterID> prototypeNameRegister = generator.emitLoad(nullptr, propertyNames.prototype);
+    generator.emitCallDefineProperty(constructor.get(), prototypeNameRegister.get(), prototype.get(), nullptr, nullptr, 0);
 
     if (m_staticMethods)
         generator.emitNode(constructor.get(), m_staticMethods);
@@ -3876,7 +3876,7 @@
             if (!optionalIndex)
                 generator.emitGetById(temp.get(), rhs, target.propertyName);
             else {
-                RefPtr<RegisterID> index = generator.emitLoad(generator.newTemporary(), jsNumber(optionalIndex.value()));
+                RefPtr<RegisterID> index = generator.emitLoad(nullptr, jsNumber(optionalIndex.value()));
                 generator.emitGetByVal(temp.get(), rhs, index.get());
             }
         } else {

Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -2656,6 +2656,11 @@
         clobberWorld(node->origin.semantic, clobberLimit);
         break;
     }
+
+    case DefineDataProperty:
+    case DefineAccessorProperty:
+        clobberWorld(node->origin.semantic, clobberLimit);
+        break;
         
     case In: {
         // FIXME: We can determine when the property definitely exists based on abstract

Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -4238,6 +4238,38 @@
             NEXT_OPCODE(op_put_by_val_with_this);
         }
 
+        case op_define_data_property: {
+            Node* base = get(VirtualRegister(currentInstruction[1].u.operand));
+            Node* property = get(VirtualRegister(currentInstruction[2].u.operand));
+            Node* value = get(VirtualRegister(currentInstruction[3].u.operand));
+            Node* attributes = get(VirtualRegister(currentInstruction[4].u.operand));
+
+            addVarArgChild(base);
+            addVarArgChild(property);
+            addVarArgChild(value);
+            addVarArgChild(attributes);
+            addToGraph(Node::VarArg, DefineDataProperty, OpInfo(0), OpInfo(0));
+
+            NEXT_OPCODE(op_define_data_property);
+        }
+
+        case op_define_accessor_property: {
+            Node* base = get(VirtualRegister(currentInstruction[1].u.operand));
+            Node* property = get(VirtualRegister(currentInstruction[2].u.operand));
+            Node* getter = get(VirtualRegister(currentInstruction[3].u.operand));
+            Node* setter = get(VirtualRegister(currentInstruction[4].u.operand));
+            Node* attributes = get(VirtualRegister(currentInstruction[5].u.operand));
+
+            addVarArgChild(base);
+            addVarArgChild(property);
+            addVarArgChild(getter);
+            addVarArgChild(setter);
+            addVarArgChild(attributes);
+            addToGraph(Node::VarArg, DefineAccessorProperty, OpInfo(0), OpInfo(0));
+
+            NEXT_OPCODE(op_define_accessor_property);
+        }
+
         case op_try_get_by_id:
         case op_get_by_id:
         case op_get_by_id_proto_load:

Modified: trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGCapabilities.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -173,6 +173,8 @@
     case op_put_getter_setter_by_id:
     case op_put_getter_by_val:
     case op_put_setter_by_val:
+    case op_define_data_property:
+    case op_define_accessor_property:
     case op_del_by_id:
     case op_del_by_val:
     case op_jmp:

Modified: trunk/Source/_javascript_Core/dfg/DFGClobberize.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGClobberize.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -494,6 +494,8 @@
     case PutGetterSetterById:
     case PutGetterByVal:
     case PutSetterByVal:
+    case DefineDataProperty:
+    case DefineAccessorProperty:
     case DeleteById:
     case DeleteByVal:
     case ArrayPush:

Modified: trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGDoesGC.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -111,6 +111,8 @@
     case PutGetterSetterById:
     case PutGetterByVal:
     case PutSetterByVal:
+    case DefineDataProperty:
+    case DefineAccessorProperty:
     case DeleteById:
     case DeleteByVal:
     case CheckStructure:

Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1657,6 +1657,39 @@
             break;
         }
 
+        case DefineDataProperty: {
+            fixEdge<CellUse>(m_graph.varArgChild(node, 0));
+            Edge& propertyEdge = m_graph.varArgChild(node, 1);
+            if (propertyEdge->shouldSpeculateSymbol())
+                fixEdge<SymbolUse>(propertyEdge);
+            else if (propertyEdge->shouldSpeculateStringIdent())
+                fixEdge<StringIdentUse>(propertyEdge);
+            else if (propertyEdge->shouldSpeculateString())
+                fixEdge<StringUse>(propertyEdge);
+            else
+                fixEdge<UntypedUse>(propertyEdge);
+            fixEdge<UntypedUse>(m_graph.varArgChild(node, 2));
+            fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 3));
+            break;
+        }
+
+        case DefineAccessorProperty: {
+            fixEdge<CellUse>(m_graph.varArgChild(node, 0));
+            Edge& propertyEdge = m_graph.varArgChild(node, 1);
+            if (propertyEdge->shouldSpeculateSymbol())
+                fixEdge<SymbolUse>(propertyEdge);
+            else if (propertyEdge->shouldSpeculateStringIdent())
+                fixEdge<StringIdentUse>(propertyEdge);
+            else if (propertyEdge->shouldSpeculateString())
+                fixEdge<StringUse>(propertyEdge);
+            else
+                fixEdge<UntypedUse>(propertyEdge);
+            fixEdge<CellUse>(m_graph.varArgChild(node, 2));
+            fixEdge<CellUse>(m_graph.varArgChild(node, 3));
+            fixEdge<KnownInt32Use>(m_graph.varArgChild(node, 4));
+            break;
+        }
+
 #if !ASSERT_DISABLED
         // Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
         case SetArgument:
@@ -1726,8 +1759,6 @@
         case GetByValWithThis:
         case CompareEqPtr:
             break;
-            
-            break;
 #else
         default:
             break;

Modified: trunk/Source/_javascript_Core/dfg/DFGNodeType.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGNodeType.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -198,6 +198,8 @@
     macro(PutGetterSetterById, NodeMustGenerate) \
     macro(PutGetterByVal, NodeMustGenerate) \
     macro(PutSetterByVal, NodeMustGenerate) \
+    macro(DefineDataProperty, NodeMustGenerate | NodeHasVarArgs) \
+    macro(DefineAccessorProperty, NodeMustGenerate | NodeHasVarArgs) \
     macro(DeleteById, NodeResultBoolean | NodeMustGenerate) \
     macro(DeleteByVal, NodeResultBoolean | NodeMustGenerate) \
     macro(CheckStructure, NodeMustGenerate) \

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -38,6 +38,7 @@
 #include "DFGToFTLDeferredCompilationCallback.h"
 #include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
 #include "DFGWorklist.h"
+#include "DefinePropertyAttributes.h"
 #include "DirectArguments.h"
 #include "FTLForOSREntryJITCode.h"
 #include "FTLOSREntry.h"
@@ -994,6 +995,98 @@
     putWithThis<false>(exec, encodedBase, encodedThis, encodedValue, property);
 }
 
+ALWAYS_INLINE static void defineDataProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSValue value, int32_t attributes)
+{
+    PropertyDescriptor descriptor = toPropertyDescriptor(value, jsUndefined(), jsUndefined(), DefinePropertyAttributes(attributes));
+    ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
+    if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
+        JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
+    else
+        base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
+}
+
+void JIT_OPERATION operationDefineDataProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, EncodedJSValue encodedValue, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
+    RETURN_IF_EXCEPTION(scope, void());
+    defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
+}
+
+void JIT_OPERATION operationDefineDataPropertyString(ExecState* exec, JSObject* base, JSString* property, EncodedJSValue encodedValue, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    Identifier propertyName = property->toIdentifier(exec);
+    RETURN_IF_EXCEPTION(scope, void());
+    defineDataProperty(exec, vm, base, propertyName, JSValue::decode(encodedValue), attributes);
+}
+
+void JIT_OPERATION operationDefineDataPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, EncodedJSValue encodedValue, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    defineDataProperty(exec, vm, base, Identifier::fromUid(&vm, property), JSValue::decode(encodedValue), attributes);
+}
+
+void JIT_OPERATION operationDefineDataPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, EncodedJSValue encodedValue, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    defineDataProperty(exec, vm, base, Identifier::fromUid(property->privateName()), JSValue::decode(encodedValue), attributes);
+}
+
+ALWAYS_INLINE static void defineAccessorProperty(ExecState* exec, VM& vm, JSObject* base, const Identifier& propertyName, JSObject* getter, JSObject* setter, int32_t attributes)
+{
+    PropertyDescriptor descriptor = toPropertyDescriptor(jsUndefined(), getter, setter, DefinePropertyAttributes(attributes));
+    ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
+    if (base->methodTable(vm)->defineOwnProperty == JSObject::defineOwnProperty)
+        JSObject::defineOwnProperty(base, exec, propertyName, descriptor, true);
+    else
+        base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
+}
+
+void JIT_OPERATION operationDefineAccessorProperty(ExecState* exec, JSObject* base, EncodedJSValue encodedProperty, JSObject* getter, JSObject* setter, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    Identifier propertyName = JSValue::decode(encodedProperty).toPropertyKey(exec);
+    RETURN_IF_EXCEPTION(scope, void());
+    defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
+}
+
+void JIT_OPERATION operationDefineAccessorPropertyString(ExecState* exec, JSObject* base, JSString* property, JSObject* getter, JSObject* setter, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    Identifier propertyName = property->toIdentifier(exec);
+    RETURN_IF_EXCEPTION(scope, void());
+    defineAccessorProperty(exec, vm, base, propertyName, getter, setter, attributes);
+}
+
+void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState* exec, JSObject* base, UniquedStringImpl* property, JSObject* getter, JSObject* setter, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    defineAccessorProperty(exec, vm, base, Identifier::fromUid(&vm, property), getter, setter, attributes);
+}
+
+void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState* exec, JSObject* base, Symbol* property, JSObject* getter, JSObject* setter, int32_t attributes)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    defineAccessorProperty(exec, vm, base, Identifier::fromUid(property->privateName()), getter, setter, attributes);
+}
+
 char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
 {
     VM* vm = &exec->vm();

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -113,6 +113,14 @@
 void JIT_OPERATION operationPutByIdWithThisStrict(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, UniquedStringImpl*) WTF_INTERNAL;
 void JIT_OPERATION operationPutByValWithThis(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPutByValWithThisStrict(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationDefineDataProperty(ExecState*, JSObject*, EncodedJSValue, EncodedJSValue, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineDataPropertyString(ExecState*, JSObject*, JSString*, EncodedJSValue, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineDataPropertyStringIdent(ExecState*, JSObject*, UniquedStringImpl*, EncodedJSValue, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineDataPropertySymbol(ExecState*, JSObject*, Symbol*, EncodedJSValue, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineAccessorProperty(ExecState*, JSObject*, EncodedJSValue, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineAccessorPropertyString(ExecState*, JSObject*, JSString*, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState*, JSObject*, UniquedStringImpl*, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState*, JSObject*, Symbol*, JSObject*, JSObject*, int32_t) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL;
 EncodedJSValue JIT_OPERATION operationArrayPop(ExecState*, JSArray*) WTF_INTERNAL;

Modified: trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1041,6 +1041,8 @@
         case PutGetterSetterById:
         case PutGetterByVal:
         case PutSetterByVal:
+        case DefineDataProperty:
+        case DefineAccessorProperty:
         case DFG::Jump:
         case Branch:
         case Switch:

Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -213,6 +213,8 @@
     case PutGetterSetterById:
     case PutGetterByVal:
     case PutSetterByVal:
+    case DefineDataProperty:
+    case DefineAccessorProperty:
     case CheckStructure:
     case GetExecutable:
     case GetButterfly:

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -8644,6 +8644,165 @@
     blessedBooleanResult(resultGPR, node);
 }
 
+void SpeculativeJIT::compileDefineDataProperty(Node* node)
+{
+#if USE(JSVALUE64)
+    static_assert(GPRInfo::numberOfRegisters >= 5, "We are assuming we have enough registers to make this call without incrementally setting up the arguments.");
+#else
+    static_assert(GPRInfo::numberOfRegisters >= 6, "We are assuming we have enough registers to make this call without incrementally setting up the arguments.");
+#endif
+
+    SpeculateCellOperand base(this, m_jit.graph().varArgChild(node, 0));
+    GPRReg baseGPR = base.gpr();
+
+    JSValueOperand value(this, m_jit.graph().varArgChild(node, 2));
+    JSValueRegs valueRegs = value.jsValueRegs();
+
+    SpeculateInt32Operand attributes(this, m_jit.graph().varArgChild(node, 3));
+    GPRReg attributesGPR = attributes.gpr();
+
+    Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
+    switch (propertyEdge.useKind()) {
+    case StringUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRReg propertyGPR = property.gpr();
+        speculateString(propertyEdge, propertyGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineDataPropertyString, NoResult, baseGPR, propertyGPR, valueRegs, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case StringIdentUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRTemporary ident(this);
+
+        GPRReg propertyGPR = property.gpr();
+        GPRReg identGPR = ident.gpr();
+
+        speculateString(propertyEdge, propertyGPR);
+        speculateStringIdentAndLoadStorage(propertyEdge, propertyGPR, identGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineDataPropertyStringIdent, NoResult, baseGPR, identGPR, valueRegs, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case SymbolUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRReg propertyGPR = property.gpr();
+        speculateSymbol(propertyEdge, propertyGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineDataPropertySymbol, NoResult, baseGPR, propertyGPR, valueRegs, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case UntypedUse: {
+        JSValueOperand property(this, propertyEdge);
+        JSValueRegs propertyRegs = property.jsValueRegs();
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineDataProperty, NoResult, baseGPR, propertyRegs, valueRegs, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+
+    noResult(node, UseChildrenCalledExplicitly);
+}
+
+void SpeculativeJIT::compileDefineAccessorProperty(Node* node)
+{
+#if USE(JSVALUE64)
+    static_assert(GPRInfo::numberOfRegisters >= 5, "We are assuming we have enough registers to make this call without incrementally setting up the arguments.");
+#else
+    static_assert(GPRInfo::numberOfRegisters >= 6, "We are assuming we have enough registers to make this call without incrementally setting up the arguments.");
+#endif
+
+    SpeculateCellOperand base(this, m_jit.graph().varArgChild(node, 0));
+    GPRReg baseGPR = base.gpr();
+
+    SpeculateCellOperand getter(this, m_jit.graph().varArgChild(node, 2));
+    GPRReg getterGPR = getter.gpr();
+
+    SpeculateCellOperand setter(this, m_jit.graph().varArgChild(node, 3));
+    GPRReg setterGPR = setter.gpr();
+
+    SpeculateInt32Operand attributes(this, m_jit.graph().varArgChild(node, 4));
+    GPRReg attributesGPR = attributes.gpr();
+
+    Edge& propertyEdge = m_jit.graph().varArgChild(node, 1);
+    switch (propertyEdge.useKind()) {
+    case StringUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRReg propertyGPR = property.gpr();
+        speculateString(propertyEdge, propertyGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineAccessorPropertyString, NoResult, baseGPR, propertyGPR, getterGPR, setterGPR, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case StringIdentUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRTemporary ident(this);
+
+        GPRReg propertyGPR = property.gpr();
+        GPRReg identGPR = ident.gpr();
+
+        speculateString(propertyEdge, propertyGPR);
+        speculateStringIdentAndLoadStorage(propertyEdge, propertyGPR, identGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineAccessorPropertyStringIdent, NoResult, baseGPR, identGPR, getterGPR, setterGPR, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case SymbolUse: {
+        SpeculateCellOperand property(this, propertyEdge);
+        GPRReg propertyGPR = property.gpr();
+        speculateSymbol(propertyEdge, propertyGPR);
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineAccessorPropertySymbol, NoResult, baseGPR, propertyGPR, getterGPR, setterGPR, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    case UntypedUse: {
+        JSValueOperand property(this, propertyEdge);
+        JSValueRegs propertyRegs = property.jsValueRegs();
+
+        useChildren(node);
+
+        flushRegisters();
+        callOperation(operationDefineAccessorProperty, NoResult, baseGPR, propertyRegs, getterGPR, setterGPR, attributesGPR);
+        m_jit.exceptionCheck();
+        break;
+    }
+    default:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+
+    noResult(node, UseChildrenCalledExplicitly);
+}
+
 } } // namespace JSC::DFG
 
 #endif

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1335,6 +1335,46 @@
         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4);
         return appendCall(operation);
     }
+    JITCompiler::Call callOperation(V_JITOperation_EOJJZ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3.payloadGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJssJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOIJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOSymJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJOOZ operation, GPRReg arg1, JSValueRegs arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJssOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOIOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOSymOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
     JITCompiler::Call callOperation(V_JITOperation_EOJIUi operation, GPRReg arg1, GPRReg arg2, UniquedStringImpl* impl, unsigned value)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(impl), TrustedImm32(value));
@@ -1779,7 +1819,46 @@
         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1.payloadGPR(), arg1.tagGPR(), arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4.payloadGPR(), arg4.tagGPR());
         return appendCall(operation);
     }
-
+    JITCompiler::Call callOperation(V_JITOperation_EOJJZ operation, GPRReg arg1, JSValueRegs arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3.payloadGPR(), arg3.tagGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJssJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOIJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOSymJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJOOZ operation, GPRReg arg1, JSValueRegs arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOJssOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOIOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
+    JITCompiler::Call callOperation(V_JITOperation_EOSymOOZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3, arg4, arg5);
+        return appendCall(operation);
+    }
     JITCompiler::Call callOperation(V_JITOperation_EOJIUi operation, GPRReg arg1, JSValueRegs arg2, UniquedStringImpl* impl, unsigned value)
     {
         m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR(), TrustedImmPtr(impl), TrustedImm32(value));
@@ -2570,6 +2649,8 @@
     void compileGetDynamicVar(Node*);
     void compilePutDynamicVar(Node*);
     void compileCompareEqPtr(Node*);
+    void compileDefineDataProperty(Node*);
+    void compileDefineAccessorProperty(Node*);
 
     void moveTrueTo(GPRReg);
     void moveFalseTo(GPRReg);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -4479,6 +4479,16 @@
         break;
     }
 
+    case DefineDataProperty: {
+        compileDefineDataProperty(node);
+        break;
+    }
+
+    case DefineAccessorProperty: {
+        compileDefineAccessorProperty(node);
+        break;
+    }
+
     case GetGlobalLexicalVariable:
     case GetGlobalVar: {
         GPRTemporary resultPayload(this);

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -4437,6 +4437,16 @@
         break;
     }
 
+    case DefineDataProperty: {
+        compileDefineDataProperty(node);
+        break;
+    }
+
+    case DefineAccessorProperty: {
+        compileDefineAccessorProperty(node);
+        break;
+    }
+
     case GetGlobalLexicalVariable:
     case GetGlobalVar: {
         GPRTemporary result(this);

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -263,6 +263,8 @@
     case CompareGreater:
     case CompareGreaterEq:
     case CompareStrictEq:
+    case DefineDataProperty:
+    case DefineAccessorProperty:
         // These are OK.
         break;
 

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -691,6 +691,12 @@
         case PutByValWithThis:
             compilePutByValWithThis();
             break;
+        case DefineDataProperty:
+            compileDefineDataProperty();
+            break;
+        case DefineAccessorProperty:
+            compileDefineAccessorProperty();
+            break;
         case ArrayPush:
             compileArrayPush();
             break;
@@ -2763,6 +2769,71 @@
         vmCall(Void, m_out.operation(m_graph.isStrictModeFor(m_node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis),
             m_callFrame, base, thisValue, property, value);
     }
+
+    void compileDefineDataProperty()
+    {
+        LValue base = lowCell(m_graph.varArgChild(m_node, 0));
+        LValue value  = lowJSValue(m_graph.varArgChild(m_node, 2));
+        LValue attributes = lowInt32(m_graph.varArgChild(m_node, 3));
+        Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
+        switch (propertyEdge.useKind()) {
+        case StringUse: {
+            LValue property = lowString(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineDataPropertyString), m_callFrame, base, property, value, attributes);
+            break;
+        }
+        case StringIdentUse: {
+            LValue property = lowStringIdent(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineDataPropertyStringIdent), m_callFrame, base, property, value, attributes);
+            break;
+        }
+        case SymbolUse: {
+            LValue property = lowSymbol(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineDataPropertySymbol), m_callFrame, base, property, value, attributes);
+            break;
+        }
+        case UntypedUse: {
+            LValue property = lowJSValue(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineDataProperty), m_callFrame, base, property, value, attributes);
+            break;
+        }
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
+
+    void compileDefineAccessorProperty()
+    {
+        LValue base = lowCell(m_graph.varArgChild(m_node, 0));
+        LValue getter = lowCell(m_graph.varArgChild(m_node, 2));
+        LValue setter = lowCell(m_graph.varArgChild(m_node, 3));
+        LValue attributes = lowInt32(m_graph.varArgChild(m_node, 4));
+        Edge& propertyEdge = m_graph.varArgChild(m_node, 1);
+        switch (propertyEdge.useKind()) {
+        case StringUse: {
+            LValue property = lowString(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineAccessorPropertyString), m_callFrame, base, property, getter, setter, attributes);
+            break;
+        }
+        case StringIdentUse: {
+            LValue property = lowStringIdent(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineAccessorPropertyStringIdent), m_callFrame, base, property, getter, setter, attributes);
+            break;
+        }
+        case SymbolUse: {
+            LValue property = lowSymbol(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineAccessorPropertySymbol), m_callFrame, base, property, getter, setter, attributes);
+            break;
+        }
+        case UntypedUse: {
+            LValue property = lowJSValue(propertyEdge);
+            vmCall(Void, m_out.operation(operationDefineAccessorProperty), m_callFrame, base, property, getter, setter, attributes);
+            break;
+        }
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+    }
     
     void compilePutById()
     {

Modified: trunk/Source/_javascript_Core/jit/CCallHelpers.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/CCallHelpers.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/CCallHelpers.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -68,107 +68,6 @@
     storePtr(scratch2, Address(scratch1NonArgGPR));
 }
 
-#if NUMBER_OF_ARGUMENT_REGISTERS >= 4
-void CCallHelpers::setupFourStubArgsGPR(GPRReg destA, GPRReg destB, GPRReg destC, GPRReg destD, GPRReg srcA, GPRReg srcB, GPRReg srcC, GPRReg srcD)
-{
-    if (!ASSERT_DISABLED) {
-        RegisterSet destinations(destA, destB, destC, destD);
-        ASSERT_WITH_MESSAGE(destinations.numberOfSetGPRs() == 4, "Destinations should not be aliased.");
-    }
-
-    typedef std::pair<GPRReg, GPRReg> RegPair;
-    Vector<RegPair, 4> pairs;
-
-    if (srcA != destA)
-        pairs.append(std::make_pair(srcA, destA));
-    if (srcB != destB)
-        pairs.append(std::make_pair(srcB, destB));
-    if (srcC != destC)
-        pairs.append(std::make_pair(srcC, destC));
-    if (srcD != destD)
-        pairs.append(std::make_pair(srcD, destD));
-
-
-#if !ASSERT_DISABLED
-    auto numUniqueSources = [&] () -> unsigned {
-        RegisterSet set;
-        for (auto& pair : pairs) {
-            GPRReg source = pair.first;
-            set.set(source);
-        }
-        return set.numberOfSetGPRs();
-    };
-
-    auto numUniqueDests = [&] () -> unsigned {
-        RegisterSet set;
-        for (auto& pair : pairs) {
-            GPRReg dest = pair.second;
-            set.set(dest);
-        }
-        return set.numberOfSetGPRs();
-    };
-#endif
-
-    while (pairs.size()) {
-        RegisterSet freeDestinations;
-        for (auto& pair : pairs) {
-            GPRReg dest = pair.second;
-            freeDestinations.set(dest);
-        }
-        for (auto& pair : pairs) {
-            GPRReg source = pair.first;
-            freeDestinations.clear(source);
-        }
-
-        if (freeDestinations.numberOfSetGPRs()) {
-            bool madeMove = false;
-            for (unsigned i = 0; i < pairs.size(); i++) {
-                auto& pair = pairs[i];
-                GPRReg source = pair.first;
-                GPRReg dest = pair.second;
-                if (freeDestinations.get(dest)) {
-                    move(source, dest);
-                    pairs.remove(i);
-                    madeMove = true;
-                    break;
-                }
-            }
-            ASSERT_UNUSED(madeMove, madeMove);
-            continue;
-        }
-
-        ASSERT(numUniqueDests() == numUniqueSources());
-        ASSERT(numUniqueDests() == pairs.size());
-        // The set of source and destination registers are equivalent sets. This means we don't have
-        // any free destination registers that won't also clobber a source. We get around this by
-        // exchanging registers.
-
-        GPRReg source = pairs[0].first;
-        GPRReg dest = pairs[0].second;
-        swap(source, dest);
-        pairs.remove(0);
-
-        GPRReg newSource = source;
-        for (auto& pair : pairs) {
-            GPRReg source = pair.first;
-            if (source == dest) {
-                pair.first = newSource;
-                break;
-            }
-        }
-
-        // We may have introduced pairs that have the same source and destination. Remove those now.
-        for (unsigned i = 0; i < pairs.size(); i++) {
-            auto& pair = pairs[i];
-            if (pair.first == pair.second) {
-                pairs.remove(i);
-                i--;
-            }
-        }
-    }
-}
-#endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
-
 } // namespace JSC
 
 #endif // ENABLE(JIT)

Modified: trunk/Source/_javascript_Core/jit/CCallHelpers.h (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/CCallHelpers.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/CCallHelpers.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -986,7 +986,14 @@
             swap(destB, destC);
     }
 
-    void setupFourStubArgsGPR(GPRReg destA, GPRReg destB, GPRReg destC, GPRReg destD, GPRReg srcA, GPRReg srcB, GPRReg srcC, GPRReg srcD);
+    void setupFourStubArgsGPR(GPRReg destA, GPRReg destB, GPRReg destC, GPRReg destD, GPRReg srcA, GPRReg srcB, GPRReg srcC, GPRReg srcD)
+    {
+        setupStubArgsGPR<4>({ { destA, destB, destC, destD } }, { { srcA, srcB, srcC, srcD } });
+    }
+    void setupFiveStubArgsGPR(GPRReg destA, GPRReg destB, GPRReg destC, GPRReg destD, GPRReg destE, GPRReg srcA, GPRReg srcB, GPRReg srcC, GPRReg srcD, GPRReg srcE)
+    {
+        setupStubArgsGPR<5>({ { destA, destB, destC, destD, destE } }, { { srcA, srcB, srcC, srcD, srcE } });
+    }
 
 #if CPU(X86_64) || CPU(ARM64)
     template<FPRReg destA, FPRReg destB>
@@ -2183,6 +2190,12 @@
         move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
+    {
+        setupFiveStubArgsGPR(GPRInfo::argumentGPR1, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, GPRInfo::argumentGPR4, GPRInfo::argumentGPR5, arg1, arg2, arg3, arg4, arg5);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
     {
         setupStubArguments134(arg1, arg3, arg4);
@@ -2471,6 +2484,105 @@
         // Ready for a jump!
         move(newFramePointer, stackPointerRegister);
     }
+
+#if NUMBER_OF_ARGUMENT_REGISTERS >= 4
+    template<unsigned NumberOfRegisters>
+    void setupStubArgsGPR(std::array<GPRReg, NumberOfRegisters> destinations, std::array<GPRReg, NumberOfRegisters> sources)
+    {
+        if (!ASSERT_DISABLED) {
+            RegisterSet set;
+            for (GPRReg dest : destinations)
+                set.set(dest);
+            ASSERT_WITH_MESSAGE(set.numberOfSetGPRs() == NumberOfRegisters, "Destinations should not be aliased.");
+        }
+
+        typedef std::pair<GPRReg, GPRReg> RegPair;
+        Vector<RegPair, NumberOfRegisters> pairs;
+
+        for (unsigned i = 0; i < NumberOfRegisters; ++i) {
+            if (sources[i] != destinations[i])
+                pairs.append(std::make_pair(sources[i], destinations[i]));
+        }
+
+#if !ASSERT_DISABLED
+        auto numUniqueSources = [&] () -> unsigned {
+            RegisterSet set;
+            for (auto& pair : pairs) {
+                GPRReg source = pair.first;
+                set.set(source);
+            }
+            return set.numberOfSetGPRs();
+        };
+
+        auto numUniqueDests = [&] () -> unsigned {
+            RegisterSet set;
+            for (auto& pair : pairs) {
+                GPRReg dest = pair.second;
+                set.set(dest);
+            }
+            return set.numberOfSetGPRs();
+        };
+#endif
+
+        while (pairs.size()) {
+            RegisterSet freeDestinations;
+            for (auto& pair : pairs) {
+                GPRReg dest = pair.second;
+                freeDestinations.set(dest);
+            }
+            for (auto& pair : pairs) {
+                GPRReg source = pair.first;
+                freeDestinations.clear(source);
+            }
+
+            if (freeDestinations.numberOfSetGPRs()) {
+                bool madeMove = false;
+                for (unsigned i = 0; i < pairs.size(); i++) {
+                    auto& pair = pairs[i];
+                    GPRReg source = pair.first;
+                    GPRReg dest = pair.second;
+                    if (freeDestinations.get(dest)) {
+                        move(source, dest);
+                        pairs.remove(i);
+                        madeMove = true;
+                        break;
+                    }
+                }
+                ASSERT_UNUSED(madeMove, madeMove);
+                continue;
+            }
+
+            ASSERT(numUniqueDests() == numUniqueSources());
+            ASSERT(numUniqueDests() == pairs.size());
+            // The set of source and destination registers are equivalent sets. This means we don't have
+            // any free destination registers that won't also clobber a source. We get around this by
+            // exchanging registers.
+
+            GPRReg source = pairs[0].first;
+            GPRReg dest = pairs[0].second;
+            swap(source, dest);
+            pairs.remove(0);
+
+            GPRReg newSource = source;
+            for (auto& pair : pairs) {
+                GPRReg source = pair.first;
+                if (source == dest) {
+                    pair.first = newSource;
+                    break;
+                }
+            }
+
+            // We may have introduced pairs that have the same source and destination. Remove those now.
+            for (unsigned i = 0; i < pairs.size(); i++) {
+                auto& pair = pairs[i];
+                if (pair.first == pair.second) {
+                    pairs.remove(i);
+                    i--;
+                }
+            }
+        }
+    }
+#endif // NUMBER_OF_ARGUMENT_REGISTERS >= 4
     
     // These operations clobber all volatile registers. They assume that there is room on the top of
     // stack to marshall call arguments.

Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/JIT.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -322,6 +322,8 @@
         DEFINE_OP(op_put_getter_setter_by_id)
         DEFINE_OP(op_put_getter_by_val)
         DEFINE_OP(op_put_setter_by_val)
+        DEFINE_OP(op_define_data_property)
+        DEFINE_OP(op_define_accessor_property)
 
         DEFINE_OP(op_ret)
         DEFINE_OP(op_rshift)

Modified: trunk/Source/_javascript_Core/jit/JIT.h (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/JIT.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/JIT.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -566,6 +566,8 @@
         void emit_op_put_getter_setter_by_id(Instruction*);
         void emit_op_put_getter_by_val(Instruction*);
         void emit_op_put_setter_by_val(Instruction*);
+        void emit_op_define_data_property(Instruction*);
+        void emit_op_define_accessor_property(Instruction*);
         void emit_op_ret(Instruction*);
         void emit_op_rshift(Instruction*);
         void emit_op_set_function_name(Instruction*);

Modified: trunk/Source/_javascript_Core/jit/JITOperations.h (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/JITOperations.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/JITOperations.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -58,6 +58,7 @@
 class Register;
 class Structure;
 class StructureStubInfo;
+class Symbol;
 class SymbolTable;
 class WatchpointSet;
 
@@ -110,6 +111,7 @@
     Ssi: StructureStubInfo*
     St: Structure*
     Symtab: SymbolTable*
+    Sym: Symbol*
     T: StringImpl*
     V: void
     Vm: VM*
@@ -268,6 +270,14 @@
 typedef void (JIT_OPERATION *V_JITOperation_ESsiJJI)(ExecState*, StructureStubInfo*, EncodedJSValue, EncodedJSValue, UniquedStringImpl*);
 typedef void (JIT_OPERATION *V_JITOperation_EJJJI)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, UniquedStringImpl*);
 typedef void (JIT_OPERATION *V_JITOperation_EJJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue, EncodedJSValue);
+typedef void (JIT_OPERATION *V_JITOperation_EOJJZ)(ExecState*, JSObject*, EncodedJSValue, EncodedJSValue, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOJssJZ)(ExecState*, JSObject*, JSString*, EncodedJSValue, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOIJZ)(ExecState*, JSObject*, UniquedStringImpl*, EncodedJSValue, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOSymJZ)(ExecState*, JSObject*, Symbol*, EncodedJSValue, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOJOOZ)(ExecState*, JSObject*, EncodedJSValue, JSObject*, JSObject*, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOJssOOZ)(ExecState*, JSObject*, JSString*, JSObject*, JSObject*, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOIOOZ)(ExecState*, JSObject*, UniquedStringImpl*, JSObject*, JSObject*, int32_t);
+typedef void (JIT_OPERATION *V_JITOperation_EOSymOOZ)(ExecState*, JSObject*, Symbol*, JSObject*, JSObject*, int32_t);
 typedef void (JIT_OPERATION *V_JITOperation_EWs)(ExecState*, WatchpointSet*);
 typedef void (JIT_OPERATION *V_JITOperation_EZ)(ExecState*, int32_t);
 typedef void (JIT_OPERATION *V_JITOperation_EZJ)(ExecState*, int32_t, EncodedJSValue);

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1770,6 +1770,18 @@
     return slowCases;
 }
 
+void JIT::emit_op_define_data_property(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_define_data_property);
+    slowPathCall.call();
+}
+
+void JIT::emit_op_define_accessor_property(Instruction* currentInstruction)
+{
+    JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_define_accessor_property);
+    slowPathCall.call();
+}
+
 } // namespace JSC
 
 #endif // ENABLE(JIT)

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm (206777 => 206778)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter.asm	2016-10-04 19:31:24 UTC (rev 206778)
@@ -1458,6 +1458,18 @@
     dispatch(5)
 
 
+_llint_op_define_data_property:
+    traceExecution()
+    callOpcodeSlowPath(_slow_path_define_data_property)
+    dispatch(5)
+
+
+_llint_op_define_accessor_property:
+    traceExecution()
+    callOpcodeSlowPath(_slow_path_define_accessor_property)
+    dispatch(6)
+
+
 _llint_op_jtrue:
     traceExecution()
     jumpTrueOrFalse(

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -33,6 +33,7 @@
 #include "ClonedArguments.h"
 #include "CodeProfiling.h"
 #include "CommonSlowPathsExceptions.h"
+#include "DefinePropertyAttributes.h"
 #include "DirectArguments.h"
 #include "Error.h"
 #include "ErrorHandlingScope.h"
@@ -930,4 +931,39 @@
     END();
 }
 
+SLOW_PATH_DECL(slow_path_define_data_property)
+{
+    BEGIN();
+    JSObject* base = asObject(OP_C(1).jsValue());
+    JSValue property = OP_C(2).jsValue();
+    JSValue value = OP_C(3).jsValue();
+    JSValue attributes = OP_C(4).jsValue();
+    ASSERT(attributes.isInt32());
+
+    auto propertyName = property.toPropertyKey(exec);
+    CHECK_EXCEPTION();
+    PropertyDescriptor descriptor = toPropertyDescriptor(value, jsUndefined(), jsUndefined(), DefinePropertyAttributes(attributes.asInt32()));
+    ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
+    base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
+    END();
+}
+
+SLOW_PATH_DECL(slow_path_define_accessor_property)
+{
+    BEGIN();
+    JSObject* base = asObject(OP_C(1).jsValue());
+    JSValue property = OP_C(2).jsValue();
+    JSValue getter = OP_C(3).jsValue();
+    JSValue setter = OP_C(4).jsValue();
+    JSValue attributes = OP_C(5).jsValue();
+    ASSERT(attributes.isInt32());
+
+    auto propertyName = property.toPropertyKey(exec);
+    CHECK_EXCEPTION();
+    PropertyDescriptor descriptor = toPropertyDescriptor(jsUndefined(), getter, setter, DefinePropertyAttributes(attributes.asInt32()));
+    ASSERT((descriptor.attributes() & Accessor) || (!descriptor.isAccessorDescriptor()));
+    base->methodTable(vm)->defineOwnProperty(base, exec, propertyName, descriptor, true);
+    END();
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/CommonSlowPaths.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -256,5 +256,7 @@
 SLOW_PATH_HIDDEN_DECL(slow_path_get_by_val_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_put_by_id_with_this);
 SLOW_PATH_HIDDEN_DECL(slow_path_put_by_val_with_this);
+SLOW_PATH_HIDDEN_DECL(slow_path_define_data_property);
+SLOW_PATH_HIDDEN_DECL(slow_path_define_accessor_property);
 
 } // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/DefinePropertyAttributes.h (0 => 206778)


--- trunk/Source/_javascript_Core/runtime/DefinePropertyAttributes.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/DefinePropertyAttributes.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -0,0 +1,164 @@
+/*
+ * 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 <wtf/Optional.h>
+#include <wtf/TriState.h>
+
+namespace JSC {
+
+class DefinePropertyAttributes {
+public:
+    static_assert(FalseTriState == 0, "FalseTriState is 0.");
+    static_assert(TrueTriState == 1, "TrueTriState is 1.");
+    static_assert(MixedTriState == 2, "MixedTriState is 2.");
+
+    static const unsigned ConfigurableShift = 0;
+    static const unsigned EnumerableShift = 2;
+    static const unsigned WritableShift = 4;
+    static const unsigned ValueShift = 6;
+    static const unsigned GetShift = 7;
+    static const unsigned SetShift = 8;
+
+    DefinePropertyAttributes()
+        : m_attributes(
+            (MixedTriState << ConfigurableShift)
+            | (MixedTriState << EnumerableShift)
+            | (MixedTriState << WritableShift)
+            | (0 << ValueShift)
+            | (0 << GetShift)
+            | (0 << SetShift))
+    {
+    }
+
+    explicit DefinePropertyAttributes(unsigned attributes)
+        : m_attributes(attributes)
+    {
+    }
+
+    unsigned rawRepresentation() const
+    {
+        return m_attributes;
+    }
+
+    bool hasValue() const
+    {
+        return m_attributes & (0b1 << ValueShift);
+    }
+
+    void setValue()
+    {
+        m_attributes = m_attributes | (0b1 << ValueShift);
+    }
+
+    bool hasGet() const
+    {
+        return m_attributes & (0b1 << GetShift);
+    }
+
+    void setGet()
+    {
+        m_attributes = m_attributes | (0b1 << GetShift);
+    }
+
+    bool hasSet() const
+    {
+        return m_attributes & (0b1 << SetShift);
+    }
+
+    void setSet()
+    {
+        m_attributes = m_attributes | (0b1 << SetShift);
+    }
+
+    bool hasWritable() const
+    {
+        return extractTriState(WritableShift) != MixedTriState;
+    }
+
+    Optional<bool> writable() const
+    {
+        if (!hasWritable())
+            return Nullopt;
+        return extractTriState(WritableShift) == TrueTriState;
+    }
+
+    bool hasConfigurable() const
+    {
+        return extractTriState(ConfigurableShift) != MixedTriState;
+    }
+
+    Optional<bool> configurable() const
+    {
+        if (!hasConfigurable())
+            return Nullopt;
+        return extractTriState(ConfigurableShift) == TrueTriState;
+    }
+
+    bool hasEnumerable() const
+    {
+        return extractTriState(EnumerableShift) != MixedTriState;
+    }
+
+    Optional<bool> enumerable() const
+    {
+        if (!hasEnumerable())
+            return Nullopt;
+        return extractTriState(EnumerableShift) == TrueTriState;
+    }
+
+    void setWritable(bool value)
+    {
+        fillWithTriState(value ? TrueTriState : FalseTriState, WritableShift);
+    }
+
+    void setConfigurable(bool value)
+    {
+        fillWithTriState(value ? TrueTriState : FalseTriState, ConfigurableShift);
+    }
+
+    void setEnumerable(bool value)
+    {
+        fillWithTriState(value ? TrueTriState : FalseTriState, EnumerableShift);
+    }
+
+private:
+    void fillWithTriState(TriState state, unsigned shift)
+    {
+        unsigned mask = 0b11 << shift;
+        m_attributes = (m_attributes & ~mask) | (state << shift);
+    }
+
+    TriState extractTriState(unsigned shift) const
+    {
+        return static_cast<TriState>((m_attributes >> shift) & 0b11);
+    }
+
+    unsigned m_attributes;
+};
+
+
+} // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -404,7 +404,7 @@
     m_functionProtoHasInstanceSymbolFunction.set(vm, this, hasInstanceSymbolFunction);
     m_throwTypeErrorGetterSetter.initLater(
         [] (const Initializer<GetterSetter>& init) {
-            JSFunction* thrower = JSFunction::create(init.vm, init.owner, 0, String(), globalFuncThrowTypeError);
+            JSFunction* thrower = init.owner->throwTypeErrorFunction();
             GetterSetter* getterSetter = GetterSetter::create(init.vm, init.owner);
             getterSetter->setGetter(init.vm, init.owner, thrower);
             getterSetter->setSetter(init.vm, init.owner, thrower);
@@ -581,8 +581,8 @@
     ObjectConstructor* objectConstructor = ObjectConstructor::create(vm, this, ObjectConstructor::createStructure(vm, this, m_functionPrototype.get()), m_objectPrototype.get());
     m_objectConstructor.set(vm, this, objectConstructor);
 
-    JSFunction* definePropertyFunction = m_objectConstructor->addDefineProperty(exec, this);
-    m_definePropertyFunction.set(vm, this, definePropertyFunction);
+    JSFunction* throwTypeErrorFunction = JSFunction::create(vm, this, 0, String(), globalFuncThrowTypeError);
+    m_throwTypeErrorFunction.set(vm, this, throwTypeErrorFunction);
 
     JSCell* functionConstructor = FunctionConstructor::create(vm, FunctionConstructor::createStructure(vm, this, m_functionPrototype.get()), m_functionPrototype.get());
     ArrayConstructor* arrayConstructor = ArrayConstructor::create(vm, this, ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayPrototype.get(), m_speciesGetterSetter.get());
@@ -803,7 +803,7 @@
     m_specialPointers[Special::ObjectConstructor] = objectConstructor;
     m_specialPointers[Special::ArrayConstructor] = arrayConstructor;
 
-    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::DefinePropertyFunction)] = m_definePropertyFunction.get();
+    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::ThrowTypeErrorFunction)] = m_throwTypeErrorFunction.get();
 
     if (UNLIKELY(Options::useDollarVM())) {
         JSDollarVMPrototype* dollarVMPrototype = JSDollarVMPrototype::create(vm, this, JSDollarVMPrototype::createStructure(vm, this, m_objectPrototype.get()));
@@ -1066,7 +1066,7 @@
     visitor.append(&thisObject->m_evalFunction);
     visitor.append(&thisObject->m_callFunction);
     visitor.append(&thisObject->m_applyFunction);
-    visitor.append(&thisObject->m_definePropertyFunction);
+    visitor.append(&thisObject->m_throwTypeErrorFunction);
     thisObject->m_arrayProtoToStringFunction.visit(visitor);
     thisObject->m_arrayProtoValuesFunction.visit(visitor);
     thisObject->m_initializePromiseFunction.visit(visitor);

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -233,7 +233,7 @@
     WriteBarrier<JSFunction> m_evalFunction;
     WriteBarrier<JSFunction> m_callFunction;
     WriteBarrier<JSFunction> m_applyFunction;
-    WriteBarrier<JSFunction> m_definePropertyFunction;
+    WriteBarrier<JSFunction> m_throwTypeErrorFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoToStringFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_arrayProtoValuesFunction;
     LazyProperty<JSGlobalObject, JSFunction> m_initializePromiseFunction;
@@ -478,7 +478,7 @@
     JSFunction* evalFunction() const { return m_evalFunction.get(); }
     JSFunction* callFunction() const { return m_callFunction.get(); }
     JSFunction* applyFunction() const { return m_applyFunction.get(); }
-    JSFunction* definePropertyFunction() const { return m_definePropertyFunction.get(); }
+    JSFunction* throwTypeErrorFunction() const { return m_throwTypeErrorFunction.get(); }
     JSFunction* arrayProtoToStringFunction() const { return m_arrayProtoToStringFunction.get(this); }
     JSFunction* arrayProtoValuesFunction() const { return m_arrayProtoValuesFunction.get(this); }
     JSFunction* initializePromiseFunction() const { return m_initializePromiseFunction.get(this); }

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2016-10-04 19:31:24 UTC (rev 206778)
@@ -107,14 +107,6 @@
     JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->builtinNames().getOwnPropertyNamesPrivateName(), objectConstructorGetOwnPropertyNames, DontEnum, 1);
 }
 
-JSFunction* ObjectConstructor::addDefineProperty(ExecState* exec, JSGlobalObject* globalObject)
-{
-    VM& vm = exec->vm();
-    JSFunction* definePropertyFunction = JSFunction::create(vm, globalObject, 3, vm.propertyNames->defineProperty.string(), objectConstructorDefineProperty);
-    putDirectWithoutTransition(vm, vm.propertyNames->defineProperty, definePropertyFunction, DontEnum);
-    return definePropertyFunction;
-}
-
 // ES 19.1.1.1 Object([value])
 static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, JSValue newTarget)
 {

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.h (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -53,8 +53,6 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    JSFunction* addDefineProperty(ExecState*, JSGlobalObject*);
-
 protected:
     void finishCreation(VM&, JSGlobalObject*, ObjectPrototype*);
 

Modified: trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h (206777 => 206778)


--- trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h	2016-10-04 19:00:06 UTC (rev 206777)
+++ trunk/Source/_javascript_Core/runtime/PropertyDescriptor.h	2016-10-04 19:31:24 UTC (rev 206778)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "DefinePropertyAttributes.h"
 #include "JSCJSValue.h"
 
 namespace JSC {
@@ -92,4 +93,30 @@
     unsigned m_seenAttributes;
 };
 
-} // namespace JSC
+inline PropertyDescriptor toPropertyDescriptor(JSValue value, JSValue getter, JSValue setter, DefinePropertyAttributes attributes)
+{
+    // We assume that validation is already done.
+    PropertyDescriptor desc;
+
+    if (Optional<bool> enumerable = attributes.enumerable())
+        desc.setEnumerable(enumerable.value());
+
+    if (Optional<bool> configurable = attributes.configurable())
+        desc.setConfigurable(configurable.value());
+
+    if (attributes.hasValue())
+        desc.setValue(value);
+
+    if (Optional<bool> writable = attributes.writable())
+        desc.setWritable(writable.value());
+
+    if (attributes.hasGet())
+        desc.setGetter(getter);
+
+    if (attributes.hasSet())
+        desc.setSetter(setter);
+
+    return desc;
+}
+
+}
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to