Exemplo n.º 1
0
/* todo regex */
static int strpto_indexOf(PSTATE *ps, Value *args, Value *_this, Value *ret, int asc)
{
	if (asc) die("Execute String.prototype.indexOf as constructor\n");
	if (_this->vt != VT_OBJECT || _this->d.obj->ot != OT_STRING) {
		die("apply String.prototype.indexOf to a non-string object\n");
	}

	unichar *v = _this->d.obj->d.str;
	Value *seq = value_object_lookup_array(args, 0, NULL);
	Value *start = value_object_lookup_array(args, 1, NULL);

	if (!seq) {
		value_make_number(*ret, -1);
		return 0;
	}

	value_tostring(seq);
	unichar *vseq = seq->d.str;
	
	int istart = 0;
	if (start && is_number(start)) {
		istart = (int) start->d.num;
		if (istart < 0) istart = 0;
	}

	int r = unistrpos(v, istart, vseq);
	value_make_number(*ret, r);

	return 0;
}
Exemplo n.º 2
0
int main(int argc,  const char **argv)
{
    ArgState *state = arg_command_line(args,argv);
    if (! interactive) {
        if (array_len(incdirs) > 0) {
            printf("the include paths\n");
            FOR_ARR (str_t,P,incdirs)
                printf("'%s'\n",*P);
        }
        if (array_len(string_args) > 0) {
            printf("the string args\n");
            FOR_ARR (str_t,P,string_args)
                printf("'%s'\n",*P);
        }
        printf("flag a is %d\n",a);
    } else {
        char *line;
            printf("> ");
        while ((line = file_getline(stdin)) != NULL) {
            char **parts = str_split(line," ");
            // args_process assumes args start at second element, hence -1 here
            PValue v = arg_process(state,(const char**)parts-1);
            if (v != NULL) {
                printf("%s\n",value_tostring(v));
                unref(v);
            }
            dispose(parts,line);
            printf("> ");
            arg_reset_used(state);
        }        
    }
    return 0;
}
Exemplo n.º 3
0
/* charCodeAt */
static int strpto_charCodeAt(PSTATE *ps, Value *args, Value *_this, Value *ret, int asc)
{
	if (asc) die("Execute String.prototype.charCodeAt as constructor\n");

	Value target = { 0 };
	value_copy(target, *_this);
	value_tostring(&target);
	
	int slen = unistrlen(target.d.str);
	int pos = 0;
	Value *vpos;
	if ((vpos = value_object_lookup_array(args, 0, NULL))) {
		value_toint32(vpos);
		pos = (int)vpos->d.num;
	}

	if (pos < 0 || pos >= slen) {
		value_make_number(*ret, ieee_makenan());
	} else {
		value_make_number(*ret, target.d.str[pos]);
	}
	value_erase(target);
	return 0;
}
Exemplo n.º 4
0
int eval(PSTATE *ps, OpCodes *opcodes, 
		 ScopeChain *scope, Value *currentScope, 	/* scope chain */
		 Value *_this,
		 Value *vret)
{
	int context_id = ps->_context_id++;
	OpCode *ip = &opcodes->codes[0];
	OpCode *end = &opcodes->codes[opcodes->code_len];
	TryList *trylist = NULL;
	
	if (currentScope->vt != VT_OBJECT) {
		bug("Eval: current scope is not a object\n");
	}
	
	while(ip < end) {
#ifdef DEBUG
		int i;
		printf("STACK%d: ", sp);
		for (i = 0; i < sp; ++i) {
			printf("%s ", vprint(&stack[i]));
		}
		printf("\tthis: %s ", vprint(_this));
		TryList *tlt = trylist;
		for (i = 0; tlt; tlt = tlt->next) i++;
		printf("TL: %d, excpt: %s\n", i, vprint(&ps->last_exception));
		code_decode(ip, ip - opcodes->codes);

		
#endif
		switch(ip->op) {
			case OP_NOP:
			case OP_LASTOP:
				break;
			case OP_PUSHNUM:
				value_make_number(stack[sp], (*((double *)ip->data)));
				sp++;
				break;
			case OP_PUSHSTR:
				value_make_string(stack[sp], unistrdup(ip->data));
				sp++;
				break;
			case OP_PUSHVAR: {
				FastVar *n = ip->data;
				Value *v = NULL;
				if (n->context_id == context_id) {
					v = n->var.lval;
				} else {
					unichar *varname = n->var.varname;
					v = value_object_lookup(currentScope, (ObjKey *)varname, NULL);
					if (!v) v = scope_chain_object_lookup(scope, (ObjKey *)varname);

					if (!v) {	/* add to global scope */
						Value *global_scope = scope->chains_cnt > 0 ? scope->chains[0]:currentScope;
						Value key;
						value_make_string(key, varname);	/* varname is not dupped, do not erase*/
						Value val;
						value_make_undef(val);
						v = value_object_key_assign(global_scope, &key, &val, OM_DONTEMU);
						
						/* key assign dup key and insert into object, so release ourself */
					}
					n->context_id = context_id;
					n->var.lval = v;
				}
				stack[sp].vt = VT_VARIABLE;
				stack[sp].d.lval = v;
				sp++;
				break;
			}
			case OP_PUSHUND:
				value_make_undef(stack[sp]);
				sp++;
				break;
			case OP_PUSHBOO:
				value_make_bool(stack[sp], (int)ip->data);
				sp++;
				break;
			case OP_PUSHFUN: {
				FuncObj *fo = funcobj_new((Func *)ip->data);
				fo->scope =	scope_chain_dup_next(scope, currentScope);
				
				Object *obj = object_new();
				obj->ot = OT_FUNCTION;
				obj->d.fobj = fo;
				obj->__proto__ = Function_prototype;
				
				Value *fun_prototype = value_object_utils_new_object();
				fun_prototype->d.obj->__proto__ = Object_prototype;
				
				value_make_object(stack[sp], obj);
				
				value_object_utils_insert(&stack[sp], PROTOTYPE.unistr, fun_prototype, 0, 1, 0);
				/* todo: make own prototype and prototype.constructor */
				sp++;
				break;
			}
			case OP_PUSHREG: {
				Object *obj = object_new();
				obj->ot = OT_REGEXP;
				obj->d.robj = (regex_t *)ip->data;
				obj->__proto__ = RegExp_prototype;

				value_make_object(stack[sp], obj);
				sp++;
				break;
			}
			case OP_PUSHARG:
				value_copy(stack[sp], *currentScope);
				sp++;
				break;
			case OP_PUSHTHS:
				value_copy(stack[sp], *_this);
				sp++;
				break;
			case OP_PUSHTOP:
				value_copy(stack[sp], TOP);
				sp++;
				break;
			case OP_UNREF:
				topeval1();
				break;
			case OP_PUSHTOP2:
				value_copy(stack[sp], TOQ);
				value_copy(stack[sp+1], TOP);
				sp += 2;
				break;
			case OP_CHTHIS: {
				int t = sp - 2;
				if (ip->data) {
					value_erase(obj_this[t]);
					value_copy(obj_this[t], TOQ);
					if (obj_this[t].vt == VT_VARIABLE) {
						Value *v = obj_this[t].d.lval;
						value_copy(obj_this[t], *v);
					}
					value_toobject(&obj_this[t]);
				}
				break;
			}
			case OP_LOCAL: {
				ObjKey *strkey = objkey_new((const unichar *)ip->data, OM_DONTEMU);
				value_object_insert(currentScope, strkey, value_new());
				
				/* make all FastVar to be relocated */
				context_id = ps->_context_id++;
				break;
			}
			case OP_POP:
				pop_n(ip->data);
				break;
			case OP_NEG:
				topeval1();
				value_tonumber(&TOP);
				TOP.d.num = -(TOP.d.num);
				break;
			case OP_POS:
				topeval1();
				value_tonumber(&TOP);
				break;
			case OP_NOT: {
				int val = 0;
				topeval1();
				
				val = value_istrue(&TOP);
				
				value_erase(TOP);
				value_make_bool(TOP, !val);
				break;
			}
			case OP_BNOT: {
				topeval1();
				value_toint32(&TOP);
				TOP.d.num = (double)(~((int)TOP.d.num));
				break;
			}
			case OP_ADD: {
				topeval2();
				value_toprimitive(&TOP);
				value_toprimitive(&TOQ);
				
				if (TOP.vt == VT_STRING || TOQ.vt == VT_STRING) {
					value_tostring(&TOP);
					value_tostring(&TOQ);
					
					unichar *v = unistrcat(TOQ.d.str, TOP.d.str);
					
					value_erase(TOQ);
					value_make_string(TOQ, v);
				} else {
					value_tonumber(&TOP);
					value_tonumber(&TOQ);
					double n = TOP.d.num + TOQ.d.num;
					value_erase(TOQ);
					value_make_number(TOQ, n);
				}
				pop();
				break;
			}
			case OP_SUB:	/* god, the notes in ecma is so long, pray to run correctly */
				common_math_opr(-); break;
			case OP_MUL:
				common_math_opr(*); break;
			case OP_DIV:
				common_math_opr(/); break;
			case OP_MOD: {
				topeval2();
				if (!is_number(&TOP)) value_tonumber(&TOP);
				if (!is_number(&TOQ)) value_tonumber(&TOQ);

				TOQ.d.num = fmod(TOQ.d.num, TOP.d.num);
				pop();
				break;
			}
			case OP_LESS:
				topeval2();
				logic_less(TOQ, TOP, TOQ);
				pop();
				break;
			case OP_GREATER:
				topeval2();
				logic_less(TOP, TOQ, TOQ);
				pop();
				break;
			case OP_LESSEQU:
				topeval2();
				logic_less(TOP, TOQ, TOQ);
				TOQ.d.val = !TOQ.d.val;
				pop();
				break;
			case OP_GREATEREQU:
				topeval2();
				logic_less(TOQ, TOP, TOQ);
				TOQ.d.val = !TOQ.d.val;
				pop();
				break;
			case OP_EQUAL:
			case OP_NOTEQUAL: {		/* awful, equal opration */
				int r = 0;
				topeval2();
				if (TOP.vt != TOQ.vt) {
					value_toprimitive(&TOP);
					value_toprimitive(&TOQ);
				}
				if (TOP.vt != TOQ.vt) {
					if ((is_undef(&TOP) || is_null(&TOP)) && 
						(is_undef(&TOQ) || is_null(&TOQ))) {
						r = 1;
					} else {
						value_tonumber(&TOP);
						value_tonumber(&TOQ);
						r = (TOP.d.num == TOQ.d.num);
					}
				} else {
					switch (TOP.vt) {
						case VT_NUMBER:
							r = (TOP.d.num == TOQ.d.num);
							break;
						case VT_BOOL:
							r = (TOP.d.val == TOQ.d.val);
							break;
						case VT_STRING:
							r = (unistrcmp(TOQ.d.str, TOP.d.str) == 0);
							break;
						case VT_OBJECT:
							/* todo: refer to objects joined to each other */
							r = (TOP.d.obj == TOQ.d.obj);
							break;
						case VT_UNDEF:
						case VT_NULL:
							r = 1;
							break;
						default:
							bug("Unexpected value type\n");
					}
				}
				r = (ip->op == OP_EQUAL ? r : !r);
				value_erase(TOQ);
				value_make_bool(TOQ, r);
				pop();
				break;
			}
			case OP_STRICTEQU:
			case OP_STRICTNEQ: {
				int r = 0;
				topeval2();
				if (TOP.vt == TOQ.vt) {
					switch (TOP.vt) {
						case VT_NUMBER:
							r = (TOP.d.num == TOQ.d.num);
							break;
						case VT_BOOL:
							r = (TOP.d.val == TOQ.d.val);
							break;
						case VT_STRING:
							r = (unistrcmp(TOQ.d.str, TOP.d.str) == 0);
							break;
						case VT_OBJECT:
							/* todo: refer to objects joined to each other */
							r = (TOP.d.obj == TOQ.d.obj);
							break;
						case VT_UNDEF:
						case VT_NULL:
							r = 1;
							break;
						default:
							bug("Unexpected value type\n");
					}
				}
				r = (ip->op == OP_STRICTEQU ? r : !r);
				value_erase(TOQ);
				value_make_bool(TOQ, r);
				pop();
				break;
			}
			case OP_BAND: 
				common_bitwise_opr(&); break;
			case OP_BOR:
				common_bitwise_opr(|); break;
			case OP_BXOR:
				common_bitwise_opr(^); break;
			case OP_SHF: {
				topeval2();
				value_toint32(&TOQ);
				value_toint32(&TOP);
				int t1 = (int)TOQ.d.num;
				int t2 = ((unsigned int)TOP.d.num) & 0x1f;
				if (ip->data) {					/* thift right */
					if ((int)ip->data == 2) {	/* unsigned shift */
						unsigned int t3 = (unsigned int)t1;
						t3 >>= t2;
						value_make_number(TOQ, t3);
					} else {
						t1 >>= t2;
						value_make_number(TOQ, t1);
					}
				} else {
					t1 <<= t2;
					value_make_number(TOQ, t1);
				}
				pop();
				break;
			}