JavaScriptCore/runtime/FunctionConstructor.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
       
     3  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
       
     4  *
       
     5  *  This library is free software; you can redistribute it and/or
       
     6  *  modify it under the terms of the GNU Lesser General Public
       
     7  *  License as published by the Free Software Foundation; either
       
     8  *  version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  *  This library is distributed in the hope that it will be useful,
       
    11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  *  Lesser General Public License for more details.
       
    14  *
       
    15  *  You should have received a copy of the GNU Lesser General Public
       
    16  *  License along with this library; if not, write to the Free Software
       
    17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
       
    18  *
       
    19  */
       
    20 
       
    21 #include "config.h"
       
    22 #include "FunctionConstructor.h"
       
    23 
       
    24 #include "Debugger.h"
       
    25 #include "ExceptionHelpers.h"
       
    26 #include "FunctionPrototype.h"
       
    27 #include "JSFunction.h"
       
    28 #include "JSGlobalObject.h"
       
    29 #include "JSString.h"
       
    30 #include "Lexer.h"
       
    31 #include "Nodes.h"
       
    32 #include "Parser.h"
       
    33 #include "StringBuilder.h"
       
    34 
       
    35 namespace JSC {
       
    36 
       
    37 ASSERT_CLASS_FITS_IN_CELL(FunctionConstructor);
       
    38 
       
    39 FunctionConstructor::FunctionConstructor(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, FunctionPrototype* functionPrototype)
       
    40     : InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, functionPrototype->classInfo()->className))
       
    41 {
       
    42     putDirectWithoutTransition(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
       
    43 
       
    44     // Number of arguments for constructor
       
    45     putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
       
    46 }
       
    47 
       
    48 static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState* exec)
       
    49 {
       
    50     ArgList args(exec);
       
    51     return JSValue::encode(constructFunction(exec, args));
       
    52 }
       
    53 
       
    54 ConstructType FunctionConstructor::getConstructData(ConstructData& constructData)
       
    55 {
       
    56     constructData.native.function = constructWithFunctionConstructor;
       
    57     return ConstructTypeHost;
       
    58 }
       
    59 
       
    60 static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec)
       
    61 {
       
    62     ArgList args(exec);
       
    63     return JSValue::encode(constructFunction(exec, args));
       
    64 }
       
    65 
       
    66 // ECMA 15.3.1 The Function Constructor Called as a Function
       
    67 CallType FunctionConstructor::getCallData(CallData& callData)
       
    68 {
       
    69     callData.native.function = callFunctionConstructor;
       
    70     return CallTypeHost;
       
    71 }
       
    72 
       
    73 // ECMA 15.3.2 The Function Constructor
       
    74 JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
       
    75 {
       
    76     // Functions need to have a space following the opening { due to for web compatibility
       
    77     // see https://bugs.webkit.org/show_bug.cgi?id=24350
       
    78     // We also need \n before the closing } to handle // comments at the end of the last line
       
    79     UString program;
       
    80     if (args.isEmpty())
       
    81         program = "(function() { \n})";
       
    82     else if (args.size() == 1)
       
    83         program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
       
    84     else {
       
    85         StringBuilder builder;
       
    86         builder.append("(function(");
       
    87         builder.append(args.at(0).toString(exec));
       
    88         for (size_t i = 1; i < args.size() - 1; i++) {
       
    89             builder.append(",");
       
    90             builder.append(args.at(i).toString(exec));
       
    91         }
       
    92         builder.append(") { ");
       
    93         builder.append(args.at(args.size() - 1).toString(exec));
       
    94         builder.append("\n})");
       
    95         program = builder.build();
       
    96     }
       
    97 
       
    98     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
       
    99     JSGlobalData* globalData = globalObject->globalData();
       
   100     SourceCode source = makeSource(program, sourceURL, lineNumber);
       
   101     JSObject* exception = 0;
       
   102     RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
       
   103     if (!function) {
       
   104         ASSERT(exception);
       
   105         return throwError(exec, exception);
       
   106     }
       
   107 
       
   108     ScopeChain scopeChain(globalObject, globalData, globalObject, exec->globalThisValue());
       
   109     return new (exec) JSFunction(exec, function, scopeChain.node());
       
   110 }
       
   111 
       
   112 // ECMA 15.3.2 The Function Constructor
       
   113 JSObject* constructFunction(ExecState* exec, const ArgList& args)
       
   114 {
       
   115     return constructFunction(exec, args, Identifier(exec, "anonymous"), UString(), 1);
       
   116 }
       
   117 
       
   118 } // namespace JSC