static void scStringSlice(const CFunctionsScopePtr &c, void *userdata) {
	string str = c->getArgument("this")->getString();
	int length = c->getArgumentsLength()-((int)userdata & 1);
	bool slice = ((int)userdata & 2) == 0;
	int start = c->getArgument("start")->getInt();
	int end = (int)str.size();
	if(slice && start<0) start = str.size()+start;
	if(length>1) {
		end = c->getArgument("end")->getInt();
		if(slice && end<0) end = str.size()+end;
	}
	if(!slice && end < start) { end^=start; start^=end; end^=start; }
	if(start<0) start = 0;
	if(start>=(int)str.size()) 
		c->setReturnVar(c->newScriptVar(""));
	else if(end <= start)
		c->setReturnVar(c->newScriptVar(""));
	else
		c->setReturnVar(c->newScriptVar(str.substr(start, end-start)));
}
static void scTrace(const CFunctionsScopePtr &c, void * userdata) {
	CTinyJS *js = (CTinyJS*)userdata;
	if(c->getArgumentsLength())
		c->getArgument(0)->trace();
	else
		js->getRoot()->trace("root");
}
static void scStringConcat(const CFunctionsScopePtr &c, void *userdata) {
	int length = c->getArgumentsLength();
	string str = this2string(c);
	for(int32_t i=ptr2int32(userdata); i<length; i++)
		str.append(c->getArgument(i)->toString());
	c->setReturnVar(c->newScriptVar(str));
}
static void scStringConcat(const CFunctionsScopePtr &c, void *userdata) {
	int length = c->getArgumentsLength();
	string str = c->getArgument("this")->getString();
	for(int i=(int)userdata; i<length; i++)
		str.append(c->getArgument(i)->getString());
	c->setReturnVar(c->newScriptVar(str));
}
static void scArrayPush(const CFunctionsScopePtr &c, void *data) {
	CScriptVarPtr arr = c->getArgument("this");
	int l = arr->getArrayLength();
	int args = c->getArgumentsLength();
	for (int i=0;i<args;i++)
		arr->setArrayIndex(l+i, c->getArgument(i));
}
Example #6
1
static void scArraySort(const CFunctionsScopePtr &c, void *data) {
	CScriptVarPtr arr = c->getArgument("this");
	CScriptVarFunctionPtr cmp_fnc; 
	uint32_t len = arr->getLength();
	if(len > 1) {
		int args = c->getArgumentsLength();
		if(args) {
			cmp_fnc = c->getArgument(0);
			if(!cmp_fnc) c->throwError(TypeError, "invalid Array.prototype.sort argument");
		}
		SCRIPTVAR_CHILDS_it begin = lower_bound(arr->Childs.begin(), arr->Childs.end(), "0");
		/* in ECMAScript the sort algorithm is not specified
		 * in some cases sort throws a TypeError e.G. an array element is read-only, non-configurable, getter or setter
		 * this will result in a partially sorted array 
		 * in worst case the sort algorithm results in an endless loop (more getters with constant return value)
		 *
		 * 42TinyJS checks before sort if an element read-only, setter or getter and throws immediately a TypeError
		 */
		for(SCRIPTVAR_CHILDS_it it = begin; it != arr->Childs.end(); ++it) {
			if(!(*it)->isWritable()) c->throwError(TypeError, "property "+(*it)->getName()+" is read-only");
			if(!(*it)->isConfigurable()) c->throwError(TypeError, "property "+(*it)->getName()+" is non-configurable");
			if(!(*it)->getVarPtr()->isAccessor()) c->throwError(TypeError, "property "+(*it)->getName()+" is a getter and/or a setter");
		}
		sort(begin, arr->Childs.end(), ::cmp_fnc(c, cmp_fnc));
		uint32_t idx = 0;
		for(SCRIPTVAR_CHILDS_it it=begin; it != arr->Childs.end(); ++it, ++idx)
			(*it)->reName(int2string(idx));
		sort(begin, arr->Childs.end(), cmp_by_name);
	}
	c->setReturnVar(arr);
}
Example #7
1
static void scArrayPush(const CFunctionsScopePtr &c, void *data) {
	CScriptVarPtr arr = c->getArgument("this");
	uint32_t len = c->getLength(arr);
	uint32_t args = c->getArgumentsLength();
	for (uint32_t i=0; i<args; ++i)
		c->setProperty(arr, i, c->getArgument(i));
}
static void scStringSubstr(const CFunctionsScopePtr &c, void *userdata) {
	string str = this2string(c);
	int32_t length = c->getArgumentsLength()-ptr2int32(userdata);
	int32_t start = c->getArgument("start")->toNumber().toInt32();
	if(start<0 || start>=(int)str.size()) 
		c->setReturnVar(c->newScriptVar(""));
	else if(length>1) {
		int length = c->getArgument("length")->toNumber().toInt32();
		c->setReturnVar(c->newScriptVar(str.substr(start, length)));
	} else
		c->setReturnVar(c->newScriptVar(str.substr(start)));
}
static void scStringSubstr(const CFunctionsScopePtr &c, void *userdata) {
	string str = c->getArgument("this")->getString();
	int length = c->getArgumentsLength()-(int)userdata;
	int start = c->getArgument("start")->getInt();
	if(start<0 || start>=(int)str.size()) 
		c->setReturnVar(c->newScriptVar(""));
	else if(length>1) {
		int length = c->getArgument("length")->getInt();
		c->setReturnVar(c->newScriptVar(str.substr(start, length)));
	} else
		c->setReturnVar(c->newScriptVar(str.substr(start)));
}
static void scStringSlice(const CFunctionsScopePtr &c, void *userdata) {
	string str = this2string(c);
	int32_t length = c->getArgumentsLength()-(ptr2int32(userdata) & 1);
	bool slice = (ptr2int32(userdata) & 2) == 0;
	int32_t start = c->getArgument("start")->toNumber().toInt32();
	int32_t end = (int32_t)str.size();
	if(slice && start<0) start = (int32_t)(str.size())+start;
	if(length>1) {
		end = c->getArgument("end")->toNumber().toInt32();
		if(slice && end<0) end = (int32_t)(str.size())+end;
	}
	if(!slice && end < start) { end^=start; start^=end; end^=start; }
	if(start<0) start = 0;
	if(start>=(int)str.size()) 
		c->setReturnVar(c->newScriptVar(""));
	else if(end <= start)
		c->setReturnVar(c->newScriptVar(""));
	else
		c->setReturnVar(c->newScriptVar(str.substr(start, end-start)));
}