Bug 1008818: Inherit 'use strict' context for asm.js functions; r=luke

This commit is contained in:
Benjamin Bouvier 2014-05-14 15:59:00 +02:00
parent a5d8d4b3b6
commit ab4522a6b1
2 changed files with 61 additions and 7 deletions

View File

@ -237,7 +237,7 @@ if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
})();
/* Implicit "use strict" context */
/* Implicit "use strict" context in modules */
(function() {
var funcHeader = 'function (glob, ffi, heap) {',
@ -336,3 +336,33 @@ if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
}
})();
/* Implicit "use strict" context in functions */
(function () {
var funcCode = 'function g(x) {\n\
x=x|0;\n\
return x + 1 | 0;}';
var moduleCode = 'function () {\n\
"use asm";\n' + funcCode + '\n\
return g;\n\
}',
useStrict = '"use strict";';
var f5 = eval(useStrict + ";\n(" + moduleCode + "())");
var expectedToString = funcCode.replace('{', '{\n' + useStrict + '\n')
var expectedToSource = expectedToString
assertEq(f5.toString(), expectedToString);
assertEq(f5.toSource(), expectedToSource);
if (isAsmJSCompilationAvailable() && isCachingEnabled()) {
var mf5 = eval("\"use strict\";\n(" + moduleCode + ")");
assertEq(isAsmJSModuleLoadedFromCache(mf5), true);
var f5 = mf5();
assertEq(f5.toString(), expectedToString);
assertEq(f5.toSource(), expectedToSource);
}
})();

View File

@ -915,7 +915,7 @@ js::AsmJSModuleToString(JSContext *cx, HandleFunction fun, bool addParenToLambda
size_t bodyStart = 0, bodyEnd;
// No need to test for functions created with the Function ctor as
// these doesn't implicitly inherit the "use strict" context. Strict mode is
// these don't implicitly inherit the "use strict" context. Strict mode is
// enabled for functions created with the Function ctor only if they begin with
// the "use strict" directive, but these functions won't validate as asm.js
// modules.
@ -996,12 +996,36 @@ js::AsmJSFunctionToString(JSContext *cx, HandleFunction fun)
if (!out.append("function "))
return nullptr;
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (module.strict()) {
// Functions defined in a strict module inherit the strict context, thus we need to add
// "use strict" in the body right after the opening brace.
size_t bodyStart = 0, bodyEnd;
if (!out.append(src->chars(), src->length()))
return nullptr;
// FindBody 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).
JS_ASSERT(fun->atom()); // asm.js functions can't be anonymous
size_t nameEnd = begin + fun->atom()->length();
Rooted<JSFlatString*> src(cx, source->substring(cx, nameEnd, end));
ConstTwoByteChars chars(src->chars(), src->length());
if (!FindBody(cx, fun, chars, src->length(), &bodyStart, &bodyEnd))
return nullptr;
if (!out.append(fun->atom()) ||
!out.append(chars, bodyStart) ||
!out.append("\n\"use strict\";\n") ||
!out.append(chars + bodyStart, src->length() - bodyStart))
{
return nullptr;
}
} else {
Rooted<JSFlatString*> src(cx, source->substring(cx, begin, end));
if (!src)
return nullptr;
if (!out.append(src->chars(), src->length()))
return nullptr;
}
return out.finishString();
}