Changeset 206082 in webkit


Ignore:
Timestamp:
Sep 18, 2016 10:40:11 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Do not need to use defineProperty to define methods for object literals
https://bugs.webkit.org/show_bug.cgi?id=162111

Reviewed by Saam Barati.

JSTests:

  • stress/object-literal-methods.js: Added.

(shouldBe):
(throw.new.Error.let.object.get name):
(throw.new.Error):
(shouldBe.let.object.get name):
(shouldBe.let.object.get prototype):
(shouldBe.let.object.get 42):

Source/JavaScriptCore:

When we receive the following code,

var object = { method() { } };

currently, we use defineProperty to define "method" function for "object".
This patch replaces it with the ordinary put_by_id_direct / put_by_val_direct
because the following 2 conditions are met.

  1. While methods in classes have special attributes ({configurable: true, writable: true, enumerable: false}), the attributes of methods in object literals is just the same to the other normal properties ({configurable: true, writable: true, enumerable: true}). This means that we can use the usual put_by_id_direct / put_by_val_direct to define method properties for object literals.
  1. Furthermore, all the own properties that can reside in objects created by object literals have {configurable: true}. So there is no need to check conflict by defineProperty. Always overwriting is OK.

let name = 'method';
var object = { get [name]() { }, method() { } };
Latter method wins.

On the other hand, in class syntax, conflict check is necessary since "prototype" own property is defined as {configurable: false}.

class Hello { static prototype() { } } Should throw error by defineProperty's check.

This means that conflict check done in defneProperty is not necessary for object literals' properties.

  • bytecompiler/NodesCodegen.cpp:

(JSC::PropertyListNode::emitPutConstantProperty):

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r206065 r206082  
     12016-09-18  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Do not need to use defineProperty to define methods for object literals
     4        https://bugs.webkit.org/show_bug.cgi?id=162111
     5
     6        Reviewed by Saam Barati.
     7
     8        * stress/object-literal-methods.js: Added.
     9        (shouldBe):
     10        (throw.new.Error.let.object.get name):
     11        (throw.new.Error):
     12        (shouldBe.let.object.get name):
     13        (shouldBe.let.object.get prototype):
     14        (shouldBe.let.object.get 42):
     15
    1162016-09-16  Yusuke Suzuki  <utatane.tea@gmail.com>
    217
  • trunk/Source/JavaScriptCore/ChangeLog

    r206065 r206082  
     12016-09-18  Yusuke Suzuki  <utatane.tea@gmail.com>
     2
     3        [JSC] Do not need to use defineProperty to define methods for object literals
     4        https://bugs.webkit.org/show_bug.cgi?id=162111
     5
     6        Reviewed by Saam Barati.
     7
     8        When we receive the following code,
     9
     10            var object = { method() { } };
     11
     12        currently, we use defineProperty to define "method" function for "object".
     13        This patch replaces it with the ordinary put_by_id_direct / put_by_val_direct
     14        because the following 2 conditions are met.
     15
     16        1. While methods in classes have special attributes ({configurable: true, writable: true, enumerable: false}),
     17           the attributes of methods in object literals is just the same to the other normal properties ({configurable: true, writable: true, enumerable: true}).
     18           This means that we can use the usual put_by_id_direct / put_by_val_direct to define method properties for object literals.
     19
     20        2. Furthermore, all the own properties that can reside in objects created by object literals have {configurable: true}.
     21           So there is no need to check conflict by defineProperty. Always overwriting is OK.
     22
     23                let name = 'method';
     24                var object = { get [name]() { }, method() { } };
     25                // Latter method wins.
     26
     27            On the other hand, in class syntax, conflict check is necessary since "prototype" own property is defined as {configurable: false}.
     28
     29                class Hello { static prototype() { } }  // Should throw error by defineProperty's check.
     30
     31            This means that conflict check done in defneProperty is not necessary for object literals' properties.
     32
     33        * bytecompiler/NodesCodegen.cpp:
     34        (JSC::PropertyListNode::emitPutConstantProperty):
     35
    1362016-09-16  Yusuke Suzuki  <utatane.tea@gmail.com>
    237
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r206065 r206082  
    588588{
    589589    RefPtr<RegisterID> value = generator.emitNode(node.m_assign);
    590     if (node.needsSuperBinding()) {
     590    if (node.needsSuperBinding())
    591591        emitPutHomeObject(generator, value.get(), newObj);
    592592
     593    if (node.isClassProperty()) {
     594        ASSERT(node.needsSuperBinding());
    593595        RefPtr<RegisterID> propertyNameRegister;
    594596        if (node.name())
     
    597599            propertyNameRegister = generator.emitNode(node.m_expression);
    598600
    599         unsigned attributes = BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable;
    600         if (!node.isClassProperty())
    601             attributes |= BytecodeGenerator::PropertyEnumerable;
    602601        generator.emitSetFunctionNameIfNeeded(node.m_assign, value.get(), propertyNameRegister.get());
    603         generator.emitCallDefineProperty(newObj, propertyNameRegister.get(),
    604             value.get(), nullptr, nullptr, attributes, m_position);
     602        generator.emitCallDefineProperty(newObj, propertyNameRegister.get(), value.get(), nullptr, nullptr, BytecodeGenerator::PropertyConfigurable | BytecodeGenerator::PropertyWritable, m_position);
    605603        return;
    606604    }
Note: See TracChangeset for help on using the changeset viewer.