Ignore:
Timestamp:
Jul 22, 2015, 7:36:20 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

Introducing construct ability into JS executables
https://bugs.webkit.org/show_bug.cgi?id=147183

Reviewed by Geoffrey Garen.

Decouple the construct ability from the builtin functions.
Currently, all builtin functions are not constructors after r182995.
In that patch, when the given function is builtin JS function, we recognize it as the non-constructor function.

But, we need to relax it to implement some constructors in builtins JS.
By decoupling the construct ability from whether the function is builtin or not, we can provide

  1. constructors written in builtin JS
  2. non-constructors in normal JS functions

(1) is needed for Promise constructor.
And (2) is needed for method functions and arrow functions.

This patch introduces ConstructAbility into the unlinked function executables.
It holds whether the given JS function has the construct ability or not.
By leveraging this, this patch disables the construct ability of the method definitions, setters, getters and arrow functions.

And at the same time, this patch introduces the annotation for constructor in builtin JS.
We can define the function as follows,

constructor Promise(executor)
{

...

}

(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutableInternal):

  • builtins/BuiltinExecutables.h:
  • builtins/Iterator.prototype.js:

(symbolIterator):
(SymbolIterator): Deleted.

  • bytecode/UnlinkedCodeBlock.cpp:

(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):

  • bytecode/UnlinkedCodeBlock.h:
  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::makeFunction):

  • generate-js-builtins:

(getCopyright):
(Function):
(Function.init):
(Function.mangleName):
(getFunctions):
(mangleName): Deleted.

  • jit/JITOperations.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::setUpCall):

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::parseClass):

  • runtime/CodeCache.cpp:

(JSC::CodeCache::getFunctionExecutableFromGlobalCode):

  • runtime/CommonIdentifiers.h:
  • runtime/ConstructAbility.h: Copied from Source/JavaScriptCore/builtins/Iterator.prototype.js.
  • runtime/Executable.h:
  • runtime/JSFunction.cpp:

(JSC::JSFunction::getConstructData):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • tests/stress/non-constructors.js: Added.

(shouldThrow):
(.prototype.method):
(.prototype.get getter):
(.prototype.set setter):
(.method):
(.get shouldThrow):
(.set shouldThrow):
(set var.test.get getter):
(set var.test.set setter):
(set var.test.normal):
(.set var):
(.set new):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r187033 r187205  
    3030#include "CodeSpecializationKind.h"
    3131#include "CodeType.h"
     32#include "ConstructAbility.h"
    3233#include "ExpressionRangeInfo.h"
    3334#include "HandlerInfo.h"
     
    108109    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
    109110
    110     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     111    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr)
    111112    {
    112113        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
    113             UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, parentScopeTDZVariables);
     114            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables);
    114115        instance->finishCreation(*vm);
    115116        return instance;
     
    163164
    164165    bool isBuiltinFunction() const { return m_isBuiltinFunction; }
     166    ConstructAbility constructAbility() const { return static_cast<ConstructAbility>(m_constructAbility); }
    165167    bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
    166168    const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; }
    167169
    168170private:
    169     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind, VariableEnvironment&);
     171    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionBodyNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&);
    170172    WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
    171173    WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
     
    194196    unsigned m_hasCapturedVariables : 1;
    195197    unsigned m_isBuiltinFunction : 1;
     198    unsigned m_constructAbility: 1;
    196199    unsigned m_constructorKind : 2;
    197200    unsigned m_functionMode : 1; // FunctionMode
Note: See TracChangeset for help on using the changeset viewer.