Skip to content

Commit

Permalink
Working new, string length setter.
Browse files Browse the repository at this point in the history
  • Loading branch information
ndreynolds committed Oct 25, 2012
1 parent d6bc527 commit c6e0b26
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 52 deletions.
43 changes: 19 additions & 24 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fh_eval(JSValue *ctx, Node *node)
case NODE_OBJ: return fh_obj(ctx, node);
case NODE_ARR: return fh_arr(ctx, node);
case NODE_CALL: return fh_call(ctx, node);
case NODE_NEW: return fh_new_exp(ctx, node->e1);
case NODE_NEW: return fh_new_exp(ctx, node);
case NODE_MEMBER: return fh_member(ctx, node);
case NODE_IDENT: return fh_get_rec(ctx, node->sval);
case NODE_BLOCK: return fh_eval(ctx, node->e1);
Expand Down Expand Up @@ -126,12 +126,15 @@ fh_new_exp(JSValue *ctx, Node *exp)
{
JSValue *ctr;
JSArgs *args;
if (exp->e1->type == NODE_MEMBER) {
ctr = fh_eval(ctx, exp->e1->e1);
args = fh_build_args(ctx, exp->e1->e2);

// new F(x, y, z)
if (exp->e1 && exp->e1->type == NODE_MEMBER) {
ctr = fh_eval(ctx, exp->e1->e2);
args = fh_build_args(ctx, exp->e1->e1);
}
// new F
else {
ctr = fh_eval(ctx, exp);
ctr = fh_eval(ctx, exp->e1);
args = fh_new_args(0, 0, 0);
}

Expand All @@ -150,7 +153,7 @@ fh_new_exp(JSValue *ctx, Node *exp)
obj->proto = proto;

res = fh_function_call(ctx, obj, state, ctr, args);
return IS_OBJ(res) ? res : obj;
return IS_OBJ(res) || IS_FUNC(res) ? res : obj;
}


Expand Down Expand Up @@ -185,7 +188,7 @@ fh_arr(JSValue *ctx, Node *node)
while (!node->e1->visited) {
fh_set(arr, JSNUMKEY(i++)->string.ptr, fh_eval(ctx, pop_node(node->e1)));
}
fh_arr_set_len(arr, i);
fh_set_len(arr, i);
}
return arr;
}
Expand All @@ -211,23 +214,15 @@ fh_member(JSValue *ctx, Node *member)
fh_member(ctx, member->e2) :
fh_get_rec(ctx, id2->string.ptr);

// Special string type considerations
if (parent->type == T_STRING) {

// Handle array-like string character access.
if (member->e1->type == NODE_NUM) {
int i = member->e1->val, len = parent->string.length;
if (i < len && i >= 0) {
char *str = malloc(2);
sprintf(str, "%c", parent->string.ptr[i]);
return JSSTR(str);
}
return JSUNDEF();
// Handle array-like string character access.
if (IS_STR(parent) && member->e1->type == NODE_NUM) {
int i = member->e1->val, len = parent->string.length;
if (i < len && i >= 0) {
char *str = malloc(2);
sprintf(str, "%c", parent->string.ptr[i]);
return JSSTR(str);
}

// Strings don't have a hashmap, so we cheat a bit with the 'length' prop.
if (STREQ(id1->string.ptr, "length"))
return JSNUM(parent->string.length);
return JSUNDEF();
}

return fh_get_proto(parent, id1->string.ptr);
Expand All @@ -252,7 +247,7 @@ fh_assign(JSValue *ctx, Node *node)
if (IS_ARR(ctx) && member->e1->type == NODE_NUM) {
int val = member->e1->val;
if (val >= ctx->object.length)
fh_arr_set_len(ctx, val + 1);
fh_set_len(ctx, val + 1);
}
key = fh_str_from_node(ctx, member->e1)->string.ptr;
}
Expand Down
20 changes: 11 additions & 9 deletions src/flathead.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fh_new_string(char *x)

val->string.ptr = malloc((strlen(x) + 1) * sizeof(char));
strcpy(val->string.ptr, x);
val->string.length = strlen(x);
fh_set_len(val, strlen(x));
val->proto = fh_try_get_proto("String");

return val;
Expand Down Expand Up @@ -100,7 +100,7 @@ fh_new_array()

val->object.is_array = true;
val->proto = fh_try_get_proto("Array");
fh_arr_set_len(val, 0);
fh_set_len(val, 0);

return val;
}
Expand All @@ -115,6 +115,8 @@ fh_new_function(struct Node *node)
val->function.node = node;
val->function.closure = NULL;
val->function.instance = NULL;
val->function.bound_this = NULL;
val->function.bound_args = NULL;
val->proto = fh_try_get_proto("Function");

return val;
Expand All @@ -123,13 +125,10 @@ fh_new_function(struct Node *node)
JSValue *
fh_new_native_function(JSNativeFunction func)
{
JSValue *val = fh_new_val(T_FUNCTION);
JSValue *val = fh_new_function(NULL);

val->function.is_native = true;
val->function.is_generator = false;
val->function.native = func;
val->function.instance = NULL;
val->proto = fh_try_get_proto("Function");

return val;
}
Expand Down Expand Up @@ -413,8 +412,11 @@ fh_arg_len(JSArgs *args)
}

void
fh_arr_set_len(JSValue *arr, int len)
fh_set_len(JSValue *val, int len)
{
arr->object.length = len;
fh_set_prop(arr, "length", JSNUM(len), P_BUILTIN);
if (IS_STR(val))
val->string.length = len;
if (IS_ARR(val))
val->object.length = len;
fh_set_prop(val, "length", JSNUM(len), P_BUILTIN);
}
3 changes: 1 addition & 2 deletions src/flathead.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@ struct JSFunction {
struct JSValue *closure;
struct JSValue *bound_this;
struct JSArgs *bound_args;
struct JSValue *prototype;
struct JSValue *instance;
JSNativeFunction native;
};
Expand Down Expand Up @@ -219,7 +218,7 @@ JSValue * fh_cast(JSValue *, JSType);
JSValue * fh_has_instance(JSValue *, JSValue *);
JSValue * fh_has_property(JSValue *, char *);
char * fh_typeof(JSValue *);
void fh_arr_set_len(JSValue *, int);
void fh_set_len(JSValue *, int);
void fh_error(State *, JSErrorType, const char *, ...);
int fh_arg_len(JSArgs*);

Expand Down
5 changes: 3 additions & 2 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ fh_gc_mark(JSValue *val)
if (val->type == T_FUNCTION) {
fh_gc_mark(val->function.closure);
fh_gc_mark(val->function.bound_this);
fh_gc_mark(val->function.prototype);
fh_gc_mark(val->function.instance);
}

Expand Down Expand Up @@ -131,6 +130,7 @@ fh_gc_sweep(PoolMetadata *pool)
void
fh_gc_free_val(JSValue *val)
{
/*
// Free the object hashtable
// TODO: just objects?
if (val->type == T_OBJECT) {
Expand All @@ -140,8 +140,9 @@ fh_gc_free_val(JSValue *val)
if (prop != NULL) free(prop);
}
}
*/
// Free any strings (dynamically alloc-ed outside slots)
if (val->type == T_STRING && val->string.ptr != NULL) {
if (IS_STR(val) && val->string.ptr != NULL) {
free(val->string.ptr);
}

Expand Down
20 changes: 10 additions & 10 deletions src/runtime/lib/Array.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ arr_proto_pop(JSValue *instance, JSArgs *args, State *state)
JSValue *popped = fh_get(instance, key->string.ptr);

fh_del_prop(instance, key->string.ptr);
fh_arr_set_len(instance, len - 1);
fh_set_len(instance, len - 1);
return popped;
}

Expand All @@ -55,7 +55,7 @@ arr_proto_push(JSValue *instance, JSArgs *args, State *state)
len++;
}

fh_arr_set_len(instance, len);
fh_set_len(instance, len);
return JSNUM(len);
}

Expand Down Expand Up @@ -104,7 +104,7 @@ arr_proto_shift(JSValue *instance, JSArgs *args, State *state)
fh_set(instance, new_key->string.ptr, prop->ptr);
}

fh_arr_set_len(instance, len - 1);
fh_set_len(instance, len - 1);
return shifted;
}

Expand Down Expand Up @@ -185,8 +185,8 @@ arr_proto_splice(JSValue *instance, JSArgs *args, State *state)
// GC will take the hash if we don't remove the reference.
keepers->map = NULL;

fh_arr_set_len(instance, k);
fh_arr_set_len(rejects, j);
fh_set_len(instance, k);
fh_set_len(rejects, j);
return rejects;
}

Expand Down Expand Up @@ -217,7 +217,7 @@ arr_proto_unshift(JSValue *instance, JSArgs *args, State *state)
instance->map = newarr->map;
newarr->map = NULL;

fh_arr_set_len(instance, i);
fh_set_len(instance, i);
return JSNUM(i);
}

Expand Down Expand Up @@ -261,7 +261,7 @@ arr_proto_concat(JSValue *instance, JSArgs *args, State *state)
}
}

fh_arr_set_len(concat, i);
fh_set_len(concat, i);
return concat;
}

Expand Down Expand Up @@ -300,7 +300,7 @@ arr_proto_slice(JSValue *instance, JSArgs *args, State *state)
fh_set(slice, JSNUMKEY(i)->string.ptr, val);
}

fh_arr_set_len(slice, i);
fh_set_len(slice, i);
return slice;
}

Expand Down Expand Up @@ -390,7 +390,7 @@ arr_proto_filter(JSValue *instance, JSArgs *args, State *state)
}
}

fh_arr_set_len(filtered, j);
fh_set_len(filtered, j);
return filtered;
}

Expand Down Expand Up @@ -458,7 +458,7 @@ arr_proto_map(JSValue *instance, JSArgs *args, State *state)
fh_set(map, key->string.ptr, result);
}

fh_arr_set_len(map, len);
fh_set_len(map, len);
return map;
}

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/lib/Object.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ obj_keys(JSValue *instance, JSArgs *args, State *state)
fh_set(keys, JSNUMKEY(i++)->string.ptr, JSSTR(p->name));
}

fh_arr_set_len(keys, i);
fh_set_len(keys, i);
return keys;
}

Expand All @@ -122,7 +122,7 @@ obj_get_own_property_names(JSValue *instance, JSArgs *args, State *state)
fh_set(names, JSNUMKEY(i++)->string.ptr, JSSTR(p->name));
}

fh_arr_set_len(names, i);
fh_set_len(names, i);
return names;
}

Expand Down
6 changes: 3 additions & 3 deletions src/runtime/lib/String.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ str_proto_match(JSValue *instance, JSArgs *args, State *state)
fh_set(arr, JSNUMKEY(i)->string.ptr, match);
}
free(matches);
fh_arr_set_len(arr, i);
fh_set_len(arr, i);
return arr;
}

Expand Down Expand Up @@ -225,7 +225,7 @@ str_proto_split(JSValue *instance, JSArgs *args, State *state)

if (IS_UNDEF(sep_arg)) {
fh_set(arr, "0", instance);
fh_arr_set_len(arr, 1);
fh_set_len(arr, 1);
return arr;
}

Expand Down Expand Up @@ -258,7 +258,7 @@ str_proto_split(JSValue *instance, JSArgs *args, State *state)
fh_set(arr, JSNUMKEY(index++)->string.ptr, JSSTR(split));
}

fh_arr_set_len(arr, index);
fh_set_len(arr, index);
return arr;
}

Expand Down
35 changes: 35 additions & 0 deletions test/test_new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// test_new.js
// -----------
// Adapted from v8/test/mjsunit/new.js

var assert = console.assert;

function Construct(x) { return x; }

assert(null != new Construct(null));
assert(void 0 != new Construct(void 0));
assert(0 != new Construct(0));
assert(1 != new Construct(1));
assert(4.2 != new Construct(4.2));
assert('foo' != new Construct('foo'));
assert(true != new Construct(true));

x = {};
assert(x === new Construct(x));
assert(x !== new Construct(null));
assert(x !== new Construct(void 0));
assert(x !== new Construct(1));
assert(x !== new Construct(3.2));
assert(x !== new Construct(false));
assert(x !== new Construct('bar'));

x = [];
assert(x === new Construct(x));
x = new Boolean(true);
assert(x === new Construct(x));
x = new Number(42);
assert(x === new Construct(x));
x = new String('foo');
assert(x === new Construct(x));
x = function() { };
assert(x === new Construct(x));

0 comments on commit c6e0b26

Please sign in to comment.