22 #include "function_object.h"
25 #include "array_object.h"
39 FunctionPrototypeImp::FunctionPrototypeImp(
ExecState *exec)
43 putDirect(toStringPropertyName,
44 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::ToString, 0, toStringPropertyName),
46 static const Identifier applyPropertyName(
"apply");
47 putDirect(applyPropertyName,
48 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::Apply, 2, applyPropertyName),
50 static const Identifier callPropertyName(
"call");
51 putDirect(callPropertyName,
52 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::Call, 1, callPropertyName),
54 putDirect(lengthPropertyName, 0, DontDelete|ReadOnly|DontEnum);
57 FunctionPrototypeImp::~FunctionPrototypeImp()
61 bool FunctionPrototypeImp::implementsCall()
const
79 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
84 bool FunctionProtoFuncImp::implementsCall()
const
96 if (!thisObj.
isValid() || !thisObj.inherits(&InternalFunctionImp::info)) {
98 fprintf(stderr,
"attempted toString() call on null or non-function object\n");
101 exec->setException(err);
105 if (thisObj.inherits(&DeclaredFunctionImp::info)) {
106 DeclaredFunctionImp *fi =
static_cast<DeclaredFunctionImp*
>
108 return String(
"function " + fi->name().ustring() +
"(" +
109 fi->parameterString() +
") " + fi->body->toCode());
110 }
else if (thisObj.inherits(&InternalFunctionImp::info) &&
112 result =
String(
"\nfunction " + static_cast<InternalFunctionImp*>(thisObj.imp())->
name().ustring() +
"() {\n"
113 " [native code]\n}\n");
116 result =
String(
"[function]");
121 Value thisArg = args[0];
122 Value argArray = args[1];
127 exec->setException(err);
132 if (thisArg.
isA(NullType) || thisArg.
isA(UndefinedType))
138 if (!argArray.
isA(NullType) && !argArray.
isA(UndefinedType)) {
139 if (argArray.
isA(ObjectType) &&
144 unsigned int length = argArrayObj.
get(exec,lengthPropertyName).
toUInt32(exec);
145 for (
unsigned int i = 0; i < length; i++)
146 applyArgs.
append(argArrayObj.
get(exec,i));
150 exec->setException(err);
154 result = func.
call(exec,applyThis,applyArgs);
158 Value thisArg = args[0];
163 exec->setException(err);
168 if (thisArg.
isA(NullType) || thisArg.
isA(UndefinedType))
187 putDirect(prototypePropertyName, funcProto, DontEnum|DontDelete|ReadOnly);
190 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
193 FunctionObjectImp::~FunctionObjectImp()
197 bool FunctionObjectImp::implementsConstruct()
const
207 int argsSize = args.
size();
210 }
else if (argsSize == 1) {
211 body = args[0].toString(exec);
213 p = args[0].toString(exec);
214 for (
int k = 1; k < argsSize - 1; k++)
215 p +=
"," + args[k].toString(exec);
216 body = args[argsSize-1].toString(exec);
223 FunctionBodyNode *progNode = Parser::parse(body.
data(),body.
size(),&source,&errLine,&errMsg);
228 bool cont = dbg->sourceParsed(exec,source->sid,body,errLine);
234 return Object(
new ObjectImp());
238 exec->interpreter()->imp()->addSourceCode(source);
245 exec->setException(err);
253 FunctionBodyNode *bodyNode = progNode;
261 const UChar *c = p.data();
262 int i = 0, params = 0;
265 while (*c ==
' ' && i < len)
267 if (Lexer::isIdentLetter(c->uc)) {
270 while (i < len && (Lexer::isIdentLetter(c->uc) ||
271 Lexer::isDecimalDigit(c->uc))) {
275 while (i < len && *c ==
' ')
281 }
else if (*c ==
',') {
289 I18N_NOOP(
"Syntax error in parameter list"),
291 exec->setException(err);
299 prototype.
put(exec, constructorPropertyName,
Value(fimp), DontEnum|DontDelete|ReadOnly);
300 fimp->put(exec, prototypePropertyName, prototype, DontEnum|DontDelete|ReadOnly);
304 bool FunctionObjectImp::implementsCall()
const
312 return construct(exec,args);