[macruby-changes] [4219] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Jun 11 17:37:50 PDT 2010


Revision: 4219
          http://trac.macosforge.org/projects/ruby/changeset/4219
Author:   lsansonetti at apple.com
Date:     2010-06-11 17:37:48 -0700 (Fri, 11 Jun 2010)
Log Message:
-----------
follow new llvm changes + no more rtti

Modified Paths:
--------------
    MacRuby/trunk/bin/rubyc
    MacRuby/trunk/bridgesupport.cpp
    MacRuby/trunk/compiler.cpp
    MacRuby/trunk/compiler.h
    MacRuby/trunk/debugger.cpp
    MacRuby/trunk/llvm.h
    MacRuby/trunk/rakelib/builder/options.rb
    MacRuby/trunk/vm.cpp
    MacRuby/trunk/vm.h

Modified: MacRuby/trunk/bin/rubyc
===================================================================
--- MacRuby/trunk/bin/rubyc	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/bin/rubyc	2010-06-12 00:37:48 UTC (rev 4219)
@@ -65,6 +65,13 @@
     # Misc.
     @tmpdir = (ENV['TMPDIR'] or '/tmp')
     @tmpfiles = []
+
+    @llc_flags = '-relocation-model=pic '
+    if system("#{@llc} -help | grep jit-enable-eh >& /dev/null")
+      @llc_flags << '-jit-enable-eh'
+    else
+      @llc_flags << '-enable-eh'
+    end
   end
 
   def run
@@ -134,7 +141,7 @@
 
       # Compile the bitcode as assembly.
       asm = gen_tmpfile(base + arch, 's')
-      execute("#{@llc} -f \"#{bc}\" -o=\"#{asm}\" -march=#{llc_arch(arch)} -relocation-model=pic -enable-eh")
+      execute("#{@llc} \"#{bc}\" -o=\"#{asm}\" -march=#{llc_arch(arch)} #{@llc_flags}")
 
       # Compile the assembly.
       tmp_obj = gen_tmpfile(base + arch, 'o')

Modified: MacRuby/trunk/bridgesupport.cpp
===================================================================
--- MacRuby/trunk/bridgesupport.cpp	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/bridgesupport.cpp	2010-06-12 00:37:48 UTC (rev 4219)
@@ -11,7 +11,9 @@
 #include <llvm/Constants.h>
 #include <llvm/CallingConv.h>
 #include <llvm/Instructions.h>
-#include <llvm/ModuleProvider.h>
+#if !defined(LLVM_TOT)
+# include <llvm/ModuleProvider.h>
+#endif
 #include <llvm/Intrinsics.h>
 #include <llvm/Analysis/DebugInfo.h>
 #include <llvm/ExecutionEngine/JIT.h>
@@ -191,18 +193,34 @@
 	const Type *llvm_type = convert_type(ftype);
 	Value *fval = new AllocaInst(llvm_type, "", bb);
 
+	const size_t type_size = GET_CORE()->get_sizeof(llvm_type);
+
+#if LLVM_TOT
+	Value *args[] = {
+	    new BitCastInst(fval, PtrTy, "", bb),  	// start
+	    ConstantInt::get(Int8Ty, 0),		// value
+	    ConstantInt::get(IntTy, type_size),		// size
+	    ConstantInt::get(Int32Ty, 0),		// align
+	    ConstantInt::get(Int1Ty, 0)			// volatile
+	};
+	const Type *Tys[] = { args[0]->getType(), args[2]->getType() };
+	Function *memset_func = Intrinsic::getDeclaration(module,
+		Intrinsic::memset, Tys, 2);
+	assert(memset_func != NULL);
+	CallInst::Create(memset_func, args, args + 5, "", bb);
+#else
 	const Type *Tys[] = { IntTy };
 	Function *memset_func = Intrinsic::getDeclaration(module,
 		Intrinsic::memset, Tys, 1);
 	assert(memset_func != NULL);
-
 	Value *args[] = {
 	    new BitCastInst(fval, PtrTy, "", bb),
 	    ConstantInt::get(Int8Ty, 0),
-	    ConstantInt::get(IntTy, GET_CORE()->get_sizeof(llvm_type)),
+	    ConstantInt::get(IntTy, type_size),
 	    ConstantInt::get(Int32Ty, 0)
 	};
 	CallInst::Create(memset_func, args, args + 4, "", bb);
+#endif
 
 	fval = new LoadInst(fval, "", bb);
 	fval = compile_conversion_to_ruby(ftype, llvm_type, fval);

Modified: MacRuby/trunk/compiler.cpp
===================================================================
--- MacRuby/trunk/compiler.cpp	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/compiler.cpp	2010-06-12 00:37:48 UTC (rev 4219)
@@ -700,7 +700,7 @@
 	DILocation loc = debug_info->CreateLocation(current_line, 0,
 		debug_compile_unit, DILocation(NULL));
 #if LLVM_TOT
-	insn->setMetadata(dbg_mdkind, loc.getNode());
+	insn->setMetadata(dbg_mdkind, loc);
 	//insn->setDebugLoc(DebugLoc::getFromDILocation(loc.getNode()));
 #else
 	context.getMetadata().addMD(dbg_mdkind, loc.getNode(), insn);
@@ -1719,8 +1719,6 @@
 void
 RoxorCompiler::compile_return_from_block_handler(int id)
 {
-    //const std::type_info &eh_type = typeid(RoxorReturnFromBlockException *);
-    //Value *exception = compile_landing_pad_header(eh_type);
     Value *exception = compile_landing_pad_header();
 
     if (checkReturnFromBlockFunc == NULL) {
@@ -1905,12 +1903,6 @@
 Value *
 RoxorCompiler::compile_landing_pad_header(void)
 {
-    return compile_landing_pad_header(typeid(void));
-}
-
-Value *
-RoxorCompiler::compile_landing_pad_header(const std::type_info &eh_type)
-{
     Function *eh_exception_f = Intrinsic::getDeclaration(module,
 	    Intrinsic::eh_exception);
     Value *eh_ptr = CallInst::Create(eh_exception_f, "", bb);
@@ -1928,42 +1920,11 @@
     }
     params.push_back(ConstantExpr::getBitCast(__gxx_personality_v0_func, PtrTy));
 
-    if (eh_type == typeid(void)) {
-	// catch (...)
-	params.push_back(compile_const_pointer(NULL));
-    }
-    else {
-	// catch (eh_type &exc)
-	params.push_back(compile_const_pointer((void *)&eh_type));
-	params.push_back(compile_const_pointer(NULL));
-    }
+    // catch (...)
+    params.push_back(compile_const_pointer(NULL));
 
-    Value *eh_sel = CallInst::Create(eh_selector_f, params.begin(),
-	    params.end(), "", bb);
+    CallInst::Create(eh_selector_f, params.begin(), params.end(), "", bb);
 
-    if (eh_type != typeid(void)) {
-	// TODO: this doesn't work yet, the type id must be a GlobalVariable...
-	Function *eh_typeid_for_f = Intrinsic::getDeclaration(module,
-		Intrinsic::eh_typeid_for);
-	std::vector<Value *> params;
-	params.push_back(compile_const_pointer((void *)&eh_type));
-
-	Value *eh_typeid = CallInst::Create(eh_typeid_for_f, params.begin(),
-		params.end(), "", bb);
-
-	Function *f = bb->getParent();
-	BasicBlock *typeok_bb = BasicBlock::Create(context, "typeok", f);
-	BasicBlock *nocatch_bb  = BasicBlock::Create(context, "nocatch", f);
-	Value *need_ret = new ICmpInst(*bb, ICmpInst::ICMP_EQ, eh_sel,
-		eh_typeid);
-	BranchInst::Create(typeok_bb, nocatch_bb, need_ret, bb);
-
-	bb = nocatch_bb;
-	compile_rethrow_exception();
-
-	bb = typeok_bb;
-    }
-
     Function *beginCatchFunc = NULL;
     if (beginCatchFunc == NULL) {
 	// void *__cxa_begin_catch(void *);
@@ -2469,10 +2430,18 @@
 	}
     }
 
+#if LLVM_TOT
+    InlineFunctionInfo IFI;
     for (std::vector<CallInst *>::iterator i = insns.begin();
 	    i != insns.end(); ++i) {
+	InlineFunction(*i, IFI);
+    }
+#else
+    for (std::vector<CallInst *>::iterator i = insns.begin();
+	    i != insns.end(); ++i) {
 	InlineFunction(*i);
     }
+#endif
 }
 
 Function *
@@ -2774,6 +2743,20 @@
 
 	    // Transform the InvokeInst in CallInst.
 	    std::vector<Value *> params;
+#if LLVM_TOT
+	    for (unsigned i = 0; i < invoke->getNumOperands() - 3; i++) {
+		params.push_back(invoke->getOperand(i));
+	    }
+	    CallInst *call_inst = CallInst::Create(
+		    invoke->getCalledValue(),
+		    params.begin(), params.end(),
+		    "",
+		    invoke);
+
+	    invoke->replaceAllUsesWith(call_inst);
+	    BasicBlock *normal_bb = dyn_cast<BasicBlock>
+		(invoke->getNormalDest());
+#else
 	    for (InvokeInst::op_iterator op_it = invoke->op_begin()+3;
 		    op_it != invoke->op_end(); ++op_it) {
 		params.push_back(op_it->get());
@@ -2786,6 +2769,7 @@
 
 	    invoke->replaceAllUsesWith(call_inst);
 	    BasicBlock *normal_bb = dyn_cast<BasicBlock>(invoke->getOperand(1));
+#endif
 	    assert(normal_bb != NULL);
 	    BranchInst::Create(normal_bb, invoke);
 	    invoke->eraseFromParent();

Modified: MacRuby/trunk/compiler.h
===================================================================
--- MacRuby/trunk/compiler.h	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/compiler.h	2010-06-12 00:37:48 UTC (rev 4219)
@@ -396,7 +396,6 @@
 	Value *compile_set_current_class(Value *klass);
 
 	Value *compile_landing_pad_header(void);
-	Value *compile_landing_pad_header(const std::type_info &eh_type);
 	void compile_landing_pad_footer(bool pop_exception=true);
 	Value *compile_current_exception(void);
 	void compile_rethrow_exception(void);

Modified: MacRuby/trunk/debugger.cpp
===================================================================
--- MacRuby/trunk/debugger.cpp	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/debugger.cpp	2010-06-12 00:37:48 UTC (rev 4219)
@@ -11,7 +11,9 @@
 #include <llvm/Constants.h>
 #include <llvm/CallingConv.h>
 #include <llvm/Instructions.h>
-#include <llvm/ModuleProvider.h>
+#if !defined(LLVM_TOT)
+# include <llvm/ModuleProvider.h>
+#endif
 #include <llvm/Intrinsics.h>
 #include <llvm/Analysis/DebugInfo.h>
 #include <llvm/ExecutionEngine/JIT.h>

Modified: MacRuby/trunk/llvm.h
===================================================================
--- MacRuby/trunk/llvm.h	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/llvm.h	2010-06-12 00:37:48 UTC (rev 4219)
@@ -9,7 +9,9 @@
 #include <llvm/Constants.h>
 #include <llvm/CallingConv.h>
 #include <llvm/Instructions.h>
-#include <llvm/ModuleProvider.h>
+#if !defined(LLVM_TOT)
+# include <llvm/ModuleProvider.h>
+#endif
 #include <llvm/Intrinsics.h>
 #include <llvm/Analysis/DebugInfo.h>
 #include <llvm/ExecutionEngine/JIT.h>

Modified: MacRuby/trunk/rakelib/builder/options.rb
===================================================================
--- MacRuby/trunk/rakelib/builder/options.rb	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/rakelib/builder/options.rb	2010-06-12 00:37:48 UTC (rev 4219)
@@ -124,10 +124,11 @@
 CFLAGS = "-I. -I./include #{ARCHFLAGS} -fno-common -pipe -g -Wall -fexceptions #{OPTZFLAG}"
 CFLAGS << " -Wno-deprecated-declarations -Werror" if NO_WARN_BUILD
 OBJC_CFLAGS = CFLAGS + " -fobjc-gc-only"
-CXXFLAGS = `#{LLVM_CONFIG} --cxxflags #{LLVM_MODULES}`.sub(/-DNDEBUG/, '').sub(/-fno-exceptions/, '').strip
+CXXFLAGS = `#{LLVM_CONFIG} --cxxflags #{LLVM_MODULES}`.sub(/-DNDEBUG/, '').sub(/-fno-exceptions/, '').sub(/-Wcast-qual/, '').strip
 CXXFLAGS.sub!(/-O\d/, OPTZFLAG)
 CXXFLAGS << " -I. -I./include -g -Wall #{ARCHFLAGS}"
 CXXFLAGS << " -Wno-deprecated-declarations -Werror" if NO_WARN_BUILD
+CXXFLAGS << " -fno-rtti" unless CXXFLAGS.index("-fno-rtti")
 CXXFLAGS << " -DLLVM_TOT" if ENV['LLVM_TOT']
 CXXFLAGS << " -DLLVM_PRE_TOT" if ENV['LLVM_PRE_TOT']
 LDFLAGS = `#{LLVM_CONFIG} --ldflags --libs #{LLVM_MODULES}`.strip.gsub(/\n/, '')

Modified: MacRuby/trunk/vm.cpp
===================================================================
--- MacRuby/trunk/vm.cpp	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/vm.cpp	2010-06-12 00:37:48 UTC (rev 4219)
@@ -14,7 +14,9 @@
 #include <llvm/Constants.h>
 #include <llvm/CallingConv.h>
 #include <llvm/Instructions.h>
-#include <llvm/ModuleProvider.h>
+#if !defined(LLVM_TOT)
+# include <llvm/ModuleProvider.h>
+#endif
 #include <llvm/PassManager.h>
 #include <llvm/Analysis/DebugInfo.h>
 #include <llvm/Analysis/Verifier.h>
@@ -207,16 +209,6 @@
 	    return mm->getGOTBase();
 	}
 
-#if defined(LLVM_TOT) || defined(LLVM_PRE_TOT)
-	void SetDlsymTable(void *ptr) {
-	    mm->SetDlsymTable(ptr);
-	}
-
-	void *getDlsymTable() const {
-	    return mm->getDlsymTable();
-	}
-#endif
-
 	uint8_t *startFunctionBody(const Function *F, 
 		uintptr_t &ActualSize) {
 	    return mm->startFunctionBody(F, ActualSize);
@@ -263,8 +255,7 @@
 
 	void NotifyFunctionEmitted(const Function &F,
 		void *Code, size_t Size,
-		const EmittedFunctionDetails &Details)
-	{
+		const EmittedFunctionDetails &Details) {
 	    RoxorFunction *function = current_function();
 
 	    std::string path;
@@ -312,19 +303,21 @@
     default_random = Qnil;
 
     load_path = rb_ary_new();
-    rb_objc_retain((void *)load_path);
+    GC_RETAIN(load_path);
 
     loaded_features = rb_ary_new();
-    rb_objc_retain((void *)loaded_features);
+    GC_RETAIN(loaded_features);
 
     threads = rb_ary_new();
-    rb_objc_retain((void *)threads);
+    GC_RETAIN(threads);
 
     bs_parser = NULL;
 
     llvm_start_multithreaded();
 
+#if !defined(LLVM_TOT)
     emp = new ExistingModuleProvider(RoxorCompiler::module);
+#endif
     jmm = new RoxorJITManager;
 
     InitializeNativeTarget();
@@ -358,7 +351,12 @@
     }
 
     std::string err;
+#if LLVM_TOT
+    ee = ExecutionEngine::createJIT(RoxorCompiler::module, &err, jmm, opt,
+	    false);
+#else
     ee = ExecutionEngine::createJIT(emp, &err, jmm, opt, false);
+#endif
     if (ee == NULL) {
 	fprintf(stderr, "error while creating JIT: %s\n", err.c_str());
 	abort();
@@ -366,7 +364,11 @@
     ee->DisableLazyCompilation();
     ee->RegisterJITEventListener(jmm);
 
+#if LLVM_TOT
+    fpm = new FunctionPassManager(RoxorCompiler::module);
+#else
     fpm = new FunctionPassManager(emp);
+#endif
     fpm->add(new TargetData(*ee->getTargetData()));
 
     // Do simple "peephole" optimizations and bit-twiddling optzns.
@@ -452,7 +454,7 @@
 	    GC_WB(&b->locals, orig->locals);
 	    GC_WB(&b->parent_block, orig->parent_block);  // XXX not sure
 #endif
-	    rb_objc_retain(b);
+	    GC_RETAIN(b);
 	    blocks[block_cache_key(orig)] = b;
 	}
 	current_blocks.push_back(b);
@@ -467,7 +469,7 @@
     parse_in_eval = false;
     has_ensure = false;
     return_from_block = -1;
-    throw_exc = NULL;
+    special_exc = NULL;
     current_super_class = NULL;
     current_super_sel = 0;
 
@@ -3175,44 +3177,16 @@
 RoxorVM::push_current_exception(VALUE exc)
 {
     assert(!NIL_P(exc));
-    rb_objc_retain((void *)exc);
+    GC_RETAIN(exc);
     current_exceptions.push_back(exc);
 //printf("PUSH %p %s\n", (void *)exc, RSTRING_PTR(rb_inspect(exc)));
 }
 
-class RoxorThreadRaiseException {
-};
-
-static inline bool
-current_exception_is_return_from_block(void)
-{
-    const std::type_info *exc_type = __cxa_current_exception_type();
-    return exc_type != NULL
-	&& *exc_type == typeid(RoxorReturnFromBlockException *);
-}
-
-static inline bool
-current_exception_is_catch_throw(void)
-{
-    const std::type_info *exc_type = __cxa_current_exception_type();
-    return exc_type != NULL
-	&& *exc_type == typeid(RoxorCatchThrowException *);
-}
-
-static inline bool
-current_exception_is_thread_raise(void)
-{
-    const std::type_info *exc_type = __cxa_current_exception_type();
-    return exc_type != NULL
-	&& *exc_type == typeid(RoxorThreadRaiseException *);
-}
-
 void
 RoxorVM::pop_current_exception(int pos)
 {
-    if (current_exception_is_return_from_block()
-	|| current_exception_is_catch_throw()
-	|| current_exception_is_thread_raise()) {
+    RoxorSpecialException *sexc = get_special_exc();
+    if (sexc != NULL) {
 	return;
     }
 
@@ -3222,7 +3196,7 @@
     VALUE exc = *iter;
     current_exceptions.erase(iter);
 
-    rb_objc_release((void *)exc);
+    GC_RELEASE(exc);
 //printf("POP (%d) %p %s\n", pos, (void *)exc, RSTRING_PTR(rb_inspect(exc)));
 }
 
@@ -3257,7 +3231,7 @@
 rb_vm_raise(VALUE exception)
 {
     rb_iv_set(exception, "bt", rb_vm_backtrace(0));
-    rb_objc_retain((void *)exception);
+    GC_RETAIN(exception);
     GET_VM()->push_current_exception(exception);
     __vm_raise();
 }
@@ -3381,6 +3355,7 @@
     if (vm->get_has_ensure() || (running_block->flags & VM_BLOCK_PROC)) {
 	RoxorReturnFromBlockException *exc =
 	    new RoxorReturnFromBlockException();
+	vm->set_special_exc(exc);
 	exc->val = val;
 	exc->id = id;
 	throw exc;
@@ -3410,11 +3385,14 @@
 VALUE
 rb_vm_check_return_from_block_exc(RoxorReturnFromBlockException **pexc, int id)
 {
-    if (current_exception_is_return_from_block()) {
+    RoxorVM *vm = GET_VM();
+    RoxorSpecialException *sexc = vm->get_special_exc();
+    if (sexc != NULL && sexc->type == RETURN_FROM_BLOCK_EXCEPTION) {
 	RoxorReturnFromBlockException *exc = *pexc;
 	if (id == -1 || exc->id == id) {
 	    VALUE val = exc->val;
 	    delete exc;
+	    vm->set_special_exc(NULL);
 	    return val;
 	}
     }
@@ -3963,30 +3941,27 @@
 {
     VALUE retval = Qundef;
 
-    this->increase_nesting_for_tag(tag);
+    increase_nesting_for_tag(tag);
     try {
 	retval = rb_vm_yield(1, &tag);
     }
     catch (...) {
-	// Cannot catch "RoxorCatchThrowException *exc", otherwise the program
-	// will crash when trying to interpret ruby exceptions.
-	// So we catch ... instead, and retrieve the exception from the VM.
-	std::type_info *t = __cxa_current_exception_type();
-	if (t != NULL && *t == typeid(RoxorCatchThrowException *)) {
-	    RoxorCatchThrowException *exc = GET_VM()->get_throw_exc();
-	    if (exc != NULL && exc->throw_symbol == tag) {
+	RoxorSpecialException *sexc = get_special_exc();
+	if (sexc != NULL && sexc->type == CATCH_THROW_EXCEPTION) {
+	    RoxorCatchThrowException *exc = (RoxorCatchThrowException *)sexc;
+	    if (exc->throw_symbol == tag) {
 		retval = exc->throw_value;
 		GC_RELEASE(retval);
 		delete exc;
-		GET_VM()->set_throw_exc(NULL);
+		set_special_exc(NULL);
 	    }
 	}
 	if (retval == Qundef) {
-	    this->decrease_nesting_for_tag(tag);
+	    decrease_nesting_for_tag(tag);
 	    throw;
 	}
     }
-    this->decrease_nesting_for_tag(tag); 
+    decrease_nesting_for_tag(tag); 
 
     return retval;
 }
@@ -4016,11 +3991,9 @@
     }
 
     RoxorCatchThrowException *exc = new RoxorCatchThrowException;
+    set_special_exc(exc);
     exc->throw_symbol = tag;
     exc->throw_value = value;
-    // There is no way - yet - to retrieve the exception from the ABI
-    // So instead, we store the exception in the VM
-    set_throw_exc(exc);
     throw exc;
 
     return Qnil; // Never reached;
@@ -4251,14 +4224,17 @@
 
     pthread_cleanup_push(rb_vm_thread_destructor, (void *)thread);
 
+    RoxorVM *vm = GET_VM();
     try {
 	VALUE val = rb_vm_block_eval(t->body, t->argc, t->argv);
 	GC_WB(&t->value, val);
     }
     catch (...) {
 	VALUE exc;
-	if (current_exception_is_return_from_block()) {
-	    // TODO: the exception is leaking!
+	RoxorSpecialException *sexc = vm->get_special_exc();
+	if (sexc != NULL && sexc->type == RETURN_FROM_BLOCK_EXCEPTION) {
+	    delete sexc;
+	    vm->set_special_exc(NULL);
 	    exc = rb_exc_new2(rb_eLocalJumpError,
 		    "unexpected return from Thread");
 	}
@@ -4580,7 +4556,11 @@
 Init_PreVM(void)
 {
     // To emit DWARF exception tables. 
+#if LLVM_TOT
+    llvm::JITExceptionHandling = true;
+#else
     llvm::DwarfExceptionHandling = true; 
+#endif
     // To emit DWARF debug metadata. 
     llvm::JITEmitDebugInfo = true; 
     // To not interfere with our signal handling mechanism.

Modified: MacRuby/trunk/vm.h
===================================================================
--- MacRuby/trunk/vm.h	2010-06-11 02:37:41 UTC (rev 4218)
+++ MacRuby/trunk/vm.h	2010-06-12 00:37:48 UTC (rev 4219)
@@ -666,7 +666,9 @@
 
     private:
 	// LLVM objects.
+#if !defined(LLVM_TOT)
 	ExistingModuleProvider *emp;
+#endif
 	RoxorJITManager *jmm;
 	ExecutionEngine *ee;
 	FunctionPassManager *fpm;
@@ -904,20 +906,45 @@
     METHOD_MISSING_SUPER
 } rb_vm_method_missing_reason_t;
 
-// Custom C++ exception class for catch/throw blocks.
-class RoxorCatchThrowException {
+// MacRuby doesn't compile with rtti so we make our own.
+#define CATCH_THROW_EXCEPTION		1
+#define RETURN_FROM_BLOCK_EXCEPTION	2
+#define THREAD_RAISE_EXCEPTION		3
+
+class RoxorSpecialException {
     public:
+	int type;
+
+	RoxorSpecialException(int _type) { type = _type; }
+};
+
+// Custom C++ exception class used to implement catch/throw.
+class RoxorCatchThrowException : public RoxorSpecialException {
+    public:
 	VALUE throw_symbol;
 	VALUE throw_value;
+
+	RoxorCatchThrowException()
+	    : RoxorSpecialException(CATCH_THROW_EXCEPTION) {}
 };
 
 // Custom C++ exception class used to implement "return-from-block".
-class RoxorReturnFromBlockException {
+class RoxorReturnFromBlockException : public RoxorSpecialException {
     public:
 	VALUE val;
 	int id;
+
+	RoxorReturnFromBlockException()
+	    : RoxorSpecialException(RETURN_FROM_BLOCK_EXCEPTION) {}
 };
 
+// Custom C++ exception class used to implement thread cancelation.
+class RoxorThreadRaiseException : public RoxorSpecialException {
+    public:
+	RoxorThreadRaiseException()
+	    : RoxorSpecialException(THREAD_RAISE_EXCEPTION) {}
+};
+
 // The VM class is instantiated per thread. There is always at least one
 // instance. The VM class is purely thread-safe and concurrent, it does not
 // acquire any lock, except when it calls the Core.
@@ -972,7 +999,7 @@
 	Class current_super_class;
 	SEL current_super_sel;	
 
-	RoxorCatchThrowException *throw_exc;
+	RoxorSpecialException *special_exc;
 
 	void increase_nesting_for_tag(VALUE tag);
 	void decrease_nesting_for_tag(VALUE tag);
@@ -994,7 +1021,7 @@
 	ACCESSOR(parse_in_eval, bool);
 	ACCESSOR(has_ensure, bool);
 	ACCESSOR(return_from_block, int);
-	ACCESSOR(throw_exc, RoxorCatchThrowException *);
+	ACCESSOR(special_exc, RoxorSpecialException *);
 	ACCESSOR(current_super_class, Class);
 	ACCESSOR(current_super_sel, SEL);
 	READER(mcache, struct mcache *);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100611/8f4ed700/attachment-0001.html>


More information about the macruby-changes mailing list