Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling uncaughtException #91

Merged
merged 1 commit into from
Jun 19, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/iotjs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,21 @@ static void CleanupModules() {


static bool InitIoTjs(JObject* process) {
JResult jmain = JObject::Eval(mainjs, false, false);
IOTJS_ASSERT(jmain.IsOk());

JRawValueType retval;
jerry_api_eval(mainjs,mainjs_length,
false, false, &retval);
JObject iotjs_fun(&retval, true);
JArgList args(1);
args.Add(*process);

JObject global(JObject::Global());
iotjs_fun.Call(global, args);
JResult jmain_res = jmain.value().Call(global, args);

return true;
if (jmain_res.IsException()) {
UncaughtException(jmain_res.value());
return false;
} else {
return true;
}
}


Expand Down
65 changes: 60 additions & 5 deletions src/iotjs_binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,13 @@ namespace iotjs {
static_cast<int64_t>((val_p)->v_uint32))



JRawObjectType* GetGlobal() {
return jerry_api_get_global();
}



JObject::JObject() {
JRawObjectType* new_obj = jerry_api_create_object();
_obj_val = JVal::Object(new_obj);
Expand Down Expand Up @@ -194,7 +196,7 @@ JObject JObject::URIError(const char* message) {
}


JObject JObject::Eval(const char* source, bool direct_mode, bool strict_mode) {
JResult JObject::Eval(const char* source, bool direct_mode, bool strict_mode) {
size_t source_len = strlen(source);
JRawValueType res;
jerry_completion_code_t ret = jerry_api_eval(source,
Expand All @@ -206,7 +208,11 @@ JObject JObject::Eval(const char* source, bool direct_mode, bool strict_mode) {
IOTJS_ASSERT(ret == JERRY_COMPLETION_CODE_OK ||
ret == JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION);

return JObject(&res);
JResultType type = (ret == JERRY_COMPLETION_CODE_OK)
? JRESULT_OK
: JRESULT_EXCEPTION;

return JResult(&res, type);
}


Expand Down Expand Up @@ -308,7 +314,7 @@ uintptr_t JObject::GetNative() {
}


JObject JObject::Call(JObject& this_, JArgList& arg) {
JResult JObject::Call(JObject& this_, JArgList& arg) {
IOTJS_ASSERT(IsFunction());

JRawObjectType* this_obj_p = this_.IsNull() ? NULL
Expand All @@ -330,13 +336,21 @@ JObject JObject::Call(JObject& this_, JArgList& arg) {
&res,
val_args,
val_argv);
IOTJS_ASSERT(is_ok);

if (val_args) {
delete [] val_args;
}

return JObject(&res);
JResultType type = is_ok ? JRESULT_OK : JRESULT_EXCEPTION;

return JResult(&res, type);
}


JObject JObject::CallOk(JObject& this_, JArgList& arg) {
JResult jres = Call(this_, arg);
IOTJS_ASSERT(jres.IsOk());
return jres.value();
}


Expand Down Expand Up @@ -382,6 +396,47 @@ size_t JObject::GetCStringLength() {
}



JResult::JResult(const JObject& value, JResultType type)
: _value(value)
, _type(type) {
}


JResult::JResult(const JRawValueType* raw_val, JResultType type)
: _value(raw_val)
, _type(type) {
}


JResult::JResult(const JResult& other)
: _value(other._value)
, _type(other._type) {
}


JObject& JResult::value() {
return _value;
}


JResultType JResult::type() const {
IOTJS_ASSERT(_type == JRESULT_OK || _type == JRESULT_EXCEPTION);
return _type;
}


bool JResult::IsOk() const {
return type() == JRESULT_OK;
}


bool JResult::IsException() const {
return type() == JRESULT_EXCEPTION;
}



JRawValueType JVal::Void() {
JRawValueType val;
val.type = JERRY_API_DATA_TYPE_VOID;
Expand Down
33 changes: 31 additions & 2 deletions src/iotjs_binding.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,18 @@ typedef jerry_api_object_t JRawObjectType;
typedef jerry_api_value_t JRawValueType;



class JObject;
class JResult;
class JArgList;
class JHandlerInfo;
class JLocalScope;

enum JResultType {
JRESULT_OK,
JRESULT_EXCEPTION
};


/// Wrapper for Javascript objects.
class JObject {
Expand Down Expand Up @@ -92,7 +99,7 @@ class JObject {

// Evaluate javascript source file.
// `souce` shoud be a null-terminated c string.
static JObject Eval(const char* source,
static JResult Eval(const char* source,
bool direct_mode = true,
bool strict_mode = false);

Expand Down Expand Up @@ -150,7 +157,8 @@ class JObject {
size_t GetCStringLength();

// Calls javascript function.
JObject Call(JObject& this_, JArgList& arg);
JResult Call(JObject& this_, JArgList& arg);
JObject CallOk(JObject& this_, JArgList& arg);

JRawValueType raw_value() { return _obj_val; }

Expand All @@ -163,6 +171,27 @@ class JObject {
};


class JResult {
public:
JResult(const JObject& value, JResultType type);
JResult(const JRawValueType* raw_val, JResultType type);
JResult(const JResult& other);

JObject& value();
JResultType type() const;

bool IsOk() const;
bool IsException() const;

private:
JObject _value;
JResultType _type;

// disable assignment.
JResult& operator=(const JResult& rhs) = delete;
};


class JVal {
public:
static JRawValueType Void();
Expand Down
9 changes: 5 additions & 4 deletions src/iotjs_module_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,17 @@ JObject CreateBuffer(size_t len) {
JObject jglobal(JObject::Global());
IOTJS_ASSERT(jglobal.IsObject());

JObject jBuffer = jglobal.GetProperty("Buffer");
JObject jBuffer(jglobal.GetProperty("Buffer"));
IOTJS_ASSERT(jBuffer.IsFunction());

JArgList jargs(1);
jargs.Add(JVal::Int(len));

JObject jbuffer = jBuffer.Call(JObject::Null(), jargs);
IOTJS_ASSERT(jbuffer.IsObject());
JResult jres(jBuffer.Call(JObject::Null(), jargs));
IOTJS_ASSERT(jres.IsOk());
IOTJS_ASSERT(jres.value().IsObject());

return jbuffer;
return jres.value();
}


Expand Down
5 changes: 3 additions & 2 deletions src/iotjs_module_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,10 @@ JObject MakeStatObject(uv_stat_t* statbuf) {
args.Add(size);
args.Add(blocks);

JObject statobj(createStat.Call(JObject::Null(), args));
JResult jstat_res(createStat.Call(JObject::Null(), args));
IOTJS_ASSERT(jstat_res.IsOk());

return statobj;
return jstat_res.value();
}


Expand Down
80 changes: 61 additions & 19 deletions src/iotjs_module_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,40 +33,60 @@
namespace iotjs {


void ProcessExit(int code) {
static JObject* GetProcess() {
Module* module = GetBuiltinModule(MODULE_PROCESS);
IOTJS_ASSERT(module != NULL);

JObject* process = module->module;
IOTJS_ASSERT(process != NULL);
IOTJS_ASSERT(process->IsObject());

return process;
}


void UncaughtException(JObject& jexception) {
JObject* process = GetProcess();

JObject jonuncaughtexception(process->GetProperty("_onUncaughtExcecption"));
IOTJS_ASSERT(jonuncaughtexception.IsFunction());

JArgList args(1);
args.Add(jexception);

JResult jres = jonuncaughtexception.Call(*process, args);
IOTJS_ASSERT(jres.IsOk());
}


void ProcessExit(int code) {
JObject* process = GetProcess();

JObject jexit(process->GetProperty("exit"));
IOTJS_ASSERT(jexit.IsFunction());

JArgList args(1);
args.Add(JVal::Double(code));

jexit.Call(JObject::Null(), args);
JResult jres = jexit.Call(JObject::Null(), args);
if (!jres.IsOk()) {
exit(2);
}
}


// Calls next tick callbacks registered via `process.nextTick()`.
bool ProcessNextTick() {
Module* module = GetBuiltinModule(MODULE_PROCESS);
IOTJS_ASSERT(module != NULL);

JObject* process = module->module;
IOTJS_ASSERT(process != NULL);
IOTJS_ASSERT(process->IsObject());
JObject* process = GetProcess();

JObject jon_next_tick(process->GetProperty("_onNextTick"));
IOTJS_ASSERT(jon_next_tick.IsFunction());

JObject ret(jon_next_tick.Call(JObject::Null(), JArgList::Empty()));
IOTJS_ASSERT(ret.IsBoolean());
JResult jres = jon_next_tick.Call(JObject::Null(), JArgList::Empty());
IOTJS_ASSERT(jres.IsOk());
IOTJS_ASSERT(jres.value().IsBoolean());

return ret.GetBoolean();
return jres.value().GetBoolean();
}


Expand All @@ -75,13 +95,16 @@ bool ProcessNextTick() {
// will be called after the callback function `function` returns.
JObject MakeCallback(JObject& function, JObject& this_, JArgList& args) {
// Calls back the function.
JObject res = function.Call(this_, args);
JResult jres = function.Call(this_, args);
if (jres.IsException()) {
UncaughtException(jres.value());
}

// Calls the next tick callbacks.
ProcessNextTick();

// Return value.
return res;
return jres.value();
}


Expand Down Expand Up @@ -112,11 +135,15 @@ JHANDLER_FUNCTION(Compile, handler){

LocalString code(handler.GetArg(0)->GetCString());

JObject eval = JObject::Eval(code);
JResult jres(JObject::Eval(code));

handler.Return(eval);
if (jres.IsOk()) {
handler.Return(jres.value());
} else {
handler.Throw(jres.value());
}

return true;
return !handler.HasThrown();
}


Expand All @@ -138,11 +165,15 @@ JHANDLER_FUNCTION(CompileNativePtr, handler){
strcat(code,source);
strcat(code,wrapper[1]);

JObject eval = JObject::Eval(code);
JResult jres(JObject::Eval(code));

handler.Return(eval);
if (jres.IsOk()) {
handler.Return(jres.value());
} else {
handler.Throw(jres.value());
}

return true;
return !handler.HasThrown();
}


Expand Down Expand Up @@ -176,6 +207,16 @@ JHANDLER_FUNCTION(Cwd, handler){
}


JHANDLER_FUNCTION(DoExit, handler) {
IOTJS_ASSERT(handler.GetArgLength() == 1);
IOTJS_ASSERT(handler.GetArg(0)->IsNumber());

int exit_code = handler.GetArg(0)->GetInt32();

exit(exit_code);
}


void SetNativeSources(JObject* native_sources) {
for (int i = 0; natives[i].name; i++) {
JObject native_source;
Expand Down Expand Up @@ -209,6 +250,7 @@ JObject* InitProcess() {
process->SetMethod("compileNativePtr", CompileNativePtr);
process->SetMethod("readSource", ReadSource);
process->SetMethod("cwd", Cwd);
process->SetMethod("doExit", DoExit);
SetProcessEnv(process);

// process.native_sources
Expand Down
Loading