Skip to content

Commit

Permalink
Additional tests for global objects and a few fixes
Browse files Browse the repository at this point in the history
- Fixes a few function lengths that were wrong.
- Fixes the inheritance between the Object and Function objects and
  their prototypes. Little bit of chicken & the egg.
- Remaining unimplemented methods now exit on error.
- Adds missing Error constructor variants.
- Updates docket.
  • Loading branch information
ndreynolds committed Apr 5, 2013
1 parent 63ec447 commit d69508c
Show file tree
Hide file tree
Showing 10 changed files with 482 additions and 71 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Flathead
========
Flathead is a tiny JavaScript (Ecma-262) interpreter written in C.
Flathead is a tiny JavaScript (ECMA-262) interpreter written in C.

![Flathead's REPL](http://ndreynolds.com/img/flathead.png)

Expand Down Expand Up @@ -111,6 +111,8 @@ The Docket
- The JSON object ([JSON-js][1] can be used as polyfill)
- String#replace
- `new Function(...)`
- eval
- URI functions
- Garbage collection needs work


Expand Down
6 changes: 5 additions & 1 deletion src/flathead.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* flathead.c -- Core types, constructors, casting, and debug.
*
* Copyright (c) 2012 Nick Reynolds
* Copyright (c) 2012-2013 Nick Reynolds
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -123,6 +123,10 @@ fh_new_function(struct ast_node *node)
fh_set_class(val, "Function");
fh_set_prop(val, "prototype", JSOBJ(), P_WRITE);

fh_set(val, "name", JSSTR(""));
fh_set(val, "arguments", JSNULL());
fh_set(val, "caller", JSNULL());

val->object.native = false;
val->object.generator = false;
val->object.node = node;
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/lib/Array.c
Original file line number Diff line number Diff line change
Expand Up @@ -740,7 +740,7 @@ bootstrap_array()
DEF(array, "prototype", proto);

// Methods
DEF(array, "isArray", JSNFUNC(arr_is_array, 0));
DEF(array, "isArray", JSNFUNC(arr_is_array, 1));

// Array.prototype
// ---------------
Expand Down
54 changes: 54 additions & 0 deletions src/runtime/lib/Error.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,60 @@ error_new(js_val *instance, js_args *args, eval_state *state)
return err;
}

// [new] EvalError(message)
js_val *
error_eval_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "EvalError");
return err;
}

// [new] RangeError(message)
js_val *
error_range_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "RangeError");
return err;
}

// [new] ReferenceError(message)
js_val *
error_ref_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "ReferenceError");
return err;
}

// [new] SyntaxError(message)
js_val *
error_syntax_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "SyntaxError");
return err;
}

// [new] TypeError(message)
js_val *
error_type_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "TypeError");
return err;
}

// [new] URIError(message)
js_val *
error_uri_new(js_val *instance, js_args *args, eval_state *state)
{
js_val *err = error_new(instance, args, state);
fh_set_class(err, "URIError");
return err;
}

// Error.prototype.toString()
js_val *
error_proto_to_string(js_val *instance, js_args *args, eval_state *state)
Expand Down
8 changes: 8 additions & 0 deletions src/runtime/lib/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#include "../runtime.h"

js_val * error_new(js_val *, js_args *, eval_state *);
js_val * error_eval_new(js_val *, js_args *, eval_state *);
js_val * error_range_new(js_val *, js_args *, eval_state *);
js_val * error_ref_new(js_val *, js_args *, eval_state *);
js_val * error_syntax_new(js_val *, js_args *, eval_state *);
js_val * error_type_new(js_val *, js_args *, eval_state *);
js_val * error_uri_new(js_val *, js_args *, eval_state *);

js_val * error_proto_to_string(js_val *, js_args *, eval_state *);

js_val * bootstrap_error(void);

Expand Down
4 changes: 3 additions & 1 deletion src/runtime/lib/Function.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ func_new(js_val *instance, js_args *args, eval_state *state)
// TODO: No clue how this is going to work. Need to generate
// nodes for the args, which can be manual, but also the func
// body, which we'll need the parser's help with.
return JSUNDEF();
fh_error(state, E_ERROR, "The Function constructor is not yet implemented");
UNREACHABLE();
}

// Function.prototype.apply(thisValue[, argsArray])
Expand Down Expand Up @@ -85,6 +86,7 @@ bootstrap_function()
{
js_val *function = JSNFUNC(func_new, 1);
js_val *prototype = JSFUNC(NULL);
function->proto = prototype;
prototype->proto = fh->object_proto;

// Function
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/lib/Object.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ bootstrap_object()
DEF(object, "defineProperties", JSNFUNC(obj_define_properties, 2));
DEF(object, "getOwnPropertyDescriptor", JSNFUNC(obj_get_own_property_descriptor, 2));
DEF(object, "keys", JSNFUNC(obj_keys, 1));
DEF(object, "getOwnPropertyName", JSNFUNC(obj_get_own_property_names, 1));
DEF(object, "getOwnPropertyNames", JSNFUNC(obj_get_own_property_names, 1));
DEF(object, "getPrototypeOf", JSNFUNC(obj_get_prototype_of, 1));
DEF(object, "preventExtensions", JSNFUNC(obj_prevent_extensions, 1));
DEF(object, "isExtensible", JSNFUNC(obj_is_extensible, 1));
Expand Down
78 changes: 48 additions & 30 deletions src/runtime/runtime.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* runtime.c -- Bootstrap global object and friends
*
* Copyright (c) 2012 Nick Reynolds
* Copyright (c) 2012-2013 Nick Reynolds
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
Expand Down Expand Up @@ -79,8 +79,9 @@ global_parse_float(js_val *instance, js_args *args, eval_state *state)
js_val *
global_eval(js_val *instance, js_args *args, eval_state *state)
{
// TODO
return JSUNDEF();
// TODO: implement
fh_error(state, E_ERROR, "eval is not yet implemented");
UNREACHABLE();
}

// gc()
Expand Down Expand Up @@ -122,44 +123,61 @@ js_val *
fh_bootstrap()
{
js_val *global = JSOBJ();
js_val *object_cons = bootstrap_object();

DEF(global, "Object", bootstrap_object());
DEF(global, "Object", object_cons);
DEF(global, "Function", bootstrap_function());
DEF(global, "Array", bootstrap_array());
DEF(global, "String", bootstrap_string());
DEF(global, "Number", bootstrap_number());
DEF(global, "Boolean", bootstrap_boolean());
DEF(global, "Date", bootstrap_date());
DEF(global, "RegExp", bootstrap_regexp());
DEF(global, "Error", bootstrap_error());
DEF(global, "Math", bootstrap_math());
DEF(global, "console", bootstrap_console());

DEF(global, "Array", bootstrap_array());
DEF(global, "String", bootstrap_string());
DEF(global, "Number", bootstrap_number());
DEF(global, "Boolean", bootstrap_boolean());
DEF(global, "Date", bootstrap_date());
DEF(global, "RegExp", bootstrap_regexp());
DEF(global, "Error", bootstrap_error());
DEF(global, "Math", bootstrap_math());
DEF(global, "console", bootstrap_console());

// The Object constructor and its methods are created before the Function
// constructor exists, so we need connect the prototypes manually.
object_cons->proto = fh->function_proto;
fh_attach_prototype(object_cons, fh->function_proto);
fh_attach_prototype(fh->object_proto, fh->function_proto);

// Likewise for the Function prototype.
fh_attach_prototype(fh->function_proto, fh->function_proto);

DEF(global, "NaN", JSNAN());
DEF(global, "Infinity", JSINF());
DEF(global, "NaN", JSNAN());
DEF(global, "Infinity", JSINF());
DEF(global, "undefined", JSUNDEF());
DEF(global, "this", global);
DEF(global, "this", global);

// Other Error constructors
DEF(global, "EvalError", JSNFUNC(error_eval_new, 1));
DEF(global, "RangeError", JSNFUNC(error_range_new, 1));
DEF(global, "ReferenceError", JSNFUNC(error_ref_new, 1));
DEF(global, "SyntaxError", JSNFUNC(error_syntax_new, 1));
DEF(global, "TypeError", JSNFUNC(error_type_new, 1));
DEF(global, "URIError", JSNFUNC(error_uri_new, 1));

// These aren't currently optimized, just here for compatibility's sake.
DEF(global, "Float32Array", JSNFUNC(arr_new, 1));
DEF(global, "Float64Array", JSNFUNC(arr_new, 1));
DEF(global, "Uint8Array", JSNFUNC(arr_new, 1));
DEF(global, "Uint16Array", JSNFUNC(arr_new, 1));
DEF(global, "Uint32Array", JSNFUNC(arr_new, 1));
DEF(global, "Int8Array", JSNFUNC(arr_new, 1));
DEF(global, "Int16Array", JSNFUNC(arr_new, 1));
DEF(global, "Int32Array", JSNFUNC(arr_new, 1));

DEF(global, "isNaN", JSNFUNC(global_is_nan, 1));
DEF(global, "isFinite", JSNFUNC(global_is_finite, 1));
DEF(global, "parseInt", JSNFUNC(global_parse_int, 2));
DEF(global, "Uint8Array", JSNFUNC(arr_new, 1));
DEF(global, "Uint16Array", JSNFUNC(arr_new, 1));
DEF(global, "Uint32Array", JSNFUNC(arr_new, 1));
DEF(global, "Int8Array", JSNFUNC(arr_new, 1));
DEF(global, "Int16Array", JSNFUNC(arr_new, 1));
DEF(global, "Int32Array", JSNFUNC(arr_new, 1));

DEF(global, "isNaN", JSNFUNC(global_is_nan, 1));
DEF(global, "isFinite", JSNFUNC(global_is_finite, 1));
DEF(global, "parseInt", JSNFUNC(global_parse_int, 2));
DEF(global, "parseFloat", JSNFUNC(global_parse_float, 1));
DEF(global, "eval", JSNFUNC(global_eval, 1));
DEF(global, "load", JSNFUNC(global_load, 1));
DEF(global, "print", JSNFUNC(console_log, 1));
DEF(global, "eval", JSNFUNC(global_eval, 1));

// Extras
DEF(global, "load", JSNFUNC(global_load, 1));
DEF(global, "print", JSNFUNC(console_log, 1));

#ifdef fh_gc_expose
DEF(global, "gc", JSNFUNC(global_gc, 0));
Expand Down
Loading

0 comments on commit d69508c

Please sign in to comment.