Changeset 189584 in webkit


Ignore:
Timestamp:
Sep 10, 2015 12:34:40 PM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Implement global variables in WebAssembly
https://bugs.webkit.org/show_bug.cgi?id=149031

Patch by Sukolsak Sakshuwong <Sukolsak Sakshuwong> on 2015-09-10
Reviewed by Geoffrey Garen.

This patch implements global variables in WebAssembly. There are two
types of global variables in the current format that we use (the format
used by <https://github.com/WebAssembly/polyfill-prototype-1>): internal
global variables and imported global variables. This patch does not yet
import values for imported global variables. It will be done in a
subsequent patch.

  • tests/stress/wasm-globals.js: Added.

(shouldBe):

  • tests/stress/wasm/globals.wasm: Added.
  • wasm/JSWASMModule.h:

(JSC::JSWASMModule::globalVariables):

  • wasm/WASMFunctionCompiler.h:

(JSC::WASMFunctionCompiler::buildSetGlobal):
(JSC::WASMFunctionCompiler::buildGetGlobal):

  • wasm/WASMFunctionParser.cpp:

(JSC::WASMFunctionParser::parseStatement):
(JSC::WASMFunctionParser::parseSetGlobalStatement):
(JSC::WASMFunctionParser::parseExpressionI32):
(JSC::WASMFunctionParser::parseGetGlobalExpressionI32):
(JSC::WASMFunctionParser::parseExpressionF64):
(JSC::WASMFunctionParser::parseGetGlobalExpressionF64):

  • wasm/WASMFunctionParser.h:
  • wasm/WASMFunctionSyntaxChecker.h:

(JSC::WASMFunctionSyntaxChecker::buildSetGlobal):
(JSC::WASMFunctionSyntaxChecker::buildGetGlobal):

  • wasm/WASMModuleParser.cpp:

(JSC::WASMModuleParser::parseGlobalSection):

Location:
trunk/Source/JavaScriptCore
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r189583 r189584  
     12015-09-10  Sukolsak Sakshuwong  <sukolsak@gmail.com>
     2
     3        Implement global variables in WebAssembly
     4        https://bugs.webkit.org/show_bug.cgi?id=149031
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        This patch implements global variables in WebAssembly. There are two
     9        types of global variables in the current format that we use (the format
     10        used by <https://github.com/WebAssembly/polyfill-prototype-1>): internal
     11        global variables and imported global variables. This patch does not yet
     12        import values for imported global variables. It will be done in a
     13        subsequent patch.
     14
     15        * tests/stress/wasm-globals.js: Added.
     16        (shouldBe):
     17        * tests/stress/wasm/globals.wasm: Added.
     18        * wasm/JSWASMModule.h:
     19        (JSC::JSWASMModule::globalVariables):
     20        * wasm/WASMFunctionCompiler.h:
     21        (JSC::WASMFunctionCompiler::buildSetGlobal):
     22        (JSC::WASMFunctionCompiler::buildGetGlobal):
     23        * wasm/WASMFunctionParser.cpp:
     24        (JSC::WASMFunctionParser::parseStatement):
     25        (JSC::WASMFunctionParser::parseSetGlobalStatement):
     26        (JSC::WASMFunctionParser::parseExpressionI32):
     27        (JSC::WASMFunctionParser::parseGetGlobalExpressionI32):
     28        (JSC::WASMFunctionParser::parseExpressionF64):
     29        (JSC::WASMFunctionParser::parseGetGlobalExpressionF64):
     30        * wasm/WASMFunctionParser.h:
     31        * wasm/WASMFunctionSyntaxChecker.h:
     32        (JSC::WASMFunctionSyntaxChecker::buildSetGlobal):
     33        (JSC::WASMFunctionSyntaxChecker::buildGetGlobal):
     34        * wasm/WASMModuleParser.cpp:
     35        (JSC::WASMModuleParser::parseGlobalSection):
     36
    1372015-09-10  Yusuke Suzuki  <utatane.tea@gmail.com>
    238
  • trunk/Source/JavaScriptCore/wasm/JSWASMModule.h

    r189284 r189584  
    3838    typedef JSDestructibleObject Base;
    3939
     40    union GlobalVariable {
     41        GlobalVariable(int32_t value)
     42            : intValue(value)
     43        {
     44        }
     45        GlobalVariable(float value)
     46            : floatValue(value)
     47        {
     48        }
     49        GlobalVariable(double value)
     50            : doubleValue(value)
     51        {
     52        }
     53
     54        int32_t intValue;
     55        float floatValue;
     56        double doubleValue;
     57    };
     58
    4059    static JSWASMModule* create(VM& vm, Structure* structure)
    4160    {
     
    6887    Vector<unsigned>& functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; }
    6988    Vector<unsigned>& functionStackHeights() { return m_functionStackHeights; }
     89    Vector<GlobalVariable>& globalVariables() { return m_globalVariables; }
    7090
    7191private:
     
    88108    Vector<unsigned> m_functionStartOffsetsInSource;
    89109    Vector<unsigned> m_functionStackHeights;
     110    Vector<GlobalVariable> m_globalVariables;
    90111};
    91112
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

    r189582 r189584  
    224224    }
    225225
     226    void buildSetGlobal(uint32_t globalIndex, int, WASMType type)
     227    {
     228        move(TrustedImmPtr(&m_module->globalVariables()[globalIndex]), GPRInfo::regT0);
     229        switch (type) {
     230        case WASMType::I32:
     231        case WASMType::F32:
     232            load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT1);
     233            store32(GPRInfo::regT1, GPRInfo::regT0);
     234            break;
     235        case WASMType::F64:
     236            loadDouble(temporaryAddress(m_tempStackTop - 1), FPRInfo::fpRegT0);
     237            storeDouble(FPRInfo::fpRegT0, GPRInfo::regT0);
     238            break;
     239        default:
     240            ASSERT_NOT_REACHED();
     241        }
     242        m_tempStackTop--;
     243    }
     244
    226245    void buildReturn(int, WASMExpressionType returnType)
    227246    {
     
    286305        case WASMType::F64:
    287306            loadDouble(localAddress(localIndex), FPRInfo::fpRegT0);
     307            storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
     308            break;
     309        default:
     310            ASSERT_NOT_REACHED();
     311        }
     312        return UNUSED;
     313    }
     314
     315    int buildGetGlobal(uint32_t globalIndex, WASMType type)
     316    {
     317        move(TrustedImmPtr(&m_module->globalVariables()[globalIndex]), GPRInfo::regT0);
     318        switch (type) {
     319        case WASMType::I32:
     320        case WASMType::F32:
     321            load32(GPRInfo::regT0, GPRInfo::regT0);
     322            store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop++));
     323            break;
     324        case WASMType::F64:
     325            loadDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
    288326            storeDouble(FPRInfo::fpRegT0, temporaryAddress(m_tempStackTop++));
    289327            break;
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp

    r189563 r189584  
    138138            parseSetLocalStatement(context);
    139139            break;
     140        case WASMOpStatement::SetGlobal:
     141            parseSetGlobalStatement(context);
     142            break;
    140143        case WASMOpStatement::Return:
    141144            parseReturnStatement(context);
     
    174177            parseSwitchStatement(context);
    175178            break;
    176         case WASMOpStatement::SetGlobal:
    177179        case WASMOpStatement::I32Store8:
    178180        case WASMOpStatement::I32StoreWithOffset8:
     
    199201            break;
    200202        case WASMOpStatementWithImmediate::SetGlobal:
    201             // FIXME: Implement this instruction.
    202             FAIL_WITH_MESSAGE("Unsupported instruction.");
     203            parseSetGlobalStatement(context, immediate);
     204            break;
    203205        default:
    204206            ASSERT_NOT_REACHED();
     
    225227    READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
    226228    return parseSetLocalStatement(context, localIndex);
     229}
     230
     231template <class Context>
     232ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context, uint32_t globalIndex)
     233{
     234    FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
     235    WASMType type = m_module->globalVariableTypes()[globalIndex];
     236    ContextExpression expression = parseExpression(context, WASMExpressionType(type));
     237    PROPAGATE_ERROR();
     238    context.buildSetGlobal(globalIndex, expression, type);
     239    return UNUSED;
     240}
     241
     242template <class Context>
     243ContextStatement WASMFunctionParser::parseSetGlobalStatement(Context& context)
     244{
     245    uint32_t globalIndex;
     246    READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
     247    return parseSetGlobalStatement(context, globalIndex);
    227248}
    228249
     
    475496        case WASMOpExpressionI32::GetLocal:
    476497            return parseGetLocalExpressionI32(context);
     498        case WASMOpExpressionI32::GetGlobal:
     499            return parseGetGlobalExpressionI32(context);
    477500        case WASMOpExpressionI32::CallInternal:
    478501            return parseCallInternalExpressionI32(context);
     
    515538        case WASMOpExpressionI32::GreaterThanOrEqualF64:
    516539            return parseRelationalF64ExpressionI32(context, op);
    517         case WASMOpExpressionI32::GetGlobal:
    518540        case WASMOpExpressionI32::SetLocal:
    519541        case WASMOpExpressionI32::SetGlobal:
     
    616638
    617639template <class Context>
     640ContextExpression WASMFunctionParser::parseGetGlobalExpressionI32(Context& context)
     641{
     642    uint32_t globalIndex;
     643    READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
     644    FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
     645    FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::I32, "Expected a global variable of type int32.");
     646    return context.buildGetGlobal(globalIndex, WASMType::I32);
     647}
     648
     649template <class Context>
    618650ContextExpression WASMFunctionParser::parseCallInternalExpressionI32(Context& context)
    619651{
     
    676708            return parseGetLocalExpressionF64(context);
    677709        case WASMOpExpressionF64::GetGlobal:
     710            return parseGetGlobalExpressionF64(context);
    678711        case WASMOpExpressionF64::SetLocal:
    679712        case WASMOpExpressionF64::SetGlobal:
     
    770803
    771804template <class Context>
     805ContextExpression WASMFunctionParser::parseGetGlobalExpressionF64(Context& context)
     806{
     807    uint32_t globalIndex;
     808    READ_COMPACT_UINT32_OR_FAIL(globalIndex, "Cannot read the global index.");
     809    FAIL_IF_FALSE(globalIndex < m_module->globalVariableTypes().size(), "The global index is incorrect.");
     810    FAIL_IF_FALSE(m_module->globalVariableTypes()[globalIndex] == WASMType::F64, "Expected a global variable of type float64.");
     811    return context.buildGetGlobal(globalIndex, WASMType::F64);
     812}
     813
     814template <class Context>
    772815ContextExpressionList WASMFunctionParser::parseCallArguments(Context& context, const Vector<WASMType>& arguments)
    773816{
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h

    r189563 r189584  
    6565    template <class Context> ContextStatement parseSetLocalStatement(Context&, uint32_t localIndex);
    6666    template <class Context> ContextStatement parseSetLocalStatement(Context&);
     67    template <class Context> ContextStatement parseSetGlobalStatement(Context&, uint32_t globalIndex);
     68    template <class Context> ContextStatement parseSetGlobalStatement(Context&);
    6769    template <class Context> ContextStatement parseReturnStatement(Context&);
    6870    template <class Context> ContextStatement parseBlockStatement(Context&);
     
    8789    template <class Context> ContextExpression parseGetLocalExpressionI32(Context&, uint32_t localIndex);
    8890    template <class Context> ContextExpression parseGetLocalExpressionI32(Context&);
     91    template <class Context> ContextExpression parseGetGlobalExpressionI32(Context&);
    8992    template <class Context> ContextExpression parseCallInternalExpressionI32(Context&);
    9093    template <class Context> ContextExpression parseUnaryExpressionI32(Context&, WASMOpExpressionI32);
     
    99102    template <class Context> ContextExpression parseGetLocalExpressionF64(Context&, uint32_t localIndex);
    100103    template <class Context> ContextExpression parseGetLocalExpressionF64(Context&);
     104    template <class Context> ContextExpression parseGetGlobalExpressionF64(Context&);
    101105
    102106    template <class Context> ContextExpressionList parseCallArguments(Context&, const Vector<WASMType>& arguments);
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h

    r189563 r189584  
    5656    }
    5757
     58    void buildSetGlobal(uint32_t, int, WASMType)
     59    {
     60        m_tempStackTop--;
     61    }
     62
    5863    void buildReturn(int, WASMExpressionType returnType)
    5964    {
     
    7782
    7883    int buildGetLocal(uint32_t, WASMType)
     84    {
     85        m_tempStackTop++;
     86        updateTempStackHeight();
     87        return UNUSED;
     88    }
     89
     90    int buildGetGlobal(uint32_t, WASMType)
    7991    {
    8092        m_tempStackTop++;
  • trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp

    r189284 r189584  
    192192    Vector<WASMType>& globalVariableTypes = m_module->globalVariableTypes();
    193193    globalVariableTypes.reserveInitialCapacity(numberOfGlobalVariables);
    194     for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i)
     194    Vector<JSWASMModule::GlobalVariable>& globalVariables = m_module->globalVariables();
     195    globalVariables.reserveInitialCapacity(numberOfGlobalVariables);
     196    for (uint32_t i = 0; i < numberOfInternalI32GlobalVariables; ++i) {
    195197        globalVariableTypes.uncheckedAppend(WASMType::I32);
    196     for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i)
     198        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0));
     199    }
     200    for (uint32_t i = 0; i < numberOfInternalF32GlobalVariables; ++i) {
    197201        globalVariableTypes.uncheckedAppend(WASMType::F32);
    198     for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i)
     202        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0f));
     203    }
     204    for (uint32_t i = 0; i < numberOfInternalF64GlobalVariables; ++i) {
    199205        globalVariableTypes.uncheckedAppend(WASMType::F64);
     206        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0));
     207    }
    200208    for (uint32_t i = 0; i < numberOfImportedI32GlobalVariables; ++i) {
    201209        String importName;
    202210        READ_STRING_OR_FAIL(importName, "Cannot read the import name of an int32 global variable.");
    203211        globalVariableTypes.uncheckedAppend(WASMType::I32);
     212        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0)); // FIXME: Import the value.
    204213    }
    205214    for (uint32_t i = 0; i < numberOfImportedF32GlobalVariables; ++i) {
     
    207216        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float32 global variable.");
    208217        globalVariableTypes.uncheckedAppend(WASMType::F32);
     218        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0f)); // FIXME: Import the value.
    209219    }
    210220    for (uint32_t i = 0; i < numberOfImportedF64GlobalVariables; ++i) {
     
    212222        READ_STRING_OR_FAIL(importName, "Cannot read the import name of a float64 global variable.");
    213223        globalVariableTypes.uncheckedAppend(WASMType::F64);
     224        globalVariables.uncheckedAppend(JSWASMModule::GlobalVariable(0.0)); // FIXME: Import the value.
    214225    }
    215226}
Note: See TracChangeset for help on using the changeset viewer.