23 #include "function_object.h"
26 #include "array_object.h"
40 FunctionPrototypeImp::FunctionPrototypeImp(
ExecState *exec)
44 putDirect(toStringPropertyName,
45 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::ToString, 0, toStringPropertyName),
47 static const Identifier applyPropertyName(
"apply");
48 putDirect(applyPropertyName,
49 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::Apply, 2, applyPropertyName),
51 static const Identifier callPropertyName(
"call");
52 putDirect(callPropertyName,
53 new FunctionProtoFuncImp(exec,
this, FunctionProtoFuncImp::Call, 1, callPropertyName),
55 putDirect(lengthPropertyName, 0, DontDelete|ReadOnly|DontEnum);
58 FunctionPrototypeImp::~FunctionPrototypeImp()
62 bool FunctionPrototypeImp::implementsCall()
const
80 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
85 bool FunctionProtoFuncImp::implementsCall()
const
97 if (!thisObj.
isValid() || !thisObj.inherits(&InternalFunctionImp::info)) {
99 fprintf(stderr,
"attempted toString() call on null or non-function object\n");
102 exec->setException(err);
106 if (thisObj.inherits(&DeclaredFunctionImp::info)) {
107 DeclaredFunctionImp *fi =
static_cast<DeclaredFunctionImp*
>
109 return String(
"function " + fi->name().ustring() +
"(" +
110 fi->parameterString() +
") " + fi->body->toCode());
111 }
else if (thisObj.inherits(&InternalFunctionImp::info) &&
113 result =
String(
"\nfunction " + static_cast<InternalFunctionImp*>(thisObj.imp())->
name().ustring() +
"() {\n"
114 " [native code]\n}\n");
117 result =
String(
"[function]");
122 Value thisArg = args[0];
123 Value argArray = args[1];
128 exec->setException(err);
133 if (thisArg.
isA(NullType) || thisArg.
isA(UndefinedType))
139 if (!argArray.
isA(NullType) && !argArray.
isA(UndefinedType)) {
140 if (argArray.
isA(ObjectType) &&
145 unsigned int length = argArrayObj.
get(exec,lengthPropertyName).
toUInt32(exec);
146 for (
unsigned int i = 0; i < length; i++)
147 applyArgs.
append(argArrayObj.
get(exec,i));
151 exec->setException(err);
155 result = func.
call(exec,applyThis,applyArgs);
159 Value thisArg = args[0];
164 exec->setException(err);
169 if (thisArg.
isA(NullType) || thisArg.
isA(UndefinedType))
188 putDirect(prototypePropertyName, funcProto, DontEnum|DontDelete|ReadOnly);
191 putDirect(lengthPropertyName, NumberImp::one(), ReadOnly|DontDelete|DontEnum);
194 FunctionObjectImp::~FunctionObjectImp()
198 bool FunctionObjectImp::implementsConstruct()
const
208 int argsSize = args.
size();
211 }
else if (argsSize == 1) {
212 body = args[0].toString(exec);
214 p = args[0].toString(exec);
215 for (
int k = 1; k < argsSize - 1; k++)
216 p +=
"," + args[k].toString(exec);
217 body = args[argsSize-1].toString(exec);
224 FunctionBodyNode *progNode = Parser::parse(body.
data(),body.
size(),&source,&errLine,&errMsg);
229 bool cont = dbg->sourceParsed(exec,source->sid,body,errLine);
235 return Object(
new ObjectImp());
239 exec->interpreter()->imp()->addSourceCode(source);
246 exec->setException(err);
254 FunctionBodyNode *bodyNode = progNode;
262 const UChar *c = p.data();
263 int i = 0, params = 0;
266 while (*c ==
' ' && i < len)
268 if (Lexer::isIdentLetter(c->uc)) {
271 while (i < len && (Lexer::isIdentLetter(c->uc) ||
272 Lexer::isDecimalDigit(c->uc))) {
276 while (i < len && *c ==
' ')
282 }
else if (*c ==
',') {
290 I18N_NOOP(
"Syntax error in parameter list"),
292 exec->setException(err);
300 prototype.
put(exec, constructorPropertyName,
Value(fimp), DontEnum|DontDelete|ReadOnly);
301 fimp->put(exec, prototypePropertyName, prototype, DontEnum|DontDelete|ReadOnly);
305 bool FunctionObjectImp::implementsCall()
const
313 return construct(exec,args);