Пример #1
0
	void setPersistentFunc(Persistent<Function>& pf,Handle<Value>& v){
		if(v->IsFunction()){
			if(!pf.IsEmpty()) pf.Dispose();
			pf = Persistent<Function>::New(Handle<Function>::Cast(v));
		}else if(v->IsNull()||v->IsUndefined()){
			if(pf.IsEmpty()) return;
			pf.Dispose();
			pf.Clear();
		}
	}
Пример #2
0
static Handle<Value> Nil(const Arguments& args)
{
    HandleScope handle_scope;

    if (object_template_.IsEmpty()) {
        Handle<ObjectTemplate> raw_template = PrepareTemplate();
        object_template_ = Persistent<ObjectTemplate>::New(raw_template);
    }

    if (nil_instance_.IsEmpty()) {
        nil_instance_ = Persistent<Value>::New(object_template_->NewInstance());
    }
    
    return handle_scope.Close(nil_instance_);
}
Пример #3
0
extern "C" Handle<Value> execute_string(Persistent<Context> context,
					const char* s,
					bool* is_exception) {
    // Create a stack-allocated handle scope.
    HandleScope handle_scope;

    // Enter the created context for compiling and
    // running the hello world script.
    Context::Scope context_scope(context);

    // Create a string containing the JavaScript source code.
    Handle<String> source = String::New(s);

    // Compile it
    Handle<Script> script = Script::Compile(source);

    // try-catch handler
    TryCatch trycatch;
    // Run it
    Persistent<Value> result = Persistent<Value>::New(script->Run());

    // Script->Run() returns an empty handle if the code threw an exception
    if (result.IsEmpty()) {
	*is_exception = true;
	Handle<Value> exception = trycatch.Exception();
	// String::AsciiValue exception_str(exception);
	return Persistent<Value>::New(exception);	
    }
    
    return result;
}
static void TitaniumCountlyAndroidMessaging_dispose()
{
	HandleScope scope;
	if (bindingCache.IsEmpty()) {
		return;
	}

	Local<Array> propertyNames = bindingCache->GetPropertyNames();
	uint32_t length = propertyNames->Length();

	for (uint32_t i = 0; i < length; ++i) {
		String::Utf8Value binding(propertyNames->Get(i));
		int bindingLength = binding.length();

		titanium::bindings::BindEntry *extBinding =
			::TitaniumCountlyAndroidMessagingBindings::lookupGeneratedInit(*binding, bindingLength);

		if (extBinding && extBinding->dispose) {
			extBinding->dispose();
		}
	}

	bindingCache.Dispose();
	bindingCache = Persistent<Object>();
}
Пример #5
0
/*
 * Class:     org_appcelerator_kroll_runtime_v8_V8Runtime
 * Method:    nativeRunModule
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_org_appcelerator_kroll_runtime_v8_V8Runtime_nativeRunModule
	(JNIEnv *env, jobject self, jstring source, jstring filename, jobject activityProxy)
{
	ENTER_V8(V8Runtime::globalContext);
	titanium::JNIScope jniScope(env);

	if (moduleObject.IsEmpty()) {
		moduleObject = Persistent<Object>::New(
			V8Runtime::krollGlobalObject->Get(String::New("Module"))->ToObject());

		runModuleFunction = Persistent<Function>::New(
			Handle<Function>::Cast(moduleObject->Get(String::New("runModule"))));
	}

	Handle<Value> jsSource = TypeConverter::javaStringToJsString(source);
	Handle<Value> jsFilename = TypeConverter::javaStringToJsString(filename);
	Handle<Value> jsActivity = TypeConverter::javaObjectToJsValue(activityProxy);

	Handle<Value> args[] = { jsSource, jsFilename, jsActivity };
	TryCatch tryCatch;

	runModuleFunction->Call(moduleObject, 3, args);

	if (tryCatch.HasCaught()) {
		V8Util::openJSErrorDialog(tryCatch);
		V8Util::reportException(tryCatch, true);
	}
}
Пример #6
0
JNIEXPORT void JNICALL Java_ag_boersego_bgjs_ClientAndroid_load(JNIEnv * env,
		jobject obj, jlong ctxPtr, jstring path) {
	BGJSContext* ct = (BGJSContext*) ctxPtr;
	const char* pathStr = env->GetStringUTFChars(path, 0);
	Persistent<Script> res = ct->load(pathStr);
	if (!res.IsEmpty()) {
		ct->_script = res;
	}
	env->ReleaseStringUTFChars(path, pathStr);
}
Handle<Value> TiRootObject::_require(void* userContext, TiObject* caller, const Arguments& args)
{
	HandleScope scope;
	Local<Object> globalObject = TitaniumRuntime::getContenxt()->Global();

	Handle<Value> nativeModule = TiModuleRegistry::GetModule(QString(*String::Utf8Value(args[0]->ToString())));
	if(!nativeModule->IsUndefined())
	{
		return scope.Close(nativeModule);
	}
	QString fileName = Ti::TiHelper::QStringFromValue(args[0]).append(".js");
	QString filePath = Ti::TiHelper::getAssetPath(fileName).prepend("app/native/");
	Local<Value> existingModule = globalObject->GetHiddenValue(Ti::TiHelper::ValueFromQString(fileName)->ToString());
	if(!existingModule.IsEmpty() && !existingModule->IsUndefined())
	{
		return scope.Close(existingModule);
	}

	QString js = readJsFile(filePath);
	if(js.isEmpty()) {
		ThrowException(String::New(
								QString("Module not found ").append(fileName).toLocal8Bit().constData()
						));
		return scope.Close(Undefined());
	}
	js.prepend("(function(){"
			"var __vars = {};"
			"__vars.exports = {};"
			"__vars.module = {exports:__vars.exports};"
			"var module = __vars.module;"
			"var exports = __vars.exports;");
	js.append("\nreturn __vars.module.exports;"
			"})();");


	Handle<Script> script = Script::Compile(Ti::TiHelper::ValueFromQString(js)->ToString() , Ti::TiHelper::ValueFromQString(fileName));
	TryCatch tryCatch;
	if (script.IsEmpty())
	{
    	Ti::TiErrorScreen::ShowWithTryCatch(tryCatch);
		return scope.Close(Undefined());
	}
	Persistent<Value> result = Persistent<Value>::New(script->Run());
	result.MarkIndependent();
	if (result.IsEmpty())
	{
    	Ti::TiErrorScreen::ShowWithTryCatch(tryCatch);
		return scope.Close(Undefined());
	}
	globalObject->SetHiddenValue(Ti::TiHelper::ValueFromQString(fileName)->ToString(), result);
	return scope.Close(result);
}
Пример #8
0
Handle<Object> Log::Wrap()
{
	Isolate *isolate = jsCompiler_.GetIsolate();
	HandleScope scope(isolate);

	if (logTemplate.IsEmpty()) {
		Handle<ObjectTemplate> objTemplate = MakeLogTemplate(isolate);
		logTemplate.Reset(isolate, objTemplate);
	}
	Handle<ObjectTemplate> local = Local<ObjectTemplate>::New(isolate, logTemplate);
	Handle<Object> obj = local->NewInstance();
	Handle<External> log_ptr = External::New(this);
	obj->SetInternalField(0, log_ptr);
	return scope.Close(obj);
}
Пример #9
0
bool V8Util::isNaN(Handle<Value> value)
{
	HandleScope scope;
	Local<Object> global = Context::GetCurrent()->Global();

	if (isNaNFunction.IsEmpty()) {
		Local<Value> isNaNValue = global->Get(String::NewSymbol("isNaN"));
		isNaNFunction = Persistent<Function>::New(isNaNValue.As<Function> ());
	}

	Handle<Value> args[] = { value };

	return isNaNFunction->Call(global, 1, args)->BooleanValue();

}
Пример #10
0
   bool ScriptSystem::RemoveFromComponentMap(dtEntity::ComponentType ct, dtEntity::EntityId eid)
   {
      ComponentMap::iterator it = mComponentMap.find(std::make_pair(ct, eid));
      if(it == mComponentMap.end())
      {
         return false;
      }
      HandleScope scope;
      Persistent<Object> obj = it->second;
      assert(!obj.IsEmpty() && obj->IsObject());
      // invalidate component wrapper
      obj->SetInternalField(0, External::New(0));
      obj.Dispose();
      mComponentMap.erase(it);
      V8::AdjustAmountOfExternalAllocatedMemory(-(int)sizeof(dtEntity::Component));
      return true;

   }
Пример #11
0
void V8Util::reportException(TryCatch &tryCatch, bool showLine)
{
	HandleScope scope;
	Handle<Message> message = tryCatch.Message();

	if (nameSymbol.IsEmpty()) {
		nameSymbol = SYMBOL_LITERAL("name");
		messageSymbol = SYMBOL_LITERAL("message");
	}

	if (showLine) {
		Handle<Message> message = tryCatch.Message();
		if (!message.IsEmpty()) {
			String::Utf8Value filename(message->GetScriptResourceName());
			String::Utf8Value msg(message->Get());
			int linenum = message->GetLineNumber();
			LOGE(EXC_TAG, "Exception occurred at %s:%i: %s", *filename, linenum, *msg);
		}
	}

	Local<Value> stackTrace = tryCatch.StackTrace();
	String::Utf8Value trace(tryCatch.StackTrace());

	if (trace.length() > 0 && !stackTrace->IsUndefined()) {
		LOGD(EXC_TAG, *trace);
	} else {
		Local<Value> exception = tryCatch.Exception();
		if (exception->IsObject()) {
			Handle<Object> exceptionObj = exception->ToObject();
			Handle<Value> message = exceptionObj->Get(messageSymbol);
			Handle<Value> name = exceptionObj->Get(nameSymbol);

			if (!message->IsUndefined() && !name->IsUndefined()) {
				String::Utf8Value nameValue(name);
				String::Utf8Value messageValue(message);
				LOGE(EXC_TAG, "%s: %s", *nameValue, *messageValue);
			}
		} else {
			String::Utf8Value error(exception);
			LOGE(EXC_TAG, *error);
		}
	}
}
Пример #12
0
  static Persistent<Object> getPlugin(shared_ptr<PluginContext> script)
  {
    Context::Scope context_scope(script->getContext());
    HandleScope handleScope;
    Handle<Object> global = script->getContext()->Global();

    if (global->Has(String::New("plugin")) == false)
    {
      throw IllegalArgumentException("Expected the script to have exports.");
    }

    Handle<Value> pluginValue = global->Get(String::New("plugin"));
    Persistent<Object> plugin = Persistent<Object>::New(Handle<Object>::Cast(pluginValue));
    if (plugin.IsEmpty() || plugin->IsObject() == false)
    {
      throw IllegalArgumentException("Expected plugin to be a valid object.");
    }

    return plugin;
  }
Пример #13
0
    static Handle<Value> WrapResults(cached_object cache)
    {
        HandleScope handle_scope;


        if (object_template_.IsEmpty()) {
            Handle<ObjectTemplate> raw_template = PrepareTemplate();
            object_template_ = Persistent<ObjectTemplate>::New(raw_template);
        }

        Handle<Object> new_object = object_template_->NewInstance();
        //new_object->SetInternalField(1, External::New(results));

        //printf("Here: %x\n", buffer);

        object* obj = new object(cache);
        obj->Wrap(new_object);
        // TODO: Lookup the args id and wrap it

        //printf("Wrapped and returning\n");

        return handle_scope.Close(new_object);
    }
static Handle<Value> TitaniumCountlyAndroidMessaging_getBinding(const Arguments& args)
{
	HandleScope scope;

	if (args.Length() == 0) {
		return ThrowException(Exception::Error(String::New("TitaniumCountlyAndroidMessaging.getBinding requires 1 argument: binding")));
	}

	if (bindingCache.IsEmpty()) {
		bindingCache = Persistent<Object>::New(Object::New());
	}

	Handle<String> binding = args[0]->ToString();

	if (bindingCache->Has(binding)) {
		return bindingCache->Get(binding);
	}

	String::Utf8Value bindingValue(binding);

	LOGD(TAG, "Looking up binding: %s", *bindingValue);

	titanium::bindings::BindEntry *extBinding = ::TitaniumCountlyAndroidMessagingBindings::lookupGeneratedInit(
		*bindingValue, bindingValue.length());

	if (!extBinding) {
		LOGE(TAG, "Couldn't find binding: %s, returning undefined", *bindingValue);
		return Undefined();
	}

	Handle<Object> exports = Object::New();
	extBinding->bind(exports);
	bindingCache->Set(binding, exports);

	return exports;
}
Пример #15
0
 Persistent<Context> gcx() {
   if (gRootContext.IsEmpty()) {
     gRootContext = Context::New();
   }
   return gRootContext;
 }
Пример #16
0
JNIEXPORT bool JNICALL Java_ag_boersego_bgjs_ClientAndroid_ajaxDone(
		JNIEnv * env, jobject obj, jlong ctxPtr, jstring dataStr, jint responseCode,
		jlong jsCbPtr, jlong thisPtr, jlong errorCb, jboolean success, jboolean processData) {

	BGJSContext* context = (BGJSContext*)ctxPtr;

	const char *nativeString = env->GetStringUTFChars(dataStr, 0);
	v8::Locker l;
	Context::Scope context_scope(context->_context);

	HandleScope scope;
	TryCatch trycatch;

	Persistent<Object> thisObj = static_cast<Object*>((void*)thisPtr);
	Persistent<Function> errorP;
	if (errorCb) {
		errorP = static_cast<Function*>((void*)errorCb);
	}
	Persistent<Function> callbackP = static_cast<Function*>((void*)jsCbPtr);

	Handle<Value> argarray[1];
	int argcount = 1;

	if (nativeString == 0 || dataStr == 0) {
		argarray[0] = v8::Null();
	} else {
		Handle<Value> resultObj;
		if (processData) {
			resultObj = context->JsonParse(thisObj,
				String::New(nativeString));
		} else {
			resultObj = String::New(nativeString);
		}

		argarray[0] = resultObj;
	}


	Handle<Value> result;

	if (success) {
		result = callbackP->Call(thisObj, argcount, argarray);
	} else {
		if (!errorP.IsEmpty()) {
			result = errorP->Call(thisObj, argcount, argarray);
		} else {
			LOGI("Error signaled by java code but no error callback set");
			result = v8::Undefined();
		}
	}
	if (result.IsEmpty()) {
		BGJSContext::ReportException(&trycatch);
	}
	env->ReleaseStringUTFChars(dataStr, nativeString);
	callbackP.Dispose();
	thisObj.Dispose();
	if (!errorP.IsEmpty()) {
		errorP.Dispose();
	}

	return true;
}
Пример #17
0
Handle<Value> WrappedScript::EvalMachine(const Arguments& args)
{
	HandleScope scope;

	if (input_flag == compileCode && args.Length() < 1) {
		return ThrowException(Exception::TypeError(String::New("needs at least 'code' argument.")));
	}

	const int sandbox_index = input_flag == compileCode ? 1 : 0;
	if (context_flag == userContext && args.Length() < (sandbox_index + 1)) {
		return ThrowException(Exception::TypeError(String::New("needs a 'context' argument.")));
	}

	Local<String> code;
	if (input_flag == compileCode) code = args[0]->ToString();

	Local<Object> sandbox;
	if (context_flag == newContext) {
		sandbox = args[sandbox_index]->IsObject() ? args[sandbox_index]->ToObject() : Object::New();
	} else if (context_flag == userContext) {
		sandbox = args[sandbox_index]->ToObject();
	}

	const int filename_index = sandbox_index + (context_flag == newContext ? 1 : 0);
	Local<String> filename =
			args.Length() > filename_index ? args[filename_index]->ToString() : String::New("evalmachine.<anonymous>");

	const int display_error_index = args.Length() - 1;
	bool display_error = false;
	if (args.Length() > display_error_index && args[display_error_index]->IsBoolean()
		&& args[display_error_index]->BooleanValue() == true) {
		display_error = true;
	}

	Persistent<Context> context;

	Local<Array> keys;
	unsigned int i;
	WrappedContext *nContext = NULL;
	Local<Object> contextArg;

	if (context_flag == newContext) {
		// Create the new context
		context = Context::New();

	} else if (context_flag == userContext) {
		// Use the passed in context
		contextArg = args[sandbox_index]->ToObject();
		nContext = NativeObject::Unwrap<WrappedContext>(contextArg);
		context = nContext->GetV8Context();
	}

	// New and user context share code. DRY it up.
	if (context_flag == userContext || context_flag == newContext) {
		// Enter the context
		context->Enter();

		// Call the initCallback, if it exists
		if (nContext) {
			Persistent<Function> initCallback = nContext->GetInitCallback();

			if (!initCallback.IsEmpty()) {
				Handle<Value> callbackArgs[] = { contextArg, context->Global() };
				initCallback->Call(contextArg, 2, callbackArgs);
			}
		}

		// Copy everything from the passed in sandbox (either the persistent
		// context for runInContext(), or the sandbox arg to runInNewContext()).
		keys = sandbox->GetPropertyNames();

		for (i = 0; i < keys->Length(); i++) {
			Handle<String> key = keys->Get(Integer::New(i))->ToString();
			Handle<Value> value = sandbox->Get(key);
			if (value == sandbox) {
				value = context->Global();
			}
			context->Global()->Set(key, value);
		}
	}

	Handle<Value> result;
	Handle<Script> script;

	if (input_flag == compileCode) {
		// well, here WrappedScript::New would suffice in all cases, but maybe
		// Compile has a little better performance where possible
		script = output_flag == returnResult ? Script::Compile(code, filename) : Script::New(code, filename);
		if (script.IsEmpty()) {
			// Hack because I can't get a proper stacktrace on SyntaxError
			return Undefined();
		}
	} else {
		WrappedScript *n_script = NativeObject::Unwrap<WrappedScript>(args.Holder());
		if (!n_script) {
			return ThrowException(Exception::Error(String::New("Must be called as a method of Script.")));
		} else if (n_script->script_.IsEmpty()) {
			return ThrowException(Exception::Error(String::New("'this' must be a result of previous "
				"new Script(code) call.")));
		}

		script = n_script->script_;
	}

	if (output_flag == returnResult) {
		result = script->Run();
		if (result.IsEmpty()) {
			if (context_flag == newContext) {
				context->DetachGlobal();
				context->Exit();
				context.Dispose();
			}
			return Undefined();
		}
	} else {
		WrappedScript *n_script = NativeObject::Unwrap<WrappedScript>(args.Holder());
		if (!n_script) {
			return ThrowException(Exception::Error(String::New("Must be called as a method of Script.")));
		}
		n_script->script_ = Persistent<Script>::New(script);
		result = args.This();
	}

	if (context_flag == userContext || context_flag == newContext) {
		// success! copy changes back onto the sandbox object.
		keys = context->Global()->GetPropertyNames();
		for (i = 0; i < keys->Length(); i++) {
			Handle<String> key = keys->Get(Integer::New(i))->ToString();
			Handle<Value> value = context->Global()->Get(key);
			if (value == context->Global()) {
				value = sandbox;
			}
			sandbox->Set(key, value);
		}
	}

	if (context_flag == newContext) {
		// Clean up, clean up, everybody everywhere!
		context->DetachGlobal();
		context->Exit();
		context.Dispose();
	} else if (context_flag == userContext) {
		// Exit the passed in context.
		context->Exit();
	}

	if (result->IsObject()) {
		Local<Context> creation = result->ToObject()->CreationContext();
	}

	return result == args.This() ? result : scope.Close(result);
}
Пример #18
0
int main (int argc, char** argv) {
    signal(SIGSEGV, AnsiSignalHandler);
    //    printf("SILK V0.1\n");
    char *startup;
    const char *progName;
    signal(SIGSEGV, AnsiSignalHandler);
    signal(SIGINT, AnsiSignalHandler);

    if (argc < 2) {
        startup = readFile("/usr/local/silkjs/builtin/interpreter.js");
        if (!startup) {
            startup = readFile("/usr/share/silkjs/builtin/interpreter.js");
        }
        progName = "interpreter";
    }
    else {
        startup = readFile(argv[1]);
        progName = argv[1];
    }
    if (!startup) {
        printf("%s not found\n", argv[1]);
        exit(1);
    }
    if (startup[0] == '#' && startup[1] == '!') {
        startup[0] = startup[1] = '/';
    }
    
    // v8 command line switches
    const char *switches = "--harmony";
    V8::SetFlagsFromString(switches, strlen(switches));
    
    {
        //		Isolate *isolate = Isolate::New();
        //		isolate->Enter();
        //		Locker lock(isolate);
        Locker locker;
        HandleScope scope;

        init_global_object();
        V8::SetCaptureStackTraceForUncaughtExceptions(true, 50); // , StackTrace::kDetailed);
        context = Context::New(NULL, globalObject);
        Context::Scope context_scope(context);
        {
            Locker locker;
            //			Debug::SetDebugMessageDispatchHandler(debugger, true);
            //			Debug::EnableAgent("silkjs", 5858);

            Handle<Script>init = Script::New(String::New("global=this; module = {}; include('builtin/all.js');"), String::New("builtin"));
            init->Run();
            V8::SetCaptureStackTraceForUncaughtExceptions(true, 50, StackTrace::kDetailed);
            TryCatch tryCatch;
            mainScript = Persistent<Script>::New(Script::Compile(String::New(startup), String::New(progName)));
            if (mainScript.IsEmpty()) {
                ReportException(&tryCatch);
                exit(1);
            }
            Handle<Value>v = mainScript->Run();
            if (v.IsEmpty()) {
                ReportException(&tryCatch);
                exit(1);
            }
            Handle<String> process_name = String::New("main");
            Handle<Value> process_val = context->Global()->Get(process_name);
            if (!process_val.IsEmpty() && process_val->IsFunction()) {
                Handle<Function> process_fun = Handle<Function>::Cast(process_val);
                mainFunc = Persistent<Function>::New(process_fun);
                int ac = argc - 2;
                if (ac < 0) {
                    ac = 0;
                }
                Handle<Value>av[ac];
                for (int i = 2; i < argc; i++) {
                    av[i - 2] = String::New(argv[i]);
                }
                v = mainFunc->Call(context->Global(), ac, av);
                if (v.IsEmpty()) {
                    ReportException(&tryCatch);
                    exit(1);
                }
            }
        }
        context.Dispose();
    }
}
Handle<Value> TiRootObject::_globalRequire(void*, TiObject*, const Arguments& args)
{
	if (args.Length() < 2)
	{
		return ThrowException(String::New(Ti::Msg::Missing_argument));
	}

	string id = *String::Utf8Value(args[0]->ToString());

	string parentFolder = *String::Utf8Value(args[1]->ToString());

	// CommonJS path rules
	if (id.find("/") == 0) {
		id.replace(id.find("/"), std::string("/").length(), rootFolder);
	}
	else if (id.find("./") == 0) {
		id.replace(id.find("./"), std::string("./").length(), parentFolder);
	}
	else if (id.find("../") == 0) {
		// count ../../../ in id and strip off back of parentFolder
		int count = 0;
		size_t idx = 0;
		size_t pos = 0;
		while (true) {
			idx = id.find("../", pos);
			if (idx == std::string::npos) {
				break;
			} else {
				pos = idx + 3;
				count++;
			}
		}

		// strip leading ../../ off module id
		id = id.substr(pos);

		// strip paths off the parent folder
		idx = 0;
		pos = parentFolder.size();
		for (int i = 0; i < count; i++) {
			idx = parentFolder.find_last_of("/", pos);
			pos = idx - 1;
		}

		if (idx == std::string::npos) {
			return ThrowException(String::New("Unable to find module"));
		}

		parentFolder = parentFolder.substr(0, idx + 1);

		id = parentFolder + id;
	}
	else {
		string tempId = rootFolder + id;

		ifstream ifs((tempId + ".js").c_str());
		if (!ifs) {
			id = parentFolder + id;
		}
		else {
			id = rootFolder + id;
		}
	}

	string filename = id + ".js";

	// check if cached
	static map<string, Persistent<Value> > cache;
	map<string, Persistent<Value> >::const_iterator cachedValue = cache.find(id);
	if (cachedValue != cache.end())
	{
		return cachedValue->second;
	}

	string javascript;
	{
		ifstream ifs((filename).c_str());
		if (!ifs)
		{
			Local<Value> taggedMessage = String::New((string(Ti::Msg::No_such_native_module) + " " + id).c_str());
			return ThrowException(taggedMessage);
		}
		getline(ifs, javascript, string::traits_type::to_char_type(string::traits_type::eof()));
		ifs.close();
	}

	// wrap the module
	{
		size_t idx = filename.find_last_of("/");
		parentFolder = filename.substr(0, idx + 1);
		static const string requireWithParent = "var require = function (id) { return globalRequire(id, '" + parentFolder + "')};\n";
		static const string preWrap = "(function () {" + requireWithParent + "\nvar module = { exports: {} }; var exports = module.exports;\n";
		static const string postWrap = "\nreturn module.exports; })();";
		javascript =  preWrap + javascript + postWrap;
	}

	TryCatch tryCatch;
	Handle<Script> compiledScript = Script::Compile(String::New(javascript.c_str()), String::New(filename.c_str()));
	if (compiledScript.IsEmpty())
	{
		DisplayExceptionLine(tryCatch);
		return tryCatch.ReThrow();
	}

	Persistent<Value> result = Persistent<Value>::New(compiledScript->Run());
	if (result.IsEmpty())
	{
		return tryCatch.ReThrow();
	}

	// cache result
	cache.insert(pair<string, Persistent<Value> >(id, result));

	return result;
}
Handle<Value> TiTitaniumObject::_globalInclude(void*, TiObject*, const Arguments& args)
{
	if (args.Length() < 2)
	{
		return ThrowException(String::New(Ti::Msg::Missing_argument));
	}

	string id = *String::Utf8Value(args[0]->ToString());

	string parentFolder = *String::Utf8Value(args[1]->ToString());

	// CommonJS path rules
	if (id.find("/") == 0) {
		id.replace(id.find("/"), std::string("/").length(), rootFolder);
	}
	else if (id.find("./") == 0) {
		id.replace(id.find("./"), std::string("./").length(), parentFolder);
	}
	else if (id.find("../") == 0) {
		// count ../../../ in id and strip off back of parentFolder
		int count = 0;
		size_t idx = 0;
		size_t pos = 0;
		while (true) {
			idx = id.find("../", pos);
			if (idx == std::string::npos) {
				break;
			} else {
				pos = idx + 3;
				count++;
			}
		}

		// strip leading ../../ off module id
		id = id.substr(pos);

		// strip paths off the parent folder
		idx = 0;
		pos = parentFolder.size();
		for (int i = 0; i < count; i++) {
			idx = parentFolder.find_last_of("/", pos);
			pos = idx - 1;
		}

		if (idx == std::string::npos) {
			return ThrowException(String::New("Unable to find module"));
		}

		parentFolder = parentFolder.substr(0, idx + 1);

		id = parentFolder + id;
	}
	else {
		string tempId = rootFolder + id;

		ifstream ifs((tempId).c_str());
		if (!ifs) {
			id = parentFolder + id;
		}
		else {
			id = rootFolder + id;
		}
	}

	string filename = id;

	string javascript;
	{
		ifstream ifs((filename).c_str());
		if (!ifs)
		{
			Local<Value> taggedMessage = String::New((string(Ti::Msg::No_such_native_module) + " " + id).c_str());
			return ThrowException(taggedMessage);
		}
		getline(ifs, javascript, string::traits_type::to_char_type(string::traits_type::eof()));
		ifs.close();
	}

	// wrap the module
	{
		size_t idx = filename.find_last_of("/");
		parentFolder = filename.substr(0, idx + 1);
		static const string preWrap = "Ti.include = function (id) { Ti.globalInclude(id, '" + parentFolder + "')};\n";
		javascript = preWrap + javascript;
	}

	TryCatch tryCatch;
	Handle<Script> compiledScript = Script::Compile(String::New(javascript.c_str()), String::New(filename.c_str()));
	if (compiledScript.IsEmpty())
	{
		DisplayExceptionLine(tryCatch);
		return tryCatch.ReThrow();
	}

	Persistent<Value> result = Persistent<Value>::New(compiledScript->Run());
	if (result.IsEmpty())
	{
		return tryCatch.ReThrow();
	}


    return Undefined();
}