Просмотр исходного кода

Fix function bindenv to accept arrays too, also when a native function has an env set check it.
This fix allow to cache function calls to achieve speed gains see sample test-string-concatenation.nut .

mingodad 12 лет назад
Родитель
Сommit
6fb9942388

+ 237 - 0
SquiLu/samples/test-string-concatenation.nut

@@ -0,0 +1,237 @@
+local count = 100000;
+
+
+local start = os.clock();
+for(var k=0; k < count; ++k){
+	var text = "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+	text += "Hello";
+	text += " "
+	text += "World!";
+}
+print("String concatenation with + took:", os.clock()-start);
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	var text = "Hello" + " " + "World!" + "Hello" + " " + "World!" + "Hello" + " " + "World!" + "Hello" +
+		" " + "World!" + "Hello" + " " + "World!" + "Hello" + " " + "World!" + "Hello" + " " + "World!" +
+		"Hello" + " " + "World!";
+}
+print("String concatenation with + took:", os.clock()-start);
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	var buffer = [];
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+
+	var text = buffer.concat();
+}
+print("String concatenation with array.concat1 took:", os.clock()-start);
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	var buffer = array(24);
+	buffer.clear();
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+	buffer.push("Hello");
+	buffer.push(" ");
+	buffer.push("World!");
+
+	var text = buffer.concat();
+}
+print("String concatenation with array.concat2 took:", os.clock()-start);
+
+
+var buffer3 = array(24);
+print(type(buffer3))
+var push = buffer3.push.bindenv(buffer3);
+print(type(push), type(push.getenv()), type(push.getenv().ref()))
+
+{
+	buffer3.clear();
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+
+	print(buffer3.concat());
+
+}
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	buffer3.clear();
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+	push("Hello");
+	push(" ");
+	push("World!");
+
+	var text = buffer3.concat();
+}
+print("String concatenation with array.concat3 took:", os.clock()-start);
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	var buffer = array(24), i = 0;
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+	buffer[i++] = "Hello";
+	buffer[i++] = " ";
+	buffer[i++] = "World!";
+
+	var text = buffer.concat();
+}
+print("String concatenation with array2.concat took:", os.clock()-start);
+
+start = os.clock();
+for(var k=0; k < count; ++k){
+	var buffer = array(24), i = -1;
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+	buffer[++i] = "Hello";
+	buffer[++i] = " ";
+	buffer[++i] = "World!";
+
+	var text = buffer.concat();
+}
+print("String concatenation with array2.concat took:", os.clock()-start);

+ 2 - 3
SquiLu/squirrel/sqapi.cpp

@@ -35,9 +35,7 @@ bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPt
 
 SQInteger sq_aux_invalidtype(HSQUIRRELVM v,SQObjectType type)
 {
-    SQChar *buf = _ss(v)->GetScratchPad(100);
-	scsprintf(buf, _SC("unexpected type %s"), IdType2Name(type));
-	return sq_throwerror(v, buf);
+	return sq_throwerror(v, _SC("unexpected type %s"), IdType2Name(type));
 }
 
 HSQUIRRELVM sq_open(SQInteger initialstacksize)
@@ -539,6 +537,7 @@ SQRESULT sq_setfenv(HSQUIRRELVM v,SQInteger idx, SQBool cloning)
 		return sq_throwerror(v,_SC("the target is not a closure"));
     SQObjectPtr &env = stack_get(v,-1);
 	if(!sq_istable(env) &&
+		!sq_isarray(env) &&
 		!sq_isclass(env) &&
 		!sq_isinstance(env))
 		return sq_throwerror(v,_SC("invalid environment"));

+ 1 - 1
SquiLu/squirrel/sqbaselib.cpp

@@ -1868,7 +1868,7 @@ SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
 	{_SC("pacall"),closure_pacall,2, _SC("ca")},
 	{_SC("weakref"),obj_delegate_weakref,1, NULL },
 	{_SC("tostring"),default_delegate_tostring,1, _SC(".")},
-	{_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t")},
+	{_SC("bindenv"),closure_bindenv,2, _SC("c x|y|t|a")},
 	{_SC("setenv"),closure_setenv,2, _SC("c x|y|t")},
 	{_SC("getenv"),closure_getenv,1, _SC("c")},
 	{_SC("getinfos"),closure_getinfos,1, _SC("c")},

+ 13 - 4
SquiLu/squirrel/sqvm.cpp

@@ -1210,10 +1210,19 @@ bool SQVM::CallNative(SQNativeClosure *nclosure, SQInteger nargs, SQInteger newb
 	SQInteger tcs;
 	SQIntVec &tc = nclosure->_typecheck;
 	if((tcs = tc.size())) {
-		for(SQInteger i = 0; i < nargs && i < tcs; i++) {
-			if((tc._vals[i] != -1) && !(type(_stack._vals[newbase+i]) & tc._vals[i])) {
-				Raise_ParamTypeError(i,tc._vals[i],type(_stack._vals[newbase+i]));
-				return false;
+		for(SQInteger i = 0; i < nargs && i < tcs; i++) {
+			if(tc._vals[i] != -1) {
+				SQInteger ptype;
+				if(i==0 && nclosure->_env) {
+					//if nclosure->_env is set then check it instead
+					ptype = nclosure->_env->_obj._type;
+				}
+				else ptype = type(_stack._vals[newbase+i]);
+
+				if(!(ptype & tc._vals[i])) {
+					Raise_ParamTypeError(i,tc._vals[i],ptype);
+					return false;
+				}
 			}
 		}
 	}