// ECMA 15.3.2 The Function Constructor JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber) { // Functions need to have a space following the opening { due to for web compatibility // see https://bugs.webkit.org/show_bug.cgi?id=24350 // We also need \n before the closing } to handle // comments at the end of the last line UString program; if (args.isEmpty()) program = "(function() { \n})"; else if (args.size() == 1) program = makeString("(function() { ", args.at(0).toString(exec), "\n})"); else { StringBuilder builder; builder.append("(function("); builder.append(args.at(0).toString(exec)); for (size_t i = 1; i < args.size() - 1; i++) { builder.append(","); builder.append(args.at(i).toString(exec)); } builder.append(") { "); builder.append(args.at(args.size() - 1).toString(exec)); builder.append("\n})"); program = builder.build(); } int errLine; UString errMsg; SourceCode source = makeSource(program, sourceURL, lineNumber); RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); if (!function) return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()); JSGlobalObject* globalObject = exec->lexicalGlobalObject(); ScopeChain scopeChain(globalObject, globalObject->globalData(), globalObject, exec->globalThisValue()); return new (exec) JSFunction(exec, function, scopeChain.node()); }
UString FunctionExecutable::paramString() const { FunctionParameters& parameters = *m_parameters; StringBuilder builder; for (size_t pos = 0; pos < parameters.size(); ++pos) { if (!builder.isEmpty()) builder.append(", "); builder.append(parameters[pos].ustring()); } return builder.build(); }
// "inline" is required here to help WINSCW compiler resolve specialized argument in templated functions. template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token) { ++m_ptr; const UChar* runStart; StringBuilder builder; do { runStart = m_ptr; while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr)) ++m_ptr; if (runStart < m_ptr) builder.append(runStart, m_ptr - runStart); if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') { ++m_ptr; if (m_ptr >= m_end) return TokError; switch (*m_ptr) { case '"': builder.append('"'); m_ptr++; break; case '\\': builder.append('\\'); m_ptr++; break; case '/': builder.append('/'); m_ptr++; break; case 'b': builder.append('\b'); m_ptr++; break; case 'f': builder.append('\f'); m_ptr++; break; case 'n': builder.append('\n'); m_ptr++; break; case 'r': builder.append('\r'); m_ptr++; break; case 't': builder.append('\t'); m_ptr++; break; case 'u': if ((m_end - m_ptr) < 5) // uNNNN == 5 characters return TokError; for (int i = 1; i < 5; i++) { if (!isASCIIHexDigit(m_ptr[i])) return TokError; } builder.append(AJ::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4])); m_ptr += 5; break; default: return TokError; } } } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"'); if (m_ptr >= m_end || *m_ptr != '"') return TokError; token.stringToken = builder.build(); token.type = TokString; token.end = ++m_ptr; return TokString; }