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");
100 Object err = Error::create(exec,TypeError);
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) &&
113 " [native code]\n}\n");
116 result =
String(
"[function]");
121 Value thisArg = args[0];
122 Value argArray = args[1];
126 Object err = Error::create(exec,TypeError);
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) &&
140 (Object::dynamicCast(argArray).inherits(&ArrayInstanceImp::info) ||
141 Object::dynamicCast(argArray).inherits(&ArgumentsImp::info))) {
143 Object argArrayObj = Object::dynamicCast(argArray);
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));
149 Object err = Error::create(exec,TypeError);
150 exec->setException(err);
154 result = func.
call(exec,applyThis,applyArgs);
158 Value thisArg = args[0];
162 Object err = Error::create(exec,TypeError);
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);
242 Object err = Error::create(exec,SyntaxError,errMsg.
ascii(),errLine);
245 exec->setException(err);
253 FunctionBodyNode *bodyNode = progNode;
255 FunctionImp *fimp =
new DeclaredFunctionImp(exec, Identifier::null(), bodyNode,
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 ==
',') {
288 Object err = Error::create(exec,SyntaxError,
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);
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.