void dvm_initialize_value(DVM_TypeSpecifier *type, DVM_Value *value) { if (type->derive_count > 0) { if (type->derive[0].tag == DVM_ARRAY_DERIVE) { value->object = dvm_null_object_ref; } else { DBG_assert(0, ("tag..%d", type->derive[0].tag)); } } else { switch (type->basic_type) { case DVM_VOID_TYPE: /* FALLTHRU */ case DVM_BOOLEAN_TYPE: /* FALLTHRU */ case DVM_INT_TYPE: /* FALLTHRU */ value->int_value = 0; break; case DVM_DOUBLE_TYPE: value->double_value = 0.0; break; case DVM_STRING_TYPE: /* FALLTHRU */ case DVM_CLASS_TYPE: /* FALLTHRU */ value->object = dvm_null_object_ref; break; case DVM_NULL_TYPE: /* FALLTHRU */ case DVM_BASE_TYPE: /* FALLTHRU */ default: DBG_assert(0, ("basic_type..%d", type->basic_type)); } } }
CRB_Char * CRB_object_get_string(CRB_Object *obj) { DBG_assert(obj->type == STRING_OBJECT, ("obj->type..%d\n", obj->type)); return obj->u.string.string; }
static StatementResult execute_if_statement(CRB_Interpreter *inter, CRB_LocalEnvironment *env, Statement *statement) { StatementResult result; CRB_Value cond; result.type = NORMAL_STATEMENT_RESULT; cond = crb_eval_expression(inter, env, statement->u.if_s.condition); if (cond.type != CRB_BOOLEAN_VALUE) { crb_runtime_error(statement->u.if_s.condition->line_number, NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END); } DBG_assert(cond.type == CRB_BOOLEAN_VALUE, ("cond.type..%d", cond.type)); if (cond.u.boolean_value) { result = crb_execute_statement_list(inter, env, statement->u.if_s.then_block ->statement_list); } else { CRB_Boolean elsif_executed; result = execute_elsif(inter, env, statement->u.if_s.elsif_list, &elsif_executed); if (result.type != NORMAL_STATEMENT_RESULT) goto FUNC_END; if (!elsif_executed && statement->u.if_s.else_block) { result = crb_execute_statement_list(inter, env, statement->u.if_s.else_block ->statement_list); } } FUNC_END: return result; }
void * CRB_object_get_native_pointer(CRB_Object *obj) { DBG_assert(obj->type == NATIVE_POINTER_OBJECT, ("obj->type..%d\n", obj->type)); return obj->u.native_pointer.pointer; }
static void fix_labels(OpcodeBuf *ob) { int i; int j; OpcodeInfo *info; int label; int address; for (i = 0; i < ob->size; i++) { if (ob->code[i] == DVM_JUMP || ob->code[i] == DVM_JUMP_IF_TRUE || ob->code[i] == DVM_JUMP_IF_FALSE) { label = (ob->code[i+1] << 8) + (ob->code[i+2]); address = ob->label_table[label].label_address; ob->code[i+1] = (DVM_Byte)(address >> 8); ob->code[i+2] = (DVM_Byte)(address &0xff); } info = &dvm_opcode_info[ob->code[i]]; for (j = 0; info->parameter[j] != '\0'; j++) { switch (info->parameter[j]) { case 'b': i++; break; case 's': /* FALLTHRU */ case 'p': i += 2; break; default: DBG_assert(0, ("param..%s, j..%d", info->parameter, j)); } } }
void CRB_object_set_native_pointer(CRB_Object *obj, void *p) { DBG_assert(obj->type == NATIVE_POINTER_OBJECT, ("obj->type..%d\n", obj->type)); obj->u.native_pointer.pointer = p; }
DVM_ExecutableList * DKC_compile(DKC_Compiler *compiler, FILE *fp, char *path) { extern FILE *yyin; DVM_ExecutableList *list; DVM_Executable *exe; DBG_assert(st_compiler_list == NULL, ("st_compiler_list != NULL(%p)", st_compiler_list)); set_path_to_compiler(compiler, path); compiler->input_mode = FILE_INPUT_MODE; yyin = fp; list = MEM_malloc(sizeof(DVM_ExecutableList)); list->list = NULL; exe = do_compile(compiler, list, NULL, DVM_FALSE); exe->path = MEM_strdup(path); list->top_level = exe; /* dvm_disassemble(exe);*/ dispose_compiler_list(); dkc_reset_string_literal_buffer(); return list; }
static void generate_cast_expression(DVM_Executable *exe, Block *block, Expression *expr, OpcodeBuf *ob) { generate_expression(exe, block, expr->u.cast.operand, ob); switch (expr->u.cast.type) { case INT_TO_DOUBLE_CAST: generate_code(ob, expr->line_number, DVM_CAST_INT_TO_DOUBLE); break; case DOUBLE_TO_INT_CAST: generate_code(ob, expr->line_number, DVM_CAST_DOUBLE_TO_INT); break; case BOOLEAN_TO_STRING_CAST: generate_code(ob, expr->line_number, DVM_CAST_BOOLEAN_TO_STRING); break; case INT_TO_STRING_CAST: generate_code(ob, expr->line_number, DVM_CAST_INT_TO_STRING); break; case DOUBLE_TO_STRING_CAST: generate_code(ob, expr->line_number, DVM_CAST_DOUBLE_TO_STRING); break; default: DBG_assert(0, ("expr->u.cast.type..%d", expr->u.cast.type)); } }
char * dkc_get_type_name(TypeSpecifier *type) { VString vstr; TypeDerive *derive_pos; dkc_vstr_clear(&vstr); if (type->basic_type == DVM_CLASS_TYPE) { dkc_vstr_append_string(&vstr, type->class_ref.identifier); } else { dkc_vstr_append_string(&vstr, dkc_get_basic_type_name(type->basic_type)); } for (derive_pos = type->derive; derive_pos; derive_pos = derive_pos->next) { switch (derive_pos->tag) { case FUNCTION_DERIVE: function_type_to_string(&vstr, derive_pos); break; case ARRAY_DERIVE: dkc_vstr_append_string(&vstr, "[]"); break; default: DBG_assert(0, ("derive_tag..%d\n", derive_pos->tag)); } } return vstr.string; }
char * dkc_get_basic_type_name(DVM_BasicType type) { switch (type) { case DVM_VOID_TYPE: return "void"; break; case DVM_BOOLEAN_TYPE: return "boolean"; break; case DVM_INT_TYPE: return "int"; break; case DVM_DOUBLE_TYPE: return "double"; break; case DVM_STRING_TYPE: return "string"; break; case DVM_CLASS_TYPE: return "class"; break; case DVM_NULL_TYPE: return "null"; break; case DVM_BASE_TYPE: /* FALLTHRU */ default: DBG_assert(0, ("bad case. type..%d\n", type)); } return NULL; }
static StatementResult execute_while_statement(CRB_Interpreter *inter, CRB_LocalEnvironment *env, Statement *statement) { StatementResult result; CRB_Value cond; result.type = NORMAL_STATEMENT_RESULT; for (;;) { cond = crb_eval_expression(inter, env, statement->u.while_s.condition); if (cond.type != CRB_BOOLEAN_VALUE) { crb_runtime_error(statement->u.while_s.condition->line_number, NOT_BOOLEAN_TYPE_ERR, MESSAGE_ARGUMENT_END); } DBG_assert(cond.type == CRB_BOOLEAN_VALUE, ("cond.type..%d", cond.type)); if (!cond.u.boolean_value) break; result = crb_execute_statement_list(inter, env, statement->u.while_s.block ->statement_list); if (result.type == RETURN_STATEMENT_RESULT) { break; } else if (result.type == BREAK_STATEMENT_RESULT) { result.type = NORMAL_STATEMENT_RESULT; break; } } return result; }
static DVM_TypeSpecifier * copy_type_specifier(TypeSpecifier *src) { DVM_TypeSpecifier *dest; int derive_count = 0; TypeDerive *derive; int param_count; int i; dest = MEM_malloc(sizeof(DVM_TypeSpecifier)); dest->basic_type = src->basic_type; for (derive = src->derive; derive; derive = derive->next) { derive_count++; } dest->derive_count = derive_count; dest->derive = MEM_malloc(sizeof(DVM_TypeDerive) * derive_count); for (i = 0, derive = src->derive; derive; derive = derive->next, i++) { switch (derive->tag) { case DVM_FUNCTION_DERIVE: dest->derive[i].tag = DVM_FUNCTION_DERIVE; dest->derive[i].u.function_d.parameter = copy_parameter_list(derive->u.function_d.parameter_list, ¶m_count); dest->derive[i].u.function_d.parameter_count = param_count; break; default: DBG_assert(0, ("derive->tag..%d\n", derive->tag)); } } return dest; }
static void eval_inc_dec_expression(SIMCAR_Interpreter *inter, SIMCAR_LocalEnvironment *env, Expression *expr) { SIMCAR_Value *operand; SIMCAR_Value result; int old_value; operand = get_lvalue(inter, env, expr->u.inc_dec.operand); if (operand->type != SIMCAR_INT_VALUE) { crb_runtime_error(expr->line_number, INC_DEC_OPERAND_TYPE_ERR, MESSAGE_ARGUMENT_END); } old_value = operand->u.int_value; if (expr->type == INCREMENT_EXPRESSION) { operand->u.int_value++; } else { DBG_assert(expr->type == DECREMENT_EXPRESSION, ("expr->type..%d\n", expr->type)); operand->u.int_value--; } result.type = SIMCAR_INT_VALUE; result.u.int_value = old_value; push_value(inter, &result); }
ClassOrMemberModifierList Ivyc_create_class_or_member_modifier(ClassOrMemberModifierKind modifier) { ClassOrMemberModifierList ret; ret.is_abstract = NOT_SPECIFIED_MODIFIER; ret.access_modifier = NOT_SPECIFIED_MODIFIER; ret.is_override = NOT_SPECIFIED_MODIFIER; ret.is_virtual = NOT_SPECIFIED_MODIFIER; switch (modifier) { case ABSTRACT_MODIFIER: ret.is_abstract = ABSTRACT_MODIFIER; break; case PUBLIC_MODIFIER: ret.access_modifier = PUBLIC_MODIFIER; break; case PRIVATE_MODIFIER: ret.access_modifier = PRIVATE_MODIFIER; break; case OVERRIDE_MODIFIER: ret.is_override = OVERRIDE_MODIFIER; break; case VIRTUAL_MODIFIER: ret.is_virtual = VIRTUAL_MODIFIER; break; case NOT_SPECIFIED_MODIFIER: /* FALLTHRU */ default: DBG_assert(0, ("modifier..%d", modifier)); } return ret; }
void Ivyc_class_define(MemberDeclaration *member_list) { Ivyc_Compiler *compiler; ClassDefinition *cd; ClassDefinition *pos; compiler = Ivyc_get_current_compiler(); cd = compiler->current_class_definition; DBG_assert(cd != NULL, ("current_class_definition is NULL.")); cd->member = member_list; if (cd->is_generic == ISandBox_TRUE) { if (compiler->template_class_definition_list == NULL) { compiler->template_class_definition_list = cd; } else { for (pos = compiler->template_class_definition_list; pos->next; pos = pos->next) ; pos->next = cd; } } else { if (compiler->class_definition_list == NULL) { compiler->class_definition_list = cd; } else { for (pos = compiler->class_definition_list; pos->next; pos = pos->next) ; pos->next = cd; } } compiler->current_class_definition = NULL; }
void CRB_interpret(CRB_Interpreter *interpreter) { int error_code; StatementResult result; crb_add_std_fp(interpreter); if ((error_code = setjmp(interpreter ->current_recovery_environment.environment)) == 0) { result = crb_execute_statement_list(interpreter, NULL, interpreter->statement_list); if (result.type != NORMAL_STATEMENT_RESULT) { crb_runtime_error(interpreter, NULL, 0, BREAK_OR_CONTINUE_REACHED_TOPLEVEL_ERR, CRB_MESSAGE_ARGUMENT_END); } } else { show_error_stack_trace(interpreter); crb_set_stack_pointer(interpreter, 0); interpreter->current_exception.type = CRB_NULL_VALUE; } DBG_assert(interpreter->stack.stack_pointer == 0, ("stack_pointer..%d\n", interpreter->stack.stack_pointer)); crb_garbage_collect(interpreter); }
void CRB_array_set(CRB_Interpreter *inter, CRB_LocalEnvironment *env, CRB_Object *obj, int index, CRB_Value *value) { DBG_assert(obj->type == ARRAY_OBJECT, ("obj->type..%d\n", obj->type)); obj->u.array.array[index] = *value; }
ClassOrMemberModifierList Ivyc_chain_class_or_member_modifier(ClassOrMemberModifierList list, ClassOrMemberModifierList add) { if (add.is_abstract != NOT_SPECIFIED_MODIFIER) { DBG_assert(add.is_abstract == ABSTRACT_MODIFIER, ("add.is_abstract..%d", add.is_abstract)); if (list.is_abstract != NOT_SPECIFIED_MODIFIER) { Ivyc_compile_error(Ivyc_get_current_compiler()->current_line_number, ABSTRACT_MULTIPLE_SPECIFIED_ERR, MESSAGE_ARGUMENT_END); } list.is_abstract = ABSTRACT_MODIFIER; } else if (add.access_modifier != NOT_SPECIFIED_MODIFIER) { DBG_assert(add.access_modifier == PUBLIC_MODIFIER || add.access_modifier == PUBLIC_MODIFIER, ("add.access_modifier..%d", add.access_modifier)); if (list.access_modifier != NOT_SPECIFIED_MODIFIER) { Ivyc_compile_error(Ivyc_get_current_compiler()->current_line_number, ACCESS_MODIFIER_MULTIPLE_SPECIFIED_ERR, MESSAGE_ARGUMENT_END); } list.access_modifier = add.access_modifier; } else if (add.is_override != NOT_SPECIFIED_MODIFIER) { DBG_assert(add.is_override == OVERRIDE_MODIFIER, ("add.is_override..%d", add.is_override)); if (list.is_override != NOT_SPECIFIED_MODIFIER) { Ivyc_compile_error(Ivyc_get_current_compiler()->current_line_number, OVERRIDE_MODIFIER_MULTIPLE_SPECIFIED_ERR, MESSAGE_ARGUMENT_END); } list.is_override = add.is_override; } else if (add.is_virtual != NOT_SPECIFIED_MODIFIER) { DBG_assert(add.is_virtual == VIRTUAL_MODIFIER, ("add.is_virtual..%d", add.is_virtual)); if (list.is_virtual != NOT_SPECIFIED_MODIFIER) { Ivyc_compile_error(Ivyc_get_current_compiler()->current_line_number, VIRTUAL_MODIFIER_MULTIPLE_SPECIFIED_ERR, MESSAGE_ARGUMENT_END); } list.is_virtual = add.is_virtual; } return list; }
static void generate_return_statement(DVM_Executable *exe, Block *block, Statement *statement, OpcodeBuf *ob) { DBG_assert(statement->u.return_s.return_value != NULL, ("return value is null.")); generate_expression(exe, block, statement->u.return_s.return_value, ob); generate_code(ob, statement->line_number, DVM_RETURN); }
ISandBox_AccessModifier conv_access_modifier(ClassOrMemberModifierKind src) { if (src == PUBLIC_MODIFIER) { return ISandBox_PUBLIC_ACCESS; } else if (src == PRIVATE_MODIFIER) { return ISandBox_PRIVATE_ACCESS; } else { DBG_assert(src == NOT_SPECIFIED_MODIFIER, ("src..%d\n", src)); return ISandBox_FILE_ACCESS; } }
Block * Ivyc_close_block(Block *block, StatementList *statement_list) { Ivyc_Compiler *compiler = Ivyc_get_current_compiler(); DBG_assert(block == compiler->current_block, ("block mismatch.\n")); block->statement_list = statement_list; compiler->current_block = block->outer_block; return block; }
static void generate_assign_expression(DVM_Executable *exe, Block *block, Expression *expr, OpcodeBuf *ob, DVM_Boolean is_toplevel) { if (expr->u.assign_expression.operator != NORMAL_ASSIGN) { generate_identifier_expression(exe, block, expr->u.assign_expression.left, ob); } generate_expression(exe, block, expr->u.assign_expression.operand, ob); switch (expr->u.assign_expression.operator) { case NORMAL_ASSIGN : break; case ADD_ASSIGN: generate_code(ob, expr->line_number, DVM_ADD_INT + get_opcode_type_offset(expr->type->basic_type)); break; case SUB_ASSIGN: generate_code(ob, expr->line_number, DVM_SUB_INT + get_opcode_type_offset(expr->type->basic_type)); break; case MUL_ASSIGN: generate_code(ob, expr->line_number, DVM_MUL_INT + get_opcode_type_offset(expr->type->basic_type)); break; case DIV_ASSIGN: generate_code(ob, expr->line_number, DVM_DIV_INT + get_opcode_type_offset(expr->type->basic_type)); break; case MOD_ASSIGN: generate_code(ob, expr->line_number, DVM_MOD_INT + get_opcode_type_offset(expr->type->basic_type)); break; default: DBG_assert(0, ("operator..%d\n", expr->u.assign_expression.operator)); } if (!is_toplevel) { generate_code(ob, expr->line_number, DVM_DUPLICATE); } generate_pop_to_identifier(expr->u.assign_expression.left ->u.identifier.u.declaration, expr->line_number, ob); }
CRB_Value * CRB_search_local_variable(CRB_LocalEnvironment *env, char *identifier) { CRB_Value *value; CRB_Object *sc; /* scope chain */ if (env == NULL) return NULL; DBG_assert(env->variable->type == SCOPE_CHAIN_OBJECT, ("type..%d\n", env->variable->type)); for (sc = env->variable; sc; sc = sc->u.scope_chain.next) { DBG_assert(sc->type == SCOPE_CHAIN_OBJECT, ("sc->type..%d\n", sc->type)); value = CRB_search_assoc_member(sc->u.scope_chain.frame, identifier); if (value) break; } return value; }
static DVM_Value nv_print_proc(DVM_VirtualMachine *dvm, int arg_count, DVM_Value *args) { DVM_Value ret; ret.int_value = 0; DBG_assert(arg_count == 1, ("arg_count..%d", arg_count)); dvm_print_wcs(stdout, args[0].object->u.string.string); fflush(stdout); return ret; }
CRB_Value * CRB_add_local_variable(CRB_Interpreter *inter, CRB_LocalEnvironment *env, char *identifier, CRB_Value *value, CRB_Boolean is_final) { CRB_Value *ret; DBG_assert(env->variable->type == SCOPE_CHAIN_OBJECT, ("type..%d\n", env->variable->type)); ret = CRB_add_assoc_member(inter, env->variable->u.scope_chain.frame, identifier, value, is_final); return ret; }
static void generate_statement_list(DVM_Executable *exe, Block *current_block, StatementList *statement_list, OpcodeBuf *ob) { StatementList *pos; for (pos = statement_list; pos; pos = pos->next) { switch (pos->statement->type) { case EXPRESSION_STATEMENT: generate_expression_statement(exe, current_block, pos->statement->u.expression_s, ob); break; case IF_STATEMENT: generate_if_statement(exe, current_block, pos->statement, ob); break; case WHILE_STATEMENT: generate_while_statement(exe, current_block, pos->statement, ob); break; case FOR_STATEMENT: generate_for_statement(exe, current_block, pos->statement, ob); break; case FOREACH_STATEMENT: break; case RETURN_STATEMENT: generate_return_statement(exe, current_block, pos->statement, ob); break; case BREAK_STATEMENT: generate_break_statement(exe, current_block, pos->statement, ob); break; case CONTINUE_STATEMENT: generate_continue_statement(exe, current_block, pos->statement, ob); break; case TRY_STATEMENT: break; case THROW_STATEMENT: break; case DECLARATION_STATEMENT: generate_initializer(exe, current_block, pos->statement, ob); break; case STATEMENT_TYPE_COUNT_PLUS_1: /* FALLTHRU */ default: DBG_assert(0, ("pos->statement->type..", pos->statement->type)); } } }
static void push_value(SIMCAR_Interpreter *inter, SIMCAR_Value *value) { DBG_assert(inter->stack.stack_pointer <= inter->stack.stack_alloc_size, ("stack_pointer..%d, stack_alloc_size..%d\n", inter->stack.stack_pointer, inter->stack.stack_alloc_size)); if (inter->stack.stack_pointer == inter->stack.stack_alloc_size) { inter->stack.stack_alloc_size += STACK_ALLOC_SIZE; inter->stack.stack = MEM_realloc(inter->stack.stack, sizeof(SIMCAR_Value) * inter->stack.stack_alloc_size); } inter->stack.stack[inter->stack.stack_pointer] = *value; inter->stack.stack_pointer++; }
void CRB_dispose_interpreter(CRB_Interpreter *interpreter) { release_global_strings(interpreter); if (interpreter->execute_storage) { MEM_dispose_storage(interpreter->execute_storage); } interpreter->variable = NULL; crb_garbage_collect(interpreter); DBG_assert(interpreter->heap.current_heap_size == 0, ("%d bytes leaked.\n", interpreter->heap.current_heap_size)); MEM_free(interpreter->stack.stack); crb_dispose_regexp_literals(interpreter); MEM_dispose_storage(interpreter->interpreter_storage); }
static void generate_code(OpcodeBuf *ob, int line_number, DVM_Opcode code, ...) { va_list ap; int i; char *param; int param_count; int start_pc; va_start(ap, code); param = dvm_opcode_info[(int)code].parameter; param_count = strlen(param); if (ob->alloc_size < ob->size + 1 + (param_count * 2)) { ob->code = MEM_realloc(ob->code, ob->alloc_size + OPCODE_ALLOC_SIZE); ob->alloc_size += OPCODE_ALLOC_SIZE; } start_pc = ob->size; ob->code[ob->size] = code; ob->size++; for (i = 0; param[i] != '\0'; i++) { unsigned int value = va_arg(ap, int); switch (param[i]) { case 'b': /* byte */ ob->code[ob->size] = (DVM_Byte)value; ob->size++; break; case 's': /* short(2byte int) */ ob->code[ob->size] = (DVM_Byte)(value >> 8); ob->code[ob->size+1] = (DVM_Byte)(value & 0xff); ob->size += 2; break; case 'p': /* constant pool index */ ob->code[ob->size] = (DVM_Byte)(value >> 8); ob->code[ob->size+1] = (DVM_Byte)(value & 0xff); ob->size += 2; break; default: DBG_assert(0, ("param..%s, i..%d", param, i)); } } add_line_number(ob, line_number, start_pc); va_end(ap); }
static void generate_binary_expression(DVM_Executable *exe, Block *block, Expression *expr, DVM_Opcode code, OpcodeBuf *ob) { DBG_assert(expr->u.binary_expression.left->type->basic_type == expr->u.binary_expression.right->type->basic_type, ("left..%d, right..%d", expr->u.binary_expression.left->type->basic_type, expr->u.binary_expression.right->type->basic_type)); generate_expression(exe, block, expr->u.binary_expression.left, ob); generate_expression(exe, block, expr->u.binary_expression.right, ob); generate_code(ob, expr->line_number, code + get_opcode_type_offset(expr->u.binary_expression.left ->type->basic_type)); }