예제 #1
0
JSString*
js::AsmJSFunctionToString(JSContext* cx, HandleFunction fun)
{
    AsmJSModule& module = FunctionToEnclosingModule(fun);
    const AsmJSModule::ExportedFunction& f = FunctionToExportedFunction(fun, module);
    uint32_t begin = module.srcStart() + f.startOffsetInModule();
    uint32_t end = module.srcStart() + f.endOffsetInModule();

    ScriptSource* source = module.scriptSource();
    StringBuffer out(cx);

    if (!out.append("function "))
        return nullptr;

    bool haveSource = source->hasSourceData();
    if (!haveSource && !JSScript::loadSource(cx, source, &haveSource))
        return nullptr;

    if (!haveSource) {
        // asm.js functions can't be anonymous
        MOZ_ASSERT(fun->atom());
        if (!out.append(fun->atom()))
            return nullptr;
        if (!out.append("() {\n    [sourceless code]\n}"))
            return nullptr;
    } else {
        // asm.js functions cannot have been created with a Function constructor
        // as they belong within a module.
        MOZ_ASSERT(!(begin == 0 && end == source->length() && source->argumentsNotIncluded()));

        if (module.strict()) {
            // AppendUseStrictSource expects its input to start right after the
            // function name, so split the source chars from the src into two parts:
            // the function name and the rest (arguments + body).

            // asm.js functions can't be anonymous
            MOZ_ASSERT(fun->atom());
            if (!out.append(fun->atom()))
                return nullptr;

            size_t nameEnd = begin + fun->atom()->length();
            Rooted<JSFlatString*> src(cx, source->substring(cx, nameEnd, end));
            if (!AppendUseStrictSource(cx, fun, src, out))
                return nullptr;
        } else {
            Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
            if (!src)
                return nullptr;
            if (!out.append(src))
                return nullptr;
        }
    }

    return out.finishString();
}
예제 #2
0
JSString*
js::AsmJSModuleToString(JSContext* cx, HandleFunction fun, bool addParenToLambda)
{
    AsmJSModule& module = ModuleFunctionToModuleObject(fun).module();

    uint32_t begin = module.srcStart();
    uint32_t end = module.srcEndAfterCurly();
    ScriptSource* source = module.scriptSource();
    StringBuffer out(cx);

    if (addParenToLambda && fun->isLambda() && !out.append("("))
        return nullptr;

    if (!out.append("function "))
        return nullptr;

    if (fun->atom() && !out.append(fun->atom()))
        return nullptr;

    bool haveSource = source->hasSourceData();
    if (!haveSource && !JSScript::loadSource(cx, source, &haveSource))
        return nullptr;

    if (!haveSource) {
        if (!out.append("() {\n    [sourceless code]\n}"))
            return nullptr;
    } else {
        // Whether the function has been created with a Function ctor
        bool funCtor = begin == 0 && end == source->length() && source->argumentsNotIncluded();
        if (funCtor) {
            // Functions created with the function constructor don't have arguments in their source.
            if (!out.append("("))
                return nullptr;

            if (PropertyName* argName = module.globalArgumentName()) {
                if (!out.append(argName))
                    return nullptr;
            }
            if (PropertyName* argName = module.importArgumentName()) {
                if (!out.append(", ") || !out.append(argName))
                    return nullptr;
            }
            if (PropertyName* argName = module.bufferArgumentName()) {
                if (!out.append(", ") || !out.append(argName))
                    return nullptr;
            }

            if (!out.append(") {\n"))
                return nullptr;
        }

        Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
        if (!src)
            return nullptr;

        if (module.strict()) {
            if (!AppendUseStrictSource(cx, fun, src, out))
                return nullptr;
        } else {
            if (!out.append(src))
                return nullptr;
        }

        if (funCtor && !out.append("\n}"))
            return nullptr;
    }

    if (addParenToLambda && fun->isLambda() && !out.append(")"))
        return nullptr;

    return out.finishString();
}