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");
101 Object err = Error::create(exec,TypeError);
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) &&
114 " [native code]\n}\n");
117 result =
String(
"[function]");
122 Value thisArg = args[0];
123 Value argArray = args[1];
127 Object err = Error::create(exec,TypeError);
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) &&
141 (Object::dynamicCast(argArray).inherits(&ArrayInstanceImp::info) ||
142 Object::dynamicCast(argArray).inherits(&ArgumentsImp::info))) {
144 Object argArrayObj = Object::dynamicCast(argArray);
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));
150 Object err = Error::create(exec,TypeError);
151 exec->setException(err);
155 result = func.
call(exec,applyThis,applyArgs);
159 Value thisArg = args[0];
163 Object err = Error::create(exec,TypeError);
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);
243 Object err = Error::create(exec,SyntaxError,errMsg.
ascii(),errLine);
246 exec->setException(err);
254 FunctionBodyNode *bodyNode = progNode;
256 FunctionImp *fimp =
new DeclaredFunctionImp(exec, Identifier::null(), bodyNode,
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 ==
',') {
289 Object err = Error::create(exec,SyntaxError,
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);
Represents the current state of script execution.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
Interpreter * dynamicInterpreter() const
Returns the interpreter associated with this execution state.
Implementation class for functions implemented in JS.
The initial value of Function.prototype (and thus all objects created with the Function constructor)
Represents an Identifier for a Javascript object.
bool isNull() const
Returns the identfiers state of being unset.
const UString & ustring() const
returns a UString of the identifier
Base class for all function objects.
Object builtinObject() const
Returns the builtin "Object" object.
Object & globalObject() const
Returns the object that is used as the global object during all script execution performed by this in...
void append(const Value &val)
Append an object to the end of the list.
List copyTail() const
Make a copy of the list, omitting the first element.
bool implementsCall() const
Whether or not the object implements the call() method.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Value call(ExecState *exec, Object &thisObj, const List &args)
Calls this object as if it is a function.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Represents an primitive String value.
char * ascii() const
Convert the Unicode string to plain ASCII chars chopping of any higher bytes.
const UChar * data() const
Represents an primitive Undefined value.
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents.
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
unsigned int toUInt32(ExecState *exec) const
Performs the ToUInt32 type conversion operation on this value (ECMA 9.6)
bool isValid() const
Returns whether or not this is a valid value.