/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_AsmJSModule_h
#define jit_AsmJSModule_h

#ifdef JS_ION

#include "gc/Marking.h"
#include "jit/RegisterSets.h"

#include "jsscript.h"
#include "jstypedarrayinlines.h"

#include "IonMacroAssembler.h"

namespace js {

// These EcmaScript-defined coercions form the basis of the asm.js type system.
enum AsmJSCoercion
{
    AsmJS_ToInt32,
    AsmJS_ToNumber
};

// The asm.js spec recognizes this set of builtin Math functions.
enum AsmJSMathBuiltin
{
    AsmJSMathBuiltin_sin, AsmJSMathBuiltin_cos, AsmJSMathBuiltin_tan,
    AsmJSMathBuiltin_asin, AsmJSMathBuiltin_acos, AsmJSMathBuiltin_atan,
    AsmJSMathBuiltin_ceil, AsmJSMathBuiltin_floor, AsmJSMathBuiltin_exp,
    AsmJSMathBuiltin_log, AsmJSMathBuiltin_pow, AsmJSMathBuiltin_sqrt,
    AsmJSMathBuiltin_abs, AsmJSMathBuiltin_atan2, AsmJSMathBuiltin_imul
};

// An asm.js module represents the collection of functions nested inside a
// single outer "use asm" function. For example, this asm.js module:
//   function() { "use asm"; function f() {} function g() {} return f }
// contains the functions 'f' and 'g'.
//
// An asm.js module contains both the jit-code produced by compiling all the
// functions in the module as well all the data required to perform the
// link-time validation step in the asm.js spec.
//
// NB: this means that AsmJSModule must be GC-safe.
class AsmJSModule
{
  public:
    class Global
    {
      public:
        enum Which { Variable, FFI, ArrayView, MathBuiltin, Constant };
        enum VarInitKind { InitConstant, InitImport };

      private:
        Which which_;
        union {
            struct {
                uint32_t index_;
                VarInitKind initKind_;
                union {
                    Value constant_; // will only contain int32/double
                    AsmJSCoercion coercion_;
                } init;
            } var;
            uint32_t ffiIndex_;
            ArrayBufferView::ViewType viewType_;
            AsmJSMathBuiltin mathBuiltin_;
            double constantValue_;
        } u;
        RelocatablePtr<PropertyName> name_;

        friend class AsmJSModule;
        Global(Which which) : which_(which) {}

        void trace(JSTracer *trc) {
            if (name_)
                MarkString(trc, &name_, "asm.js global name");
            JS_ASSERT_IF(which_ == Variable && u.var.initKind_ == InitConstant,
                         !u.var.init.constant_.isMarkable());
        }

      public:
        Which which() const {
            return which_;
        }
        uint32_t varIndex() const {
            JS_ASSERT(which_ == Variable);
            return u.var.index_;
        }
        VarInitKind varInitKind() const {
            JS_ASSERT(which_ == Variable);
            return u.var.initKind_;
        }
        const Value &varInitConstant() const {
            JS_ASSERT(which_ == Variable);
            JS_ASSERT(u.var.initKind_ == InitConstant);
            return u.var.init.constant_;
        }
        AsmJSCoercion varImportCoercion() const {
            JS_ASSERT(which_ == Variable);
            JS_ASSERT(u.var.initKind_ == InitImport);
            return u.var.init.coercion_;
        }
        PropertyName *varImportField() const {
            JS_ASSERT(which_ == Variable);
            JS_ASSERT(u.var.initKind_ == InitImport);
            return name_;
        }
        PropertyName *ffiField() const {
            JS_ASSERT(which_ == FFI);
            return name_;
        }
        uint32_t ffiIndex() const {
            JS_ASSERT(which_ == FFI);
            return u.ffiIndex_;
        }
        PropertyName *viewName() const {
            JS_ASSERT(which_ == ArrayView);
            return name_;
        }
        ArrayBufferView::ViewType viewType() const {
            JS_ASSERT(which_ == ArrayView);
            return u.viewType_;
        }
        PropertyName *mathName() const {
            JS_ASSERT(which_ == MathBuiltin);
            return name_;
        }
        AsmJSMathBuiltin mathBuiltin() const {
            JS_ASSERT(which_ == MathBuiltin);
            return u.mathBuiltin_;
        }
        PropertyName *constantName() const {
            JS_ASSERT(which_ == Constant);
            return name_;
        }
        double constantValue() const {
            JS_ASSERT(which_ == Constant);
            return u.constantValue_;
        }
    };

    class Exit
    {
        unsigned ffiIndex_;

        union {
            unsigned codeOffset_;
            uint8_t *code_;
        } interp;

        union {
            unsigned codeOffset_;
            uint8_t *code_;
        } ion;

      public:
        Exit(unsigned ffiIndex)
          : ffiIndex_(ffiIndex)
        {
          interp.codeOffset_ = 0;
          ion.codeOffset_ = 0;
        }
        unsigned ffiIndex() const {
            return ffiIndex_;
        }
        void initInterpOffset(unsigned off) {
            JS_ASSERT(!interp.codeOffset_);
            interp.codeOffset_ = off;
        }
        void initIonOffset(unsigned off) {
            JS_ASSERT(!ion.codeOffset_);
            ion.codeOffset_ = off;
        }
        void patch(uint8_t *baseAddress) {
            interp.code_ = baseAddress + interp.codeOffset_;
            ion.code_ = baseAddress + ion.codeOffset_;
        }
        uint8_t *interpCode() const {
            return interp.code_;
        }
        uint8_t *ionCode() const {
            return ion.code_;
        }
    };
#ifdef JS_CPU_ARM
    typedef int32_t (*CodePtr)(uint64_t *args, uint8_t *global);
#else
    typedef int32_t (*CodePtr)(uint64_t *args);
#endif

    typedef Vector<AsmJSCoercion, 0, SystemAllocPolicy> ArgCoercionVector;

    enum ReturnType { Return_Int32, Return_Double, Return_Void };

    class ExportedFunction
    {
      public:

      private:

        RelocatablePtr<JSFunction> fun_;
        RelocatablePtr<PropertyName> maybeFieldName_;
        ArgCoercionVector argCoercions_;
        ReturnType returnType_;
        bool hasCodePtr_;
        union {
            unsigned codeOffset_;
            CodePtr code_;
        } u;

        friend class AsmJSModule;

        ExportedFunction(JSFunction *fun,
                         PropertyName *maybeFieldName,
                         MoveRef<ArgCoercionVector> argCoercions,
                         ReturnType returnType)
          : fun_(fun),
            maybeFieldName_(maybeFieldName),
            argCoercions_(argCoercions),
            returnType_(returnType),
            hasCodePtr_(false)
        {
            u.codeOffset_ = 0;
        }

        void trace(JSTracer *trc) {
            MarkObject(trc, &fun_, "asm.js export name");
            if (maybeFieldName_)
                MarkString(trc, &maybeFieldName_, "asm.js export field");
        }

      public:
        ExportedFunction(MoveRef<ExportedFunction> rhs)
          : fun_(rhs->fun_),
            maybeFieldName_(rhs->maybeFieldName_),
            argCoercions_(Move(rhs->argCoercions_)),
            returnType_(rhs->returnType_),
            hasCodePtr_(rhs->hasCodePtr_),
            u(rhs->u)
        {}

        void initCodeOffset(unsigned off) {
            JS_ASSERT(!hasCodePtr_);
            JS_ASSERT(!u.codeOffset_);
            u.codeOffset_ = off;
        }
        void patch(uint8_t *baseAddress) {
            JS_ASSERT(!hasCodePtr_);
            JS_ASSERT(u.codeOffset_);
            hasCodePtr_ = true;
            u.code_ = JS_DATA_TO_FUNC_PTR(CodePtr, baseAddress + u.codeOffset_);
        }

        PropertyName *name() const {
            return fun_->name();
        }
        JSFunction *unclonedFunObj() const {
            return fun_;
        }
        PropertyName *maybeFieldName() const {
            return maybeFieldName_;
        }
        unsigned numArgs() const {
            return argCoercions_.length();
        }
        AsmJSCoercion argCoercion(unsigned i) const {
            return argCoercions_[i];
        }
        ReturnType returnType() const {
            return returnType_;
        }
        CodePtr code() const {
            JS_ASSERT(hasCodePtr_);
            return u.code_;
        }
    };

#if defined(MOZ_VTUNE)
    // Function information to add to the VTune JIT profiler following linking.
    struct ProfiledFunction
    {
        JSAtom *name;
        unsigned startCodeOffset;
        unsigned endCodeOffset;

        ProfiledFunction(JSAtom *name, unsigned start, unsigned end)
          : name(name), startCodeOffset(start), endCodeOffset(end)
        { }
    };
#endif

    // If linking fails, we recompile the function as if it's ordinary JS.
    // This struct holds the data required to do this.
    struct PostLinkFailureInfo
    {
        CompileOptions      options_;
        ScriptSource *      scriptSource_;
        uint32_t            bufStart_;      // offset of the function body's start
        uint32_t            bufEnd_;        // offset of the function body's end

        PostLinkFailureInfo(JSContext *cx)
          : options_(cx),
            scriptSource_(),
            bufStart_(),
            bufEnd_()
        { }

        void init(CompileOptions options, ScriptSource *scriptSource,
                  uint32_t bufStart, uint32_t bufEnd)
        {
            options_      = options;
            scriptSource_ = scriptSource;
            bufStart_     = bufStart;
            bufEnd_       = bufEnd;

            scriptSource_->incref();
        }

        ~PostLinkFailureInfo() {
            if (scriptSource_)
                scriptSource_->decref();
        }
    };

  private:
    typedef Vector<ExportedFunction, 0, SystemAllocPolicy> ExportedFunctionVector;
    typedef Vector<Global, 0, SystemAllocPolicy> GlobalVector;
    typedef Vector<Exit, 0, SystemAllocPolicy> ExitVector;
    typedef Vector<jit::AsmJSHeapAccess, 0, SystemAllocPolicy> HeapAccessVector;
#if defined(JS_CPU_ARM)
    typedef Vector<jit::AsmJSBoundsCheck, 0, SystemAllocPolicy> BoundsCheckVector;
#endif
    typedef Vector<jit::IonScriptCounts *, 0, SystemAllocPolicy> FunctionCountsVector;
#if defined(MOZ_VTUNE)
    typedef Vector<ProfiledFunction, 0, SystemAllocPolicy> ProfiledFunctionVector;
#endif

    GlobalVector                          globals_;
    ExitVector                            exits_;
    ExportedFunctionVector                exports_;
    HeapAccessVector                      heapAccesses_;
#if defined(JS_CPU_ARM)
    BoundsCheckVector                     boundsChecks_;
#endif
#if defined(MOZ_VTUNE)
    ProfiledFunctionVector                profiledFunctions_;
#endif

    uint32_t                              numGlobalVars_;
    uint32_t                              numFFIs_;
    uint32_t                              numFuncPtrTableElems_;
    bool                                  hasArrayView_;

    ScopedReleasePtr<JSC::ExecutablePool> codePool_;
    uint8_t *                             code_;
    uint8_t *                             operationCallbackExit_;
    size_t                                functionBytes_;
    size_t                                codeBytes_;
    size_t                                totalBytes_;

    bool                                  linked_;
    HeapPtr<ArrayBufferObject>            maybeHeap_;

    HeapPtrPropertyName                   globalArgumentName_;
    HeapPtrPropertyName                   importArgumentName_;
    HeapPtrPropertyName                   bufferArgumentName_;

    PostLinkFailureInfo                   postLinkFailureInfo_;

    FunctionCountsVector                  functionCounts_;

  public:
    explicit AsmJSModule(JSContext *cx)
      : numGlobalVars_(0),
        numFFIs_(0),
        numFuncPtrTableElems_(0),
        hasArrayView_(false),
        code_(NULL),
        operationCallbackExit_(NULL),
        functionBytes_(0),
        codeBytes_(0),
        totalBytes_(0),
        linked_(false),
        maybeHeap_(),
        postLinkFailureInfo_(cx)
    {}

    ~AsmJSModule();

    void trace(JSTracer *trc) {
        for (unsigned i = 0; i < globals_.length(); i++)
            globals_[i].trace(trc);
        for (unsigned i = 0; i < exports_.length(); i++)
            exports_[i].trace(trc);
        for (unsigned i = 0; i < exits_.length(); i++) {
            if (exitIndexToGlobalDatum(i).fun)
                MarkObject(trc, &exitIndexToGlobalDatum(i).fun, "asm.js imported function");
        }
        if (maybeHeap_)
            MarkObject(trc, &maybeHeap_, "asm.js heap");

        if (globalArgumentName_)
            MarkString(trc, &globalArgumentName_, "asm.js global argument name");
        if (importArgumentName_)
            MarkString(trc, &importArgumentName_, "asm.js import argument name");
        if (bufferArgumentName_)
            MarkString(trc, &bufferArgumentName_, "asm.js buffer argument name");
    }

    bool addGlobalVarInitConstant(const Value &v, uint32_t *globalIndex) {
        JS_ASSERT(!v.isMarkable());
        if (numGlobalVars_ == UINT32_MAX)
            return false;
        Global g(Global::Variable);
        g.u.var.initKind_ = Global::InitConstant;
        g.u.var.init.constant_ = v;
        g.u.var.index_ = *globalIndex = numGlobalVars_++;
        return globals_.append(g);
    }
    bool addGlobalVarImport(PropertyName *fieldName, AsmJSCoercion coercion, uint32_t *globalIndex) {
        Global g(Global::Variable);
        g.u.var.initKind_ = Global::InitImport;
        g.u.var.init.coercion_ = coercion;
        g.u.var.index_ = *globalIndex = numGlobalVars_++;
        g.name_ = fieldName;
        return globals_.append(g);
    }
    bool incrementNumFuncPtrTableElems(uint32_t numElems) {
        if (UINT32_MAX - numFuncPtrTableElems_ < numElems)
            return false;
        numFuncPtrTableElems_ += numElems;
        return true;
    }
    bool addFFI(PropertyName *field, uint32_t *ffiIndex) {
        if (numFFIs_ == UINT32_MAX)
            return false;
        Global g(Global::FFI);
        g.u.ffiIndex_ = *ffiIndex = numFFIs_++;
        g.name_ = field;
        return globals_.append(g);
    }
    bool addArrayView(ArrayBufferView::ViewType vt, PropertyName *field) {
        hasArrayView_ = true;
        Global g(Global::ArrayView);
        g.u.viewType_ = vt;
        g.name_ = field;
        return globals_.append(g);
    }
    bool addMathBuiltin(AsmJSMathBuiltin mathBuiltin, PropertyName *field) {
        Global g(Global::MathBuiltin);
        g.u.mathBuiltin_ = mathBuiltin;
        g.name_ = field;
        return globals_.append(g);
    }
    bool addGlobalConstant(double value, PropertyName *fieldName) {
        Global g(Global::Constant);
        g.u.constantValue_ = value;
        g.name_ = fieldName;
        return globals_.append(g);
    }
    bool addExit(unsigned ffiIndex, unsigned *exitIndex) {
        *exitIndex = unsigned(exits_.length());
        return exits_.append(Exit(ffiIndex));
    }
    bool addFunctionCounts(jit::IonScriptCounts *counts) {
        return functionCounts_.append(counts);
    }

    bool addExportedFunction(JSFunction *fun, PropertyName *maybeFieldName,
                             MoveRef<ArgCoercionVector> argCoercions, ReturnType returnType)
    {
        ExportedFunction func(fun, maybeFieldName, argCoercions, returnType);
        return exports_.append(Move(func));
    }
    unsigned numExportedFunctions() const {
        return exports_.length();
    }
    const ExportedFunction &exportedFunction(unsigned i) const {
        return exports_[i];
    }
    ExportedFunction &exportedFunction(unsigned i) {
        return exports_[i];
    }
#ifdef MOZ_VTUNE
    bool trackProfiledFunction(JSAtom *name, unsigned startCodeOffset, unsigned endCodeOffset) {
        ProfiledFunction func(name, startCodeOffset, endCodeOffset);
        return profiledFunctions_.append(func);
    }
    unsigned numProfiledFunctions() const {
        return profiledFunctions_.length();
    }
    const ProfiledFunction &profiledFunction(unsigned i) const {
        return profiledFunctions_[i];
    }
#endif
    bool hasArrayView() const {
        return hasArrayView_;
    }
    unsigned numFFIs() const {
        return numFFIs_;
    }
    unsigned numGlobalVars() const {
        return numGlobalVars_;
    }
    unsigned numGlobals() const {
        return globals_.length();
    }
    Global &global(unsigned i) {
        return globals_[i];
    }
    unsigned numFuncPtrTableElems() const {
        return numFuncPtrTableElems_;
    }
    unsigned numExits() const {
        return exits_.length();
    }
    Exit &exit(unsigned i) {
        return exits_[i];
    }
    const Exit &exit(unsigned i) const {
        return exits_[i];
    }
    unsigned numFunctionCounts() const {
        return functionCounts_.length();
    }
    jit::IonScriptCounts *functionCounts(unsigned i) {
        return functionCounts_[i];
    }

    // An Exit holds bookkeeping information about an exit; the ExitDatum
    // struct overlays the actual runtime data stored in the global data
    // section.
    struct ExitDatum
    {
        uint8_t *exit;
        HeapPtrFunction fun;
    };

    // Global data section
    //
    // The global data section is placed after the executable code (i.e., at
    // offset codeBytes_) in the module's linear allocation. The global data
    // are laid out in this order:
    //   0. a pointer/descriptor for the heap that was linked to the module
    //   1. global variable state (elements are sizeof(uint64_t))
    //   2. function-pointer table elements (elements are sizeof(void*))
    //   3. exits (elements are sizeof(ExitDatum))
    //
    // NB: The list of exits is extended while emitting function bodies and
    // thus exits must be at the end of the list to avoid invalidating indices.
    uint8_t *globalData() const {
        JS_ASSERT(code_);
        return code_ + codeBytes_;
    }

    size_t globalDataBytes() const {
        return sizeof(void*) +
               numGlobalVars_ * sizeof(uint64_t) +
               numFuncPtrTableElems_ * sizeof(void*) +
               exits_.length() * sizeof(ExitDatum);
    }
    unsigned heapOffset() const {
        return 0;
    }
    uint8_t *&heapDatum() const {
        return *(uint8_t**)(globalData() + heapOffset());
    }
    unsigned globalVarIndexToGlobalDataOffset(unsigned i) const {
        JS_ASSERT(i < numGlobalVars_);
        return sizeof(void*) +
               i * sizeof(uint64_t);
    }
    void *globalVarIndexToGlobalDatum(unsigned i) const {
        return (void *)(globalData() + globalVarIndexToGlobalDataOffset(i));
    }
    unsigned funcPtrIndexToGlobalDataOffset(unsigned i) const {
        return sizeof(void*) +
               numGlobalVars_ * sizeof(uint64_t) +
               i * sizeof(void*);
    }
    void *&funcPtrIndexToGlobalDatum(unsigned i) const {
        return *(void **)(globalData() + funcPtrIndexToGlobalDataOffset(i));
    }
    unsigned exitIndexToGlobalDataOffset(unsigned exitIndex) const {
        JS_ASSERT(exitIndex < exits_.length());
        return sizeof(void*) +
               numGlobalVars_ * sizeof(uint64_t) +
               numFuncPtrTableElems_ * sizeof(void*) +
               exitIndex * sizeof(ExitDatum);
    }
    ExitDatum &exitIndexToGlobalDatum(unsigned exitIndex) const {
        return *(ExitDatum *)(globalData() + exitIndexToGlobalDataOffset(exitIndex));
    }

    void setFunctionBytes(size_t functionBytes) {
        JS_ASSERT(functionBytes % AsmJSPageSize == 0);
        functionBytes_ = functionBytes;
    }
    size_t functionBytes() const {
        JS_ASSERT(functionBytes_);
        JS_ASSERT(functionBytes_ % AsmJSPageSize == 0);
        return functionBytes_;
    }
    bool containsPC(void *pc) const {
        uint8_t *code = functionCode();
        return pc >= code && pc < (code + functionBytes());
    }

    bool addHeapAccesses(const jit::AsmJSHeapAccessVector &accesses) {
        return heapAccesses_.append(accesses);
    }
    unsigned numHeapAccesses() const {
        return heapAccesses_.length();
    }
    jit::AsmJSHeapAccess &heapAccess(unsigned i) {
        return heapAccesses_[i];
    }
    const jit::AsmJSHeapAccess &heapAccess(unsigned i) const {
        return heapAccesses_[i];
    }
#if defined(JS_CPU_ARM)
    bool addBoundsChecks(const jit::AsmJSBoundsCheckVector &checks) {
        return boundsChecks_.append(checks);
    }
    void convertBoundsChecksToActualOffset(jit::MacroAssembler &masm) {
        for (unsigned i = 0; i < boundsChecks_.length(); i++)
            boundsChecks_[i].setOffset(masm.actualOffset(boundsChecks_[i].offset()));
    }

    void patchBoundsChecks(unsigned heapSize) {
        jit::AutoFlushCache afc("patchBoundsCheck");
        int bits = -1;
        JS_CEILING_LOG2(bits, heapSize);
        if (bits == -1) {
            // tried to size the array to 0, that is bad, but not horrible
            return;
        }

        for (unsigned i = 0; i < boundsChecks_.length(); i++)
            jit::Assembler::updateBoundsCheck(bits, (jit::Instruction*)(boundsChecks_[i].offset() + code_));

    }
    unsigned numBoundsChecks() const {
        return boundsChecks_.length();
    }
    const jit::AsmJSBoundsCheck &boundsCheck(unsigned i) const {
        return boundsChecks_[i];
    }
#endif



    void takeOwnership(JSC::ExecutablePool *pool, uint8_t *code, size_t codeBytes, size_t totalBytes) {
        JS_ASSERT(uintptr_t(code) % AsmJSPageSize == 0);
        codePool_ = pool;
        code_ = code;
        codeBytes_ = codeBytes;
        totalBytes_ = totalBytes;
    }
    uint8_t *functionCode() const {
        JS_ASSERT(code_);
        JS_ASSERT(uintptr_t(code_) % AsmJSPageSize == 0);
        return code_;
    }

    void setOperationCallbackExit(uint8_t *ptr) {
        operationCallbackExit_ = ptr;
    }
    uint8_t *operationCallbackExit() const {
        return operationCallbackExit_;
    }

    void setIsLinked(Handle<ArrayBufferObject*> maybeHeap) {
        JS_ASSERT(!linked_);
        linked_ = true;
        maybeHeap_ = maybeHeap;
        heapDatum() = maybeHeap_ ? maybeHeap_->dataPointer() : NULL;
    }
    bool isLinked() const {
        return linked_;
    }
    uint8_t *maybeHeap() const {
        JS_ASSERT(linked_);
        return heapDatum();
    }
    size_t heapLength() const {
        JS_ASSERT(linked_);
        return maybeHeap_ ? maybeHeap_->byteLength() : 0;
    }

    void initGlobalArgumentName(PropertyName *n) { globalArgumentName_ = n; }
    void initImportArgumentName(PropertyName *n) { importArgumentName_ = n; }
    void initBufferArgumentName(PropertyName *n) { bufferArgumentName_ = n; }

    PropertyName *globalArgumentName() const { return globalArgumentName_; }
    PropertyName *importArgumentName() const { return importArgumentName_; }
    PropertyName *bufferArgumentName() const { return bufferArgumentName_; }

    void initPostLinkFailureInfo(CompileOptions options,
                                 ScriptSource *scriptSource, uint32_t bufStart, uint32_t bufEnd) {
        options.filename = scriptSource->filename();
        postLinkFailureInfo_.init(options, scriptSource, bufStart, bufEnd);
    }

    const PostLinkFailureInfo &postLinkFailureInfo() const {
        return postLinkFailureInfo_;
    }

    size_t exitDatumToExitIndex(ExitDatum *exit) const {
        ExitDatum *first = &exitIndexToGlobalDatum(0);
        JS_ASSERT(exit >= first && exit < first + numExits());
        return exit - first;
    }

    void detachIonCompilation(size_t exitIndex) const {
        ExitDatum &exitDatum = exitIndexToGlobalDatum(exitIndex);
        exitDatum.exit = exit(exitIndex).interpCode();
    }
};


// The AsmJSModule C++ object is held by a JSObject that takes care of calling
// 'trace' and the destructor on finalization.
extern AsmJSModule &
AsmJSModuleObjectToModule(JSObject *obj);

extern bool
IsAsmJSModuleObject(JSObject *obj);

extern JSObject &
AsmJSModuleObject(JSFunction *moduleFun);

extern void
SetAsmJSModuleObject(JSFunction *moduleFun, JSObject *moduleObj);

}  // namespace js

#endif  // JS_ION

#endif /* jit_AsmJSModule_h */
