mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Limit scope of modeline search (#2967)
Only matches the first and last 5 lines against the modeline regular expressions
This commit is contained in:
		
				
					committed by
					
						 Arfon Smith
						Arfon Smith
					
				
			
			
				
	
			
			
			
						parent
						
							9ae19a1f94
						
					
				
				
					commit
					5c19f1f546
				
			| @@ -15,6 +15,10 @@ module Linguist | |||||||
|  |  | ||||||
|       MODELINES = [EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2] |       MODELINES = [EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2] | ||||||
|  |  | ||||||
|  |       # Scope of the search for modelines | ||||||
|  |       # Number of lines to check at the beginning and at the end of the file | ||||||
|  |       SEARCH_SCOPE = 5 | ||||||
|  |  | ||||||
|       # Public: Detects language based on Vim and Emacs modelines |       # Public: Detects language based on Vim and Emacs modelines | ||||||
|       # |       # | ||||||
|       # blob               - An object that quacks like a blob. |       # blob               - An object that quacks like a blob. | ||||||
| @@ -26,7 +30,9 @@ module Linguist | |||||||
|       # Returns an Array with one Language if the blob has a Vim or Emacs modeline |       # Returns an Array with one Language if the blob has a Vim or Emacs modeline | ||||||
|       # that matches a Language name or alias. Returns an empty array if no match. |       # that matches a Language name or alias. Returns an empty array if no match. | ||||||
|       def self.call(blob, _ = nil) |       def self.call(blob, _ = nil) | ||||||
|         Array(Language.find_by_alias(modeline(blob.data))) |         header = blob.lines.first(SEARCH_SCOPE).join("\n") | ||||||
|  |         footer = blob.lines.last(SEARCH_SCOPE).join("\n") | ||||||
|  |         Array(Language.find_by_alias(modeline(header + footer))) | ||||||
|       end |       end | ||||||
|  |  | ||||||
|       # Public: Get the modeline from the first n-lines of the file |       # Public: Get the modeline from the first n-lines of the file | ||||||
|   | |||||||
							
								
								
									
										397
									
								
								samples/C/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										397
									
								
								samples/C/main.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,397 @@ | |||||||
|  | // Copyright 2014 the V8 project authors. All rights reserved. | ||||||
|  | // Use of this source code is governed by a BSD-style license that can be | ||||||
|  | // found in the LICENSE file. | ||||||
|  |  | ||||||
|  | #include "src/runtime/runtime-utils.h" | ||||||
|  |  | ||||||
|  | #include "src/arguments.h" | ||||||
|  | #include "src/compiler.h" | ||||||
|  | #include "src/deoptimizer.h" | ||||||
|  | #include "src/frames-inl.h" | ||||||
|  | #include "src/full-codegen/full-codegen.h" | ||||||
|  | #include "src/isolate-inl.h" | ||||||
|  | #include "src/messages.h" | ||||||
|  | #include "src/v8threads.h" | ||||||
|  | #include "src/vm-state-inl.h" | ||||||
|  |  | ||||||
|  | namespace v8 { | ||||||
|  | namespace internal { | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_CompileLazy) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK_EQ(1, args.length()); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  |  | ||||||
|  | #ifdef DEBUG | ||||||
|  | 	if (FLAG_trace_lazy && !function->shared()->is_compiled()) { | ||||||
|  | 		PrintF("[unoptimized: "); | ||||||
|  | 		function->PrintName(); | ||||||
|  | 		PrintF("]\n"); | ||||||
|  | 	} | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 	StackLimitCheck check(isolate); | ||||||
|  | 	if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); | ||||||
|  | 	if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) { | ||||||
|  | 		return isolate->heap()->exception(); | ||||||
|  | 	} | ||||||
|  | 	DCHECK(function->is_compiled()); | ||||||
|  | 	return function->code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_CompileBaseline) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK_EQ(1, args.length()); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  | 	StackLimitCheck check(isolate); | ||||||
|  | 	if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); | ||||||
|  | 	if (!Compiler::CompileBaseline(function)) { | ||||||
|  | 		return isolate->heap()->exception(); | ||||||
|  | 	} | ||||||
|  | 	DCHECK(function->is_compiled()); | ||||||
|  | 	return function->code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK_EQ(1, args.length()); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  | 	StackLimitCheck check(isolate); | ||||||
|  | 	if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); | ||||||
|  | 	if (!Compiler::CompileOptimized(function, Compiler::CONCURRENT)) { | ||||||
|  | 		return isolate->heap()->exception(); | ||||||
|  | 	} | ||||||
|  | 	DCHECK(function->is_compiled()); | ||||||
|  | 	return function->code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK_EQ(1, args.length()); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  | 	StackLimitCheck check(isolate); | ||||||
|  | 	if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); | ||||||
|  | 	if (!Compiler::CompileOptimized(function, Compiler::NOT_CONCURRENT)) { | ||||||
|  | 		return isolate->heap()->exception(); | ||||||
|  | 	} | ||||||
|  | 	DCHECK(function->is_compiled()); | ||||||
|  | 	return function->code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_NotifyStubFailure) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK(args.length() == 0); | ||||||
|  | 	Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); | ||||||
|  | 	DCHECK(AllowHeapAllocation::IsAllowed()); | ||||||
|  | 	delete deoptimizer; | ||||||
|  | 	return isolate->heap()->undefined_value(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ActivationsFinder : public ThreadVisitor { | ||||||
|  | public: | ||||||
|  | 	Code* code_; | ||||||
|  | 	bool has_code_activations_; | ||||||
|  |  | ||||||
|  | 	explicit ActivationsFinder(Code* code) | ||||||
|  | 		: code_(code), has_code_activations_(false) {} | ||||||
|  |  | ||||||
|  | 	void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | ||||||
|  | 		JavaScriptFrameIterator it(isolate, top); | ||||||
|  | 		VisitFrames(&it); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void VisitFrames(JavaScriptFrameIterator* it) { | ||||||
|  | 		for (; !it->done(); it->Advance()) { | ||||||
|  | 			JavaScriptFrame* frame = it->frame(); | ||||||
|  | 			if (code_->contains(frame->pc())) has_code_activations_ = true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK(args.length() == 1); | ||||||
|  | 	CONVERT_SMI_ARG_CHECKED(type_arg, 0); | ||||||
|  | 	Deoptimizer::BailoutType type = | ||||||
|  | 		static_cast<Deoptimizer::BailoutType>(type_arg); | ||||||
|  | 	Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); | ||||||
|  | 	DCHECK(AllowHeapAllocation::IsAllowed()); | ||||||
|  | 	TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); | ||||||
|  | 	TRACE_EVENT0("v8", "V8.DeoptimizeCode"); | ||||||
|  |  | ||||||
|  | 	Handle<JSFunction> function = deoptimizer->function(); | ||||||
|  | 	Handle<Code> optimized_code = deoptimizer->compiled_code(); | ||||||
|  |  | ||||||
|  | 	DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); | ||||||
|  | 	DCHECK(type == deoptimizer->bailout_type()); | ||||||
|  |  | ||||||
|  | 	// Make sure to materialize objects before causing any allocation. | ||||||
|  | 	JavaScriptFrameIterator it(isolate); | ||||||
|  | 	deoptimizer->MaterializeHeapObjects(&it); | ||||||
|  | 	delete deoptimizer; | ||||||
|  |  | ||||||
|  | 	// Ensure the context register is updated for materialized objects. | ||||||
|  | 	JavaScriptFrameIterator top_it(isolate); | ||||||
|  | 	JavaScriptFrame* top_frame = top_it.frame(); | ||||||
|  | 	isolate->set_context(Context::cast(top_frame->context())); | ||||||
|  |  | ||||||
|  | 	if (type == Deoptimizer::LAZY) { | ||||||
|  | 		return isolate->heap()->undefined_value(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Search for other activations of the same optimized code. | ||||||
|  | 	// At this point {it} is at the topmost frame of all the frames materialized | ||||||
|  | 	// by the deoptimizer. Note that this frame does not necessarily represent | ||||||
|  | 	// an activation of {function} because of potential inlined tail-calls. | ||||||
|  | 	ActivationsFinder activations_finder(*optimized_code); | ||||||
|  | 	activations_finder.VisitFrames(&it); | ||||||
|  | 	isolate->thread_manager()->IterateArchivedThreads(&activations_finder); | ||||||
|  |  | ||||||
|  | 	if (!activations_finder.has_code_activations_) { | ||||||
|  | 		if (function->code() == *optimized_code) { | ||||||
|  | 			if (FLAG_trace_deopt) { | ||||||
|  | 				PrintF("[removing optimized code for: "); | ||||||
|  | 				function->PrintName(); | ||||||
|  | 				PrintF("]\n"); | ||||||
|  | 			} | ||||||
|  | 			function->ReplaceCode(function->shared()->code()); | ||||||
|  | 		} | ||||||
|  | 		// Evict optimized code for this function from the cache so that it | ||||||
|  | 		// doesn't get used for new closures. | ||||||
|  | 		function->shared()->EvictFromOptimizedCodeMap(*optimized_code, "notify deoptimized"); | ||||||
|  | 	} else { | ||||||
|  | 		// TODO(titzer): we should probably do DeoptimizeCodeList(code) | ||||||
|  | 		// unconditionally if the code is not already marked for deoptimization. | ||||||
|  | 		// If there is an index by shared function info, all the better. | ||||||
|  | 		Deoptimizer::DeoptimizeFunction(*function); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return isolate->heap()->undefined_value(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static bool IsSuitableForOnStackReplacement( | ||||||
|  | 	Isolate* isolate, | ||||||
|  | 	Handle<JSFunction> function | ||||||
|  | ) { | ||||||
|  | 	// Keep track of whether we've succeeded in optimizing. | ||||||
|  | 	if (function->shared()->optimization_disabled()) return false; | ||||||
|  | 	// If we are trying to do OSR when there are already optimized | ||||||
|  | 	// activations of the function, it means (a) the function is directly or | ||||||
|  | 	// indirectly recursive and (b) an optimized invocation has been | ||||||
|  | 	// deoptimized so that we are currently in an unoptimized activation. | ||||||
|  | 	// Check for optimized activations of this function. | ||||||
|  | 	for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { | ||||||
|  | 		JavaScriptFrame* frame = it.frame(); | ||||||
|  | 		if (frame->is_optimized() && frame->function() == *function) return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK(args.length() == 1); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  | 	Handle<Code> caller_code(function->shared()->code()); | ||||||
|  |  | ||||||
|  | 	// We're not prepared to handle a function with arguments object. | ||||||
|  | 	DCHECK(!function->shared()->uses_arguments()); | ||||||
|  |  | ||||||
|  | 	RUNTIME_ASSERT(FLAG_use_osr); | ||||||
|  |  | ||||||
|  | 	// Passing the PC in the javascript frame from the caller directly is | ||||||
|  | 	// not GC safe, so we walk the stack to get it. | ||||||
|  | 	JavaScriptFrameIterator it(isolate); | ||||||
|  | 	JavaScriptFrame* frame = it.frame(); | ||||||
|  | 	if (!caller_code->contains(frame->pc())) { | ||||||
|  | 		// Code on the stack may not be the code object referenced by the shared | ||||||
|  | 		// function info.	It may have been replaced to include deoptimization data. | ||||||
|  | 		caller_code = Handle<Code>(frame->LookupCode()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	uint32_t pc_offset = | ||||||
|  | 		static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); | ||||||
|  |  | ||||||
|  | #ifdef DEBUG | ||||||
|  | 	DCHECK_EQ(frame->function(), *function); | ||||||
|  | 	DCHECK_EQ(frame->LookupCode(), *caller_code); | ||||||
|  | 	DCHECK(caller_code->contains(frame->pc())); | ||||||
|  | #endif	// DEBUG | ||||||
|  |  | ||||||
|  | 	BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset); | ||||||
|  | 	DCHECK(!ast_id.IsNone()); | ||||||
|  |  | ||||||
|  | 	MaybeHandle<Code> maybe_result; | ||||||
|  | 	if (IsSuitableForOnStackReplacement(isolate, function)) { | ||||||
|  | 		if (FLAG_trace_osr) { | ||||||
|  | 			PrintF("[OSR - Compiling: "); | ||||||
|  | 			function->PrintName(); | ||||||
|  | 			PrintF(" at -*- scheme -*- %d]\n", ast_id.ToInt()); | ||||||
|  | 		} | ||||||
|  | 		maybe_result = Compiler::GetOptimizedCodeForOSR(function, ast_id, frame); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Revert the patched back edge table, regardless of whether OSR succeeds. | ||||||
|  | 	BackEdgeTable::Revert(isolate, *caller_code); | ||||||
|  |  | ||||||
|  | 	// Check whether we ended up with usable optimized code. | ||||||
|  | 	Handle<Code> result; | ||||||
|  | 	if (maybe_result.ToHandle(&result) | ||||||
|  | 	&& result->kind() == Code::OPTIMIZED_FUNCTION) { | ||||||
|  | 		DeoptimizationInputData* data = | ||||||
|  | 			DeoptimizationInputData::cast(result->deoptimization_data()); | ||||||
|  | 		 | ||||||
|  | 		if (data->OsrPcOffset()->value() >= 0) { | ||||||
|  | 			DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id); | ||||||
|  | 			if (FLAG_trace_osr) { | ||||||
|  | 				PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n", | ||||||
|  | 					ast_id.ToInt(), data->OsrPcOffset()->value()); | ||||||
|  | 			} | ||||||
|  | 			// TODO(titzer): this is a massive hack to make the deopt counts | ||||||
|  | 			// match. Fix heuristics for reenabling optimizations! | ||||||
|  | 			function->shared()->increment_deopt_count(); | ||||||
|  |  | ||||||
|  | 			if (result->is_turbofanned()) { | ||||||
|  | 				// TurboFanned OSR code cannot be installed into the function. | ||||||
|  | 				// But the function is obviously hot, so optimize it next time. | ||||||
|  | 				function->ReplaceCode( | ||||||
|  | 					isolate->builtins()->builtin(Builtins::kCompileOptimized)); | ||||||
|  | 			} else { | ||||||
|  | 				// Crankshafted OSR code can be installed into the function. | ||||||
|  | 				function->ReplaceCode(*result); | ||||||
|  | 			} | ||||||
|  | 			return *result; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Failed. | ||||||
|  | 	if (FLAG_trace_osr) { | ||||||
|  | 		PrintF("[OSR - Failed: "); | ||||||
|  | 		function->PrintName(); | ||||||
|  | 		PrintF(" at AST id %d]\n", ast_id.ToInt()); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (!function->IsOptimized()) { | ||||||
|  | 		function->ReplaceCode(function->shared()->code()); | ||||||
|  | 	} | ||||||
|  | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK(args.length() == 1); | ||||||
|  | 	CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | ||||||
|  |  | ||||||
|  | 	// First check if this is a real stack overflow. | ||||||
|  | 	StackLimitCheck check(isolate); | ||||||
|  | 	if (check.JsHasOverflowed()) { | ||||||
|  | 		SealHandleScope shs(isolate); | ||||||
|  | 		return isolate->StackOverflow(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); | ||||||
|  | 	return (function->IsOptimized()) | ||||||
|  | 		? function->code() | ||||||
|  | 		: function->shared()->code(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | bool CodeGenerationFromStringsAllowed( | ||||||
|  | 	Isolate* isolate, | ||||||
|  | 	Handle<Context> context | ||||||
|  | ){ | ||||||
|  | 	DCHECK(context->allow_code_gen_from_strings()->IsFalse()); | ||||||
|  | 	// Check with callback if set. | ||||||
|  | 	AllowCodeGenerationFromStringsCallback callback = | ||||||
|  | 			isolate->allow_code_gen_callback(); | ||||||
|  | 	if (callback == NULL) { | ||||||
|  | 		// No callback set and code generation disallowed. | ||||||
|  | 		return false; | ||||||
|  | 	} else { | ||||||
|  | 		// Callback set. Let it decide if code generation is allowed. | ||||||
|  | 		VMState<EXTERNAL> state(isolate); | ||||||
|  | 		return callback(v8::Utils::ToLocal(context)); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static Object* CompileGlobalEval( | ||||||
|  | 	Isolate* isolate, | ||||||
|  | 	Handle<String> source, | ||||||
|  | 	Handle<SharedFunctionInfo> outer_info, | ||||||
|  | 	LanguageMode language_mode, | ||||||
|  | 	int eval_scope_position, | ||||||
|  | 	int eval_position | ||||||
|  | ){ | ||||||
|  | 	Handle<Context> context = Handle<Context>(isolate->context()); | ||||||
|  | 	Handle<Context> native_context = Handle<Context>(context->native_context()); | ||||||
|  |  | ||||||
|  | 	// Check if native context allows code generation from | ||||||
|  | 	// strings. Throw an exception if it doesn't. | ||||||
|  | 	if (native_context->allow_code_gen_from_strings()->IsFalse() && | ||||||
|  | 	!CodeGenerationFromStringsAllowed(isolate, native_context)) { | ||||||
|  | 		Handle<Object> error_message = | ||||||
|  | 				native_context->ErrorMessageForCodeGenerationFromStrings(); | ||||||
|  | 		Handle<Object> error; | ||||||
|  | 		MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError( | ||||||
|  | 				MessageTemplate::kCodeGenFromStrings, error_message); | ||||||
|  | 		if (maybe_error.ToHandle(&error)) isolate->Throw(*error); | ||||||
|  | 		return isolate->heap()->exception(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Deal with a normal eval call with a string argument. Compile it | ||||||
|  | 	// and return the compiled function bound in the local context. | ||||||
|  | 	static const ParseRestriction restriction = NO_PARSE_RESTRICTION; | ||||||
|  | 	Handle<JSFunction> compiled; | ||||||
|  | 	ASSIGN_RETURN_ON_EXCEPTION_VALUE( | ||||||
|  | 		isolate, compiled, | ||||||
|  | 		Compiler::GetFunctionFromEval( | ||||||
|  | 			source, outer_info, context, language_mode, | ||||||
|  | 			restriction, eval_scope_position, eval_position | ||||||
|  | 		), | ||||||
|  | 		isolate->heap()->exception() | ||||||
|  | 	); | ||||||
|  | 	return *compiled; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RUNTIME_FUNCTION(Runtime_ResolvePossiblyDirectEval) { | ||||||
|  | 	HandleScope scope(isolate); | ||||||
|  | 	DCHECK(args.length() == 6); | ||||||
|  |  | ||||||
|  | 	Handle<Object> callee = args.at<Object>(0); | ||||||
|  |  | ||||||
|  | 	// If "eval" didn't refer to the original GlobalEval, it's not a | ||||||
|  | 	// direct call to eval. | ||||||
|  | 	// (And even if it is, but the first argument isn't a string, just let | ||||||
|  | 	// execution default to an indirect call to eval, which will also return | ||||||
|  | 	// the first argument without doing anything). | ||||||
|  | 	if (*callee != isolate->native_context()->global_eval_fun() || !args[1]->IsString()) { | ||||||
|  | 		return *callee; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	DCHECK(args[3]->IsSmi()); | ||||||
|  | 	DCHECK(is_valid_language_mode(args.smi_at(3))); | ||||||
|  | 	LanguageMode language_mode = static_cast<LanguageMode>(args.smi_at(3)); | ||||||
|  | 	DCHECK(args[4]->IsSmi()); | ||||||
|  | 	Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(), isolate); | ||||||
|  | 	return CompileGlobalEval( | ||||||
|  | 		isolate, | ||||||
|  | 		args.at<String>(1), | ||||||
|  | 		outer_info, | ||||||
|  | 		language_mode, | ||||||
|  | 		args.smi_at(4), | ||||||
|  | 		args.smi_at(5) | ||||||
|  | 	); | ||||||
|  | } | ||||||
|  | }	// namespace internal | ||||||
|  | }	// namespace v8 | ||||||
|  |  | ||||||
|  | /* vim: set shiftwidth=4 softtabstop=0 cindent cinoptions={1s: */ | ||||||
|  |  | ||||||
| @@ -31,6 +31,7 @@ class TestModelines < Minitest::Test | |||||||
|     assert_modeline Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl") |     assert_modeline Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl") | ||||||
|     assert_modeline Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md") |     assert_modeline Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md") | ||||||
|     assert_modeline Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc") |     assert_modeline Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc") | ||||||
|  |     assert_modeline nil, sample_blob("C/main.c") | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def test_modeline_languages |   def test_modeline_languages | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user