//---------------------------------------------------------------------------- //创建一个Array对象, prototype 为NULL表示指向 Object_prototype //如果argv == NULL 表示不需要添加具体的元素 static struct JsObject* JsCreateArray(struct JsObject* prototype, int length, struct JsValue** argv){ //创建一个标准的对象 struct JsObject* array = JsCreateStandardObject(NULL); if(prototype != NULL) array->Prototype = prototype; struct JsValue* vLength = JsCreateValue(); vLength->type = JS_NUMBER; vLength->u.number = length; array->Class = "Array"; (*array->Put)(array,"length",vLength,JS_OBJECT_ATTR_DONTENUM | JS_OBJECT_ATTR_DONTDELETE); //构建[item...] int i; for( i = 0 ; i < length && argv != NULL ;++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); (*array->Put)(array,buf,argv[i],JS_OBJECT_ATTR_DEFAULT); } //修改Put array->Put = &JsArrayInstPut; return array; }
JsList JsListCopy(JsList dst,JsList src){ int i; struct JsNode** npp1; struct JsNode** npp2; struct JsNode* np; struct JsNodeHead* head; struct JsNodeHead* p ; JsAssert(dst != NULL && src != NULL); head = src; p = dst; //没有空间或者超出范围 if(head->size == 0){ p->size = 0; return p; } npp1 = &head->first; npp2 = &p->first; p->size = head->size; for( i = 0 ; i < head->size ;++i){ np = JsGcMalloc(sizeof(struct JsNode),&JsGcMarkNode,NULL); np->data = (*npp1)->data; np->next = NULL; (*npp2) = np; npp1 = &(*npp1)->next; npp2 = &(*npp2)->next; } return p; }
static void JsArrayProtoPush(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ if(argc <= 0){ res->type = JS_NUMBER; res->u.number = 0; return; } struct JsValue vLength; (*thisobj->Get)(thisobj,"length",NULL,&vLength); int begin = 0; if(vLength.type == JS_NUMBER){ begin = vLength.u.number > 0 ? vLength.u.number : 0; } int i; for( i= begin ; i < begin+argc ;++i){ int number = i; int bit = 0 ; while(number){ number /= 10; bit++; } char* buf = (char*)JsGcMalloc(bit + 4,NULL,NULL); sprintf(buf,"%d",i); (*thisobj->Put)(thisobj,buf,argv[i - begin],JS_OBJECT_ATTR_DEFAULT); } struct JsValue* l = JsCreateValue(); l->type = JS_NUMBER; l->u.number = begin + argc; (*thisobj->Put)(thisobj,"length",l,JS_OBJECT_ATTR_DONTENUM | JS_OBJECT_ATTR_DONTDELETE); }
static void CreatePrintFn(){ char** argv = JsGcMalloc(sizeof(char*) * 1,NULL,NULL); argv[0] = "value"; //创建PrintFunction struct JsObject* print = JsCreateStandardSpecFunction(NULL,NULL,1,argv, &JsPrintFn,NULL,"print",FALSE); struct JsValue* vPrint = JsCreateValue(); vPrint->type = JS_OBJECT; vPrint->u.object = print; (*JsGetVm()->Global->Put)(JsGetVm()->Global,"print",vPrint,JS_OBJECT_ATTR_STRICT); }
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); }
void JsListPush(void* head0,void* data){ int i; struct JsNode** npp;//指向最末端 struct JsNode* np; struct JsNodeHead* head ; JsAssert(head0 != NULL); head = head0; npp = &head->first; for( i = 0 ; i < head->size; ++i){ npp = &(*npp)->next; } np = JsGcMalloc(sizeof(struct JsNode),&JsGcMarkNode,NULL); np->data = data; np->next = NULL; (*npp) = np; (head)->size++; }
static void JsArrayProtoPop(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ struct JsValue vLength; struct JsValue v; (*thisobj->Get)(thisobj,"length",NULL,&vLength); if(vLength.type == JS_NUMBER && vLength.u.number > 0){ int number = vLength.u.number; int bit = 0; while(number){ number /= 10; bit++; } char* buf = (char*)JsGcMalloc(bit+4,NULL,NULL); sprintf(buf,"%d",(int)(vLength.u.number - 1)); (*thisobj->Get)(thisobj,buf,NULL,res); (*thisobj->Delete)(thisobj,buf,&v); struct JsValue* l = JsCreateValue(); l->type = JS_NUMBER; l->u.number = vLength.u.number - 1; (*thisobj->Put)(thisobj,"length",l,JS_OBJECT_ATTR_DONTENUM | JS_OBJECT_ATTR_DONTDELETE); }else res->type = JS_UNDEFINED; }
JsList JsCreateList(){ return (JsList)JsGcMalloc(sizeof(struct JsNodeHead),&JsGcMarkNodeHead,NULL); }
/* 最后的格式为 string,string...,string */ static void JsArrayProtoJoin(struct JsObject *self, struct JsObject *thisobj, int argc, struct JsValue **argv, struct JsValue *res){ struct JsValue r; struct JsValue s; struct JsValue v; int length; char* sep = ","; //长度获取 (*thisobj->Get)(thisobj,"length",NULL,&v); if(v.type == JS_UNDEFINED || v.u.number <= 0){ res->type = JS_STRING; res->u.string = ""; return; } length = v.u.number; if(argc >= 1 && argv[0]->type != JS_UNDEFINED){ JsToString(argv[0],&v); sep = v.u.string; } //sep 的长度 int sepLength = strlen(sep); // "0" (*thisobj->Get)(thisobj,"0",NULL,&v); if(v.type == JS_NULL || v.type == JS_UNDEFINED){ s.type = JS_STRING; s.u.string =""; }else{ JsToString(&v,&s); } r.type = JS_STRING; int sizeOfMem = strlen(s.u.string)+sepLength+4; r.u.string = (char*)JsGcMalloc(sizeOfMem,NULL,NULL); strcpy(r.u.string,s.u.string); int k = 1; r10: if(length == k){ *res = r; return; } int number = k; int bit = 0 ; while(number){ number /= 10; bit ++; } char* cur = (char*)JsGcMalloc(bit+4,NULL,NULL); sprintf(cur,"%d",k); (*thisobj->Get)(thisobj,cur,NULL,&v); if(v.type == JS_UNDEFINED|| v.type == JS_NULL){ }else{ JsToString(&v,&s); sizeOfMem = sizeOfMem + sepLength + strlen(s.u.string); r.u.string = (char*)JsGcReAlloc(r.u.string,sizeOfMem); strcat(r.u.string,sep); strcat(r.u.string,s.u.string); } k++; goto r10; }