void CCodeGenerator::exit_scope() { // Pops the symbol table for this scope off the stack, and inserts code to // perform cleanup at the end of the scope. Scope::Ptr scope = scope_.back(); if (!block_has_return_) { // Free variables in reverse order! for (int i = scope->variables()-1; i >= 0; i--) { scope_cleanup(scope->variable(i)); } scope_.pop_back(); } else { func_return(); scope_.pop_back(); block_has_return_ = false; } if (braces_) { line(); for (int i = 0; i < braces_; i++) { out_ << "}"; } out_ << "\n"; } braces_ = 0; }
void CCodeGenerator::func_return() { // Search backwards through the vector and clean up variables in the // containing scope. Do NOT clean up variables in the top scope; those // variables are parameters and they are anchored (hence j > 1). for (int j = scope_.size()-1; j > 0; j--) { Scope::Ptr s = scope_[j]; for (int i = s->variables()-1; i >= 0; i--) { scope_cleanup(s->variable(i)); } } // If this is the destructor, then release all pointers held by the object, // and call free() to release memory if the object was dynamically // allocated. if (function_->is_destructor()) { dtor_epilog(function_); } // Emit an actual return. Emit code to return the value saved in the var // '_ret' if the variable has been set. if (function_->is_constructor()) { line(); out_ << "return self;\n"; } else if (!function_->type()->is_void()) { line(); out_ << "return " << return_val_ << ";\n"; } }
/****************************************************************************** * non-static function definitions ******************************************************************************/ int main(int argc, char **argv) { int retval; struct handles handles = { .sock = -1, .sock2 = -1, .server_sock = -1, .file = NULL, .file2 = NULL, }; struct scope_parameter param; if(0 != handle_options(argc,argv, &g_options)) { usage(argv[0]); return 1; } signal_init(); if (scope_init(¶m, &g_options)) { retval = 2; goto cleanup; } if (g_options.mode == client || g_options.mode == server) { if (connection_init(&g_options, &handles)) { retval = 3; goto cleanup_scope; } } else if (g_options.mode == file) { if (file_open(&g_options, &handles)) { retval = 4; goto cleanup_scope; } } retval = 0; while (!transfer_interrupted()) { if (g_options.mode == client || g_options.mode == server) { if (connection_start(&g_options, &handles) < 0) { fprintf(stderr, "%s: problem opening connection.\n", __func__); continue; } } retval = transfer_data(¶m, &g_options, &handles); if (retval && !transfer_interrupted()) fprintf(stderr, "%s: problem transferring data.\n", __func__); if (g_options.mode == client || g_options.mode == server) connection_stop(&handles); if (g_options.mode == file) break; } connection_cleanup(&handles); file_close(&handles); cleanup_scope: scope_cleanup(¶m, &g_options); cleanup: signal_exit(); return retval; }