/* 将response提交到queue中, 并且销毁 */ int JsSubmitResponse(struct JsObject* obj){ if(strcmp(obj->Class,"Response")!=0) JsThrowString("The Object Is't Response"); struct JsResponse* response = (struct JsResponse*)obj->sb[JS_RESPONSE_FLOOR]; if(response == NULL) JsThrowString("The Response Is Burned"); struct MHD_Response *HTMLResponse = NULL; //构建HTML response HTMLResponse = MHD_create_response_from_buffer (response->bUsed, (void *) response->body, MHD_RESPMEM_MUST_COPY); //配置header int i; for(i=0;i<response->hUsed;++i){ MHD_add_response_header (HTMLResponse, response->header[i].key, response->header[i].value); } //配置状态码 int ret = MHD_queue_response (response->connection, response->code, HTMLResponse); MHD_destroy_response (HTMLResponse); //释放内存 free(response->body); for(i=0;i<response->hUsed;++i){ free(response->header[i].key); free(response->header[i].value); } free(response->header); free(response); obj->sb[JS_RESPONSE_FLOOR] = NULL; return ret; }
static void clear(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(strcmp(thisobj->Class,"Response")!=0) JsThrowString("The Object Is't Response"); struct JsResponse* response = (struct JsResponse*)thisobj->sb[JS_RESPONSE_FLOOR]; if(response == NULL) JsThrowString("The Response Is Burned"); response->bUsed = 0; }
static void setStatus(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(strcmp(thisobj->Class,"Response")!=0) JsThrowString("The Object Is't Response"); if(argc >= 1 && argv[0]->type == JS_NUMBER && argv[0]->u.number >=0){ struct JsResponse* response = (struct JsResponse*)thisobj->sb[JS_RESPONSE_FLOOR]; if(response == NULL) JsThrowString("The Response Is Burned"); response->code = argv[0]->u.number; }else{ JsThrowString("setStatus Args Is Error"); } }
static void JsStringProtoToString(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ //只有对应的对象类 String 才能使用该函数 if(strcmp(thisobj->Class,"String") != 0) JsThrowString("TypeError"); res->type =JS_STRING; res->u.string = (char*)thisobj->sb[JS_STRING_FLOOR]; }
void JsToBoolean(struct JsValue *val, struct JsValue *res){ res->type = JS_BOOLEAN; switch (val->type) { case JS_UNDEFINED: case JS_NULL: res->u.boolean = FALSE; break; case JS_BOOLEAN: *res = * val; break; case JS_NUMBER: if (val->u.number == 0 || isnan(val->u.number)) res->u.boolean = FALSE; else res->u.boolean = TRUE; break; case JS_STRING: if (val->u.string == NULL || strlen(val->u.string) == 0) res->u.boolean = FALSE; else res->u.boolean = TRUE; break; case JS_OBJECT: res->u.boolean = TRUE; break; default: JsThrowString("JsToBooleanError"); } }
static void JsArrayInstPut(struct JsObject *self,char *prop, struct JsValue *value, int flags){ struct JsValue v; struct JsValue v0; if(strcmp(prop,"length") == 0){ if(value->type != JS_NUMBER || value->u.number < 0) JsThrowString("RangeError"); (*self->Get)(self,"length",NULL,&v); if(v.type == JS_NUMBER){ int i; for( i=value->u.number ; i< v.u.number;++i){ //计算bit int number = i; int bit = 0; while(number){ number /=10; bit++; } char* buf = (char*)JsGcMalloc(bit+4,NULL,NULL); sprintf(buf,"%d",i); //删除不在新范围内的数组元素 (*self->Delete)(self,buf,&v0); } } }else{ //判断是否是array Index char *endptr = NULL; long index = 0; index = strtol(prop,&endptr,10); if(*endptr == '\0'){ //说明该prop被完全解析为数据=>prop为array index (*self->Get)(self,"length",NULL,&v); if(v.type != JS_NUMBER || v.u.number < 0) JsThrowString("RangeError"); if(index >= v.u.number){ //如果大于length, 则需要重新写入length struct JsValue* l = JsCreateValue(); l->type = JS_NUMBER; l->u.number = index + 1; //修改length //不使用self->Put, 而直接调用父类的Put JsStandardPut(self,"length",l,JS_OBJECT_ATTR_DONTENUM | JS_OBJECT_ATTR_DONTDELETE); } } } //写入数据 JsStandardPut(self,prop,value,flags); }
/*15.3.4.4*/ static void JsFunctionProtoCallCall(struct JsObject *obj, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ struct JsObject* this0; int argc0; struct JsValue** argv0; if(thisobj == NULL){ JsThrowString("null point this"); return; } if(thisobj->Call == NULL){ JsThrowString("TypeError"); return; } if(argc == 0){ this0 = JsGetVm()->Global; argc0 = 0; argv0 = NULL; }else if(argc == 1){ if(argv[0]->type == JS_NULL || argv[0]->type == JS_UNDEFINED){ this0 = JsGetVm()->Global; }else{ struct JsValue o; JsToObject(argv[0],&o); this0 = o.u.object; } argc0 = 0; argv0 = NULL; }else if(argc >= 2){ //this if(argv[0]->type != JS_NULL && argv[0]->type != JS_UNDEFINED){ this0 = JsGetVm()->Global; }else{ struct JsValue o; JsToObject(argv[0],&o); this0 = o.u.object; } argc0 = argc - 1; argv0 = &argv[1]; }else{ //argc大小错误 JsAssert(FALSE); } (*thisobj->Call)(thisobj,this0,argc0,argv0,res); }
static void setHeader(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(strcmp(thisobj->Class,"Response")!=0) JsThrowString("The Object Is't Response"); if(argc >= 2 && argv[0]->type == JS_STRING && argv[0]->u.string != NULL && argv[1]->type == JS_STRING && argv[1]->u.string != NULL){ struct JsResponse* response = (struct JsResponse*)thisobj->sb[JS_RESPONSE_FLOOR]; if(response == NULL) JsThrowString("The Response Is Burned"); int i; int flag = TRUE; //判断是否已经存在该Header Key for(i=0;i<response->hUsed;++i){ if(strcmp(response->header[i].key,argv[0]->u.string) == 0){ //已经存在Key在Head中, 仅仅使用覆盖的方式 flag = FALSE; //释放先前的内存 free(response->header[i].value); char* value = (char*)malloc(strlen(argv[1]->u.string)+4); strcpy(value,argv[1]->u.string); response->header[i].value = value; break; } } if(flag == TRUE){ //先前不存在Key对应的Header //检验空间是否足够 if(response->hUsed == response->hTotal){ response->hTotal += 2; //申请新空间 response->header = realloc(response->header,sizeof(struct JsHeader)*response->hTotal); } response->header[response->hUsed].key = (char*)malloc(strlen(argv[0]->u.string)+4); response->header[response->hUsed].value = (char*)malloc(strlen(argv[1]->u.string)+4); strcpy(response->header[response->hUsed].key,argv[0]->u.string); strcpy(response->header[response->hUsed].value,argv[1]->u.string); response->hUsed++; } }else{ JsThrowString("Response Args Is Error"); } }
void JsToObject(struct JsValue *val, struct JsValue *res){ struct JsValue *argv[1]; struct JsValue con0; struct JsValue *con; argv[0] = val; res->type = JS_OBJECT; switch (val->type) { case JS_UNDEFINED: case JS_NULL: JsThrowString("TypeError"); break; case JS_OBJECT: *res = *val; //直接返回, 不需要构建了 return; case JS_BOOLEAN: JsFindValue(NULL,"Boolean",&con0); break; case JS_NUMBER: JsFindValue(NULL,"Number",&con0); break; case JS_STRING: JsFindValue(NULL,"String",&con0); break; default: JsThrowString("JsToObjectError"); return; } //变换 con = &con0; if( con->type != JS_OBJECT || con->u.object == NULL || con->u.object->Construct == NULL){ JsPrintString("TypeError"); //JsThrowString("TypeError"); //直接中断程序 JsAssert(FALSE); return; } //构造 (*con->u.object->Construct)(con->u.object,JsGetVm()->Global, 1, argv, res); }
static void write0(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(strcmp(thisobj->Class,"Response")!=0) JsThrowString("The Object Is't Response"); if(argc >= 1 && argv[0]->type == JS_STRING && argv[0]->u.string != NULL){ struct JsResponse* response = (struct JsResponse*)thisobj->sb[JS_RESPONSE_FLOOR]; if(response == NULL) JsThrowString("The Response Is Burned"); int sizeOfString = strlen(argv[0]->u.string); //检查空间大小 if(response->bUsed + sizeOfString > response->bTotal){ //增加空间 response->bTotal += response->bUsed*2 + sizeOfString + 4; response->body = realloc(response->body,response->bTotal); } memcpy(&response->body[response->bUsed],argv[0]->u.string,sizeOfString); //大小变大 response->bUsed+=sizeOfString; }else{ JsThrowString("setStatus Args Is Error"); } }
void JsPutValue(struct JsValue* v,struct JsValue* w,struct JsValue* res){ struct JsObject *target; res->type = JS_BOOLEAN; if (v->type != JS_REFERENCE){ JsThrowString("ReferenceError"); return; } target = v->u.reference.base; if (target == NULL) target = JsGetVm()->Global; (*target->Put)(target, v->u.reference.name, w, JS_OBJECT_ATTR_DEFAULT); res->u.boolean = TRUE; return; }
/* 相当于把string字符串放置在当前环境下执行. */ static void JsGlobalEval(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res) { int saveVarattr; //检查参数是否正确 if(argc <=0) { res->type =JS_UNDEFINED; return; } else if( argv[0]->type != JS_STRING) { *res = *argv[0]; return; } //从线程中获得JsEngine struct JsEngine* e = JsGetTlsEngine(); //处理上下文 /*Stack, Scope, This 都使用当前Context*/ saveVarattr = e->exec->varattr; e->exec->varattr = JS_OBJECT_ATTR_DEFAULT; //执行函数 res->type =JS_UNDEFINED; struct JsAstNode * ast; ast = JsParseString(e->vm->debug ? JS_PARSER_DEBUG_ERROR : JS_PARSER_DEBUG_CLOSE,argv[0]->u.string); if(ast == NULL) JsThrowString("SytaxError"); JsEval(e,ast,res); //还原环境 e->exec->varattr = saveVarattr; //结果处理 if(res->type == JS_COMPLETION) { if(res->u.completion.type == JS_COMPLETION_RETURN) { *res = *res->u.completion.value; } else if(res->u.completion.type == JS_COMPLETION_THROW) { //不处理 } else { //JS_COMPLETION_NORMAL, JS_COMPLETION_BREAK, JS_COMPLETION_CONTINUE res->type = JS_UNDEFINED; } } else if(res->type == JS_REFERENCE) { res->type = JS_UNDEFINED; }//res->type = JS_OBJECT, JS_NULL, JS_BOOLEAN ... return; }
/* JsReference */ void JsGetValue(struct JsValue* v, struct JsValue* res){ if (v->type != JS_REFERENCE) { *res = *v; return; } if (v->u.reference.base == NULL){ JsThrowString("ReferenceError"); return; } //do get (*v->u.reference.base->Get)(v->u.reference.base,v->u.reference.name,NULL,res); }
void JsToString(struct JsValue *val, struct JsValue *res){ res->type = JS_STRING; switch (val->type) { case JS_UNDEFINED: res->u.string = "undefined"; break; case JS_NULL: res->u.string = "null"; break; case JS_BOOLEAN:{ if(val->u.boolean == TRUE) res->u.string ="true"; else res->u.string = "false"; break; } case JS_NUMBER:{ /* 9.8.1 */ char* buf; double value ; value = val->u.number; //最大长度为128位 buf = (char*)JsMalloc(128); if(value - (int)value == 0){ //整数 sprintf(buf,"%d",(int)value); }else{ sprintf(buf,"%f",value); } res->u.string = buf; break; } case JS_STRING: *res = *val; break; case JS_OBJECT:{ struct JsValue prim; JsToPrimitive(val,JS_OBJECT_HIT_TYPE_STRING, &prim); JsToString(&prim, res); break; } default: JsThrowString("JsToStringError"); } }
void JsToNumber(struct JsValue *val, struct JsValue *res){ res->type = JS_NUMBER; switch (val->type) { case JS_UNDEFINED: res->u.number = JS_VALUE_NUMBER_NAN; break; case JS_NULL: res->u.number = 0.0; break; case JS_BOOLEAN: res->u.number = (val->u.boolean ? 1.0 : 0.0); break; case JS_NUMBER: *res = *val; break; case JS_STRING:{ char * szOrbits, *pEnd; double d1; szOrbits = val->u.string; d1 = strtod (szOrbits,&pEnd); if(*pEnd == '\0'){ res->u.number = d1; }else{ //如果不是字符串末尾, 则表示没有解析完该字符串 res->u.number = JS_VALUE_NUMBER_NAN; } break; } case JS_OBJECT:{ struct JsValue primitive; JsToPrimitive(val,JS_OBJECT_HIT_TYPE_NUMBER,&primitive); JsToNumber(&primitive, res); break; } default: JsThrowString("JsToNumbeError"); } }
//Array.prototype.toString static void JsArrayProtoToString(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(strcmp(thisobj->Class,"Array") != 0) JsThrowString("TypeError"); JsArrayProtoJoin(NULL,thisobj,0,NULL,res); }
/*15.3.4.3*/ static void JsFunctionProtoApplyCall(struct JsObject *obj, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ struct JsObject* this0; int argc0; struct JsValue** argv0; if(thisobj == NULL){ JsThrowString("null point this"); return; } if(thisobj->Call == NULL){ JsThrowString("TypeError"); return; } if(argc == 0){ this0 = JsGetVm()->Global; argc0 = 0; argv0 = NULL; }else if(argc == 1){ if(argv[0]->type == JS_NULL || argv[0]->type == JS_UNDEFINED){ this0 = JsGetVm()->Global; }else{ struct JsValue o; JsToObject(argv[0],&o); this0 = o.u.object; } argc0 = 0; argv0 = NULL; }else if(argc >= 2){ //this if(argv[0]->type == JS_NULL || argv[0]->type == JS_UNDEFINED){ this0 = JsGetVm()->Global; }else{ struct JsValue o; JsToObject(argv[0],&o); this0 = o.u.object; } //argc argv if(argv[1]->type == JS_NULL || argv[1]->type == JS_UNDEFINED){ argc0 = 0; argv0 = NULL; }else{ //测试argv[1]是否为OBJECT并且为Array类型 if(argv[1]->type != JS_OBJECT || strcmp(argv[1]->u.object->Class,"Array") !=0 ){ JsThrowString("TypeError"); return; } struct JsValue v ; (*argv[1]->u.object->Get)(argv[1]->u.object,"length",NULL,&v); if(v.type != JS_NUMBER){ JsThrowString("TypeError"); return; } argc0 = v.u.number; argv0 = (struct JsValue**)JsMalloc(sizeof(struct JsValue*)* argc0); //计算最大位数 int number = argc0; int size = 0; int i = 0; while(number){ number /=10; size++; } char* buf = (char*)JsMalloc(size + 4); //组建Argv0 for(i =0 ; i < argc0;++i){ sprintf(buf,"%d",i); (*argv[1]->u.object->Get)(argv[1]->u.object,buf,NULL,&v); argv0[i] = (struct JsValue*)JsMalloc(sizeof(struct JsValue)); *argv0[i] = v; } } }else{ //argc大小错误 JsAssert(FALSE); } (*thisobj->Call)(thisobj,this0,argc0,argv0,res); }