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/builtins/BuiltinExecutables.cpp

    r186959 r187205  
    5353        break;
    5454    case ConstructorKind::Base:
    55         return createExecutableInternal(makeSource(baseConstructorCode), name, constructorKind);
     55        return createExecutableInternal(makeSource(baseConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
    5656    case ConstructorKind::Derived:
    57         return createExecutableInternal(makeSource(derivedConstructorCode), name, constructorKind);
     57        return createExecutableInternal(makeSource(derivedConstructorCode), name, constructorKind, ConstructAbility::CanConstruct);
    5858    }
    5959    ASSERT_NOT_REACHED();
     
    6161}
    6262
    63 UnlinkedFunctionExecutable* BuiltinExecutables::createExecutableInternal(const SourceCode& source, const Identifier& name, ConstructorKind constructorKind)
     63UnlinkedFunctionExecutable* BuiltinExecutables::createExecutableInternal(const SourceCode& source, const Identifier& name, ConstructorKind constructorKind, ConstructAbility constructAbility)
    6464{
    6565    JSTextPosition positionBeforeLastNewline;
     
    104104    body->overrideName(name);
    105105    VariableEnvironment dummyTDZVariables;
    106     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, kind, dummyTDZVariables, WTF::move(sourceOverride));
     106    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&m_vm, source, body, kind, constructAbility, dummyTDZVariables, WTF::move(sourceOverride));
    107107    functionExecutable->m_nameValue.set(m_vm, functionExecutable, jsString(&m_vm, name.string()));
    108108    return functionExecutable;
     
    118118{\
    119119    if (!m_##name##Executable)\
    120         m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->builtinNames().functionName##PublicName()), this, &m_##name##Executable);\
     120        m_##name##Executable = Weak<UnlinkedFunctionExecutable>(createBuiltinExecutable(m_##name##Source, m_vm.propertyNames->builtinNames().functionName##PublicName(), s_##name##ConstructAbility), this, &m_##name##Executable);\
    121121    return m_##name##Executable.get();\
    122122}
Note: See TracChangeset for help on using the changeset viewer.