SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,const SQRegFunction *methods,const SQRegFunction *globals) { if(sq_gettype(v,-1) != OT_TABLE) return sq_throwerror(v,_SC("table expected")); SQInteger top = sq_gettop(v); //create delegate init_streamclass(v); sq_pushregistrytable(v); sq_pushstring(v,reg_name,-1); sq_pushstring(v,_SC("std_stream"),-1); if(SQ_SUCCEEDED(sq_get(v,-3))) { sq_newclass(v,SQTrue); sq_settypetag(v,-1,typetag); SQInteger i = 0; while(methods[i].name != 0) { const SQRegFunction &f = methods[i]; sq_pushstring(v,f.name,-1); sq_newclosure(v,f.f,0); sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setnativeclosurename(v,-1,f.name); sq_newslot(v,-3,SQFalse); i++; } sq_newslot(v,-3,SQFalse); sq_pop(v,1); i = 0; while(globals[i].name!=0) { const SQRegFunction &f = globals[i]; sq_pushstring(v,f.name,-1); sq_newclosure(v,f.f,0); sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_setnativeclosurename(v,-1,f.name); sq_newslot(v,-3,SQFalse); i++; } //register the class in the target table sq_pushstring(v,name,-1); sq_pushregistrytable(v); sq_pushstring(v,reg_name,-1); sq_get(v,-2); sq_remove(v,-2); sq_newslot(v,-3,SQFalse); sq_settop(v,top); return SQ_OK; } sq_settop(v,top); return SQ_ERROR; }
void init_streamclass(HSQUIRRELVM v) { sq_pushregistrytable(v); sq_pushstring(v,_SC("std_stream"),-1); if(SQ_FAILED(sq_get(v,-2))) { sq_pushstring(v,_SC("std_stream"),-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); SQInteger i = 0; while(_stream_methods[i].name != 0) { const SQRegFunction &f = _stream_methods[i]; sq_pushstring(v,f.name,-1); sq_newclosure(v,f.f,0); sq_setparamscheck(v,f.nparamscheck,f.typemask); sq_newslot(v,-3,SQFalse); i++; } sq_newslot(v,-3,SQFalse); sq_pushroottable(v); sq_pushstring(v,_SC("stream"),-1); sq_pushstring(v,_SC("std_stream"),-1); sq_get(v,-4); sq_newslot(v,-3,SQFalse); sq_pop(v,1); } else { sq_pop(v,1); //result } sq_pop(v,1); }
static SQRESULT squirrel_get_allocator(HSQUIRRELVM v, WasmAllocator** out_allocator) { SQUserPointer allocator_up; sq_pushregistrytable(v); sq_pushstring(v, WASM_ALLOCATOR_NAME, -1); CHECK_SQ_RESULT(sq_get(v, -2)); CHECK_SQ_RESULT(sq_getuserpointer(v, -1, &allocator_up)); *out_allocator = allocator_up; sq_pop(v, 2); return SQ_OK; }
void SQDbgServer::SetErrorHandlers() { sq_pushregistrytable(_v); sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); sq_rawget(_v,-2); sq_setdebughook(_v); sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1); sq_rawget(_v,-2); sq_seterrorhandler(_v); sq_pop(_v,1); }
bool SQDbgServer::Init() { //creates an environment table for the debugger sq_newtable(_v); sq_getstackobj(_v,-1,&_debugroot); sq_addref(_v,&_debugroot); //creates a emptyslot to store the watches sq_pushstring(_v,_SC("watches"),-1); sq_pushnull(_v); sq_createslot(_v,-3); sq_pushstring(_v,_SC("beginelement"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,beginelement,1); sq_setparamscheck(_v,2,_SC(".s")); sq_createslot(_v,-3); sq_pushstring(_v,_SC("endelement"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,endelement,1); sq_setparamscheck(_v,2,_SC(".s")); sq_createslot(_v,-3); sq_pushstring(_v,_SC("attribute"),-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,attribute,1); sq_setparamscheck(_v,3,_SC(".ss")); sq_createslot(_v,-3); sq_pop(_v,1); //stores debug hook and error handler in the registry sq_pushregistrytable(_v); sq_pushstring(_v,SQDBG_DEBUG_HOOK,-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,debug_hook,1); sq_createslot(_v,-3); sq_pushstring(_v,SQDBG_ERROR_HANDLER,-1); sq_pushuserpointer(_v,this); sq_newclosure(_v,error_handler,1); sq_createslot(_v,-3); sq_pop(_v,1); //sets the error handlers SetErrorHandlers(); return true; }
SQRESULT NitLibCom(HSQUIRRELVM v) { NitLibCom::Register(v); NitBindComTypeLib::Register(v); NitBindCom* com = new NitBindCom(v); sq_pushroottable(v); sq_pushstring(v, "com", -1); NitBind::push(v, com); sq_newslot(v, -3, true); sq_poptop(v); // Prevent deletion from registry sq_pushregistrytable(v); sq_pushuserpointer(v, com); NitBind::push(v, com); sq_newslot(v, -3, true); sq_poptop(v); return SQ_OK; }
SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) { SQInteger top = sq_gettop(v); sq_pushregistrytable(v); sq_pushstring(v,_SC("std_file"),-1); if(SQ_SUCCEEDED(sq_get(v,-2))) { sq_remove(v,-2); //removes the registry sq_pushroottable(v); // push the this sq_pushuserpointer(v,file); //file if(own){ sq_pushinteger(v,1); //true } else{ sq_pushnull(v); //false } if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { sq_remove(v,-2); return SQ_OK; } } sq_settop(v,top); return SQ_OK; }
static SQInteger squirrel_errorhandler(HSQUIRRELVM v) { /* Detect whether this error is just propagating through, or it originated * here. To do so, we store the last error we saw in the registry and compare * it to the current error. If they are the equal, we've already handled this * error. * * Without this check, we'll call the error handler for every transition * between the Squirrel and Wasm VMs. */ /* TODO(binji): It seems like there should be a better way to handle this */ SQInteger top = sq_gettop(v); WasmBool is_new_error = WASM_TRUE; /* get the last error we saw */ sq_pushregistrytable(v); sq_pushstring(v, WASM_LAST_ERROR_NAME, -1); if (SQ_SUCCEEDED(sq_get(v, -2))) { /* STACK: error registry_table last_error */ sq_push(v, -3); HSQOBJECT last_error; HSQOBJECT error; if (SQ_SUCCEEDED(sq_getstackobj(v, -1, &error)) && SQ_SUCCEEDED(sq_getstackobj(v, -2, &last_error))) { /* we don't want to use cmp here, because it will throw if the values are * unordered, and because it performs value equality */ if (squirrel_objects_are_equal_raw(last_error, error)) is_new_error = WASM_FALSE; } /* set the last_error in the registry to the new error. */ /* STACK: registry_table last_error error */ sq_remove(v, -2); sq_pushstring(v, WASM_LAST_ERROR_NAME, -1); sq_push(v, -2); /* STACK: registry_table error WASM_LAST_ERROR_NAME error */ SQRESULT r = sq_set(v, -4); WASM_USE(r); assert(r == SQ_OK); } sq_settop(v, top); if (is_new_error) { const char* error_msg = "unknown"; if (sq_gettop(v) >= 1) sq_getstring(v, -1, &error_msg); squirrel_error(v, "error: %s\n", error_msg); squirrel_error(v, "callstack:\n"); SQStackInfos stack_info; SQInteger depth; for (depth = 1; SQ_SUCCEEDED(sq_stackinfos(v, depth, &stack_info)); depth++) { const char* source = stack_info.source ? stack_info.source : "unknown"; const char* funcname = stack_info.funcname ? stack_info.funcname : "unknown"; SQInteger line = stack_info.line; squirrel_error(v, " #"_PRINT_INT_FMT ": %s:"_PRINT_INT_FMT ": %s()\n", depth, source, line, funcname); } } return 0; }