Commit graph

19 commits

Author SHA1 Message Date
Brad Jorsch b58ee1da94 Use the new limit report hooks
Change Ie065c7b5 added an option to show profiling data at the bottom of
preview pages, and with it new hooks to gather and format this data in a
more structured way than is possible with ParserLimitReport. This change
adds support for the new hooks.

Depends-On: I7799616a602d90e1b8d3f0ece35811ca387bade7
Change-Id: Idffd2d78f9a0217c99c07cbbfc844d6daf0172f7
2014-02-10 04:11:35 +00:00
Brad Jorsch 5989d28678 (bug 39655) Add Lua version info to Special:Version
Use the SoftwareInfo hook to add the versions of LuaSandbox and Lua to
Special:Version.

Bug: 39655
Change-Id: I912197efee0211066677c4d46e638fb546a410c6
2013-03-25 04:07:30 +00:00
Brad Jorsch 0dc45ff2f8 Improve caching in fetchModuleFromParser
On my test system, ScriuntoHooks::invokeHook takes about 4 seconds of
CPU time during the parse of a page containing 1000 #invokes of a module
containing a single do-nothing function. And about 2.3 of those seconds
appear to be spent in ScribuntoEngineBase::fetchModuleFromParser.

ScribuntoEngineBase::fetchModuleFromParser already assumes that if
Parser::fetchTemplateAndTitle returns the same $finalTitle then $text is
also the same and we can reuse the same module. But it seems just as
likely that the same input $title is always going to give the same
$finalTitle, so we may as well skip calling
Parser::fetchTemplateAndTitle entirely if we've seen the input $title
before.

This change takes the CPU time spent in ScriuntoHooks::invokeHook in the
test described above down to about 1.5 seconds. And since it's very
likely that $title and $finalTitle are the same (Modules don't support
redirects, so it's basically TemplateSandbox that would cause that), it
probably doesn't even increase the size of the module cache.

Change-Id: I87ad8b85d0f82791f49158d62effa6dc7c20f058
2013-03-20 02:13:33 +00:00
Chad Horohoe c98cc64545 Allow extensions to add libraries
Wikidata has already requested the ability to add libraries into Lua. We
do this in a simple way: add a $wgScribuntoExtraLibraries global, and
load whatever modules someone puts there.

Change-Id: I460b4e7b968eb02dd86620f1e4b50daf1be9e901
2013-02-14 12:38:03 -05:00
Brad Jorsch 4c69b1350e Lua library support functions
Adds a base class for libraries with some utility functions in PHP, and a
Lua library with utility functions for use from Lua.

Change-Id: I3d67b1de8bc50488fe3a722e4e2de5849285d127
2013-01-31 12:40:39 -05:00
Tim Starling 996ea62765 LuaSandbox profiler support
Add a profiler report to the limit report for pages with more than 1s
of Lua time. Uses the profiler introduced in I0b83a914 of LuaSandbox.

Also, fixed some circular references which were preventing the
LuaSandbox object from being destroyed when Scribunto::resetEngine()
was called. Otherwise a large number of interval timers could be started
due to a LuaSandbox object resource leak.

Change-Id: I5487fe2623974939d07f09f7197e86a5f297a8f1
2012-09-06 01:00:20 +00:00
Tim Starling b5c36bad59 Debug console module
* Added a debug console to the edit page, allowing unsaved modules to be
  tested.
* Removed the "preview" button from the edit page.
* Only show the "ignore code errors" checkbox on module edit pages, not
  all edit pages.
* Added Lua function mw.log() for sending messages to the debug log.

Change-Id: Ia51f439e573a1deb5b83f94ddd1a86792d5569c1
2012-07-14 14:35:55 +10:00
Reedy 5afbf6a7c7 Some bits of documentation
Left a FIXME

Remove some unused variables

Change-Id: If733608416e68de6afe1e8f6edd4ed78a119979e
2012-06-20 23:54:21 +01:00
Tim Starling 6bc11ff615 New parser interface
* Implemented the new parser interface based on a frame object, as
  described in the design document and wikitech-l.
* Added parser tests for the new interface.
* Removed {{script:}} parser function
* Allow named parameters to {{#invoke:}}
* Don't trim the return value
* If a function invoked by #invoke returns multiple values, concatenate
  them into a single string.
* If there is an error during parse, show the error message as an HTML
  comment as well as via JavaScript. This makes parser test construction
  easier, and probably makes debugging easier also.
* Rename mw_internal to mw_php to clarify its role. It is now strictly a
  private Lua -> PHP interface function table.
* Protect mw.setup() against multiple invocation.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::receiveMessage():
  large packets caused fread() to return with less than the requested
  amount of data, which previously caused an exception. It's necessary
  to check for EOF and to repeat the read to get all data. The receive
  function on the Lua side does not suffer from this problem.
* In the standalone engine, fixed a bug in the interpretation of null
  return values from PHP callbacks. This should return no values to Lua.
* Updated the Lua unit tests to account for the fact that functions are
  now forced to return strings.
* Updated the getfenv and setfenv tests to account for the extra stack
  level introduced by mw.executeFunction().

Change-Id: If8fdecdfc91ebe7bd4b1dae8489ccbdeb6bbf5ce
2012-05-22 14:18:49 +10:00
Tim Starling da06273ede Nicer errors with backtraces etc.
* Added error backtrace collection to MWServer:handleCall()
* When there is an error on parse, show a short and simple inline error
  message to the user, which when clicked, expands to a full error with
  HTML-formatted backtrace.
* When an error is encountered during module validation, have the code
  editor jump directly to the line. Requires r115011.
* Expose the code location of most errors to Scribunto, by parsing the
  standard error message format.
* During module validation, abbreviate the error location if the error
  is in the same module.
* Do not execute the module during validation, just parse it. Execution
  does not really work without an active parse operation in progress.
  It already caused a fatal error if you called require() from the main
  chunk, and problems would have become more visible as more
  parser-related APIs were added.
* LuaSandbox does not yet provide backtraces, but this is planned.

Change-Id: Id9f6564a41b310792b3fe3ebb527cbf8f8771bd1
2012-04-23 21:58:30 +10:00
tstarling b68cae904a More tests and some related bug fixes
* Added tests for the engine classes.
* Added some tests that run under Lua.
* In the chunk names, fixed truncation of module names at 60 bytes
  by using an "=" prefix instead of @.
* Fixed a bug in mw.clone() which was causing the metatable to be set on
  the source table instead of the destination.
* Put restricted setfenv/getfenv in the cloned environment rather than
  the base environment, they work better that way.
* In setfenv(), check for getfenv() == nil, since that's what our own
  restricted getfenv returns.
* Fixed getfenv() handling of numeric arguments: add one where
  appropriate.

Change-Id: I2b356fd65a3fcb348c4e99a3a4267408fb995739
2012-04-19 17:48:20 +10:00
tstarling cebe775ee8 Added more Lua environment features
Package library:

* Added a simulation of the Lua 5.1 package library.
* Removed mw.import(), replaced it with a package loader. Packages can be
  retrieved from the wiki, using require('Module:Foo'), or from files
  distributed with Scribunto, using require('foo'). The "Module:" prefix allows
  for source compatibility with existing Lua code.
* Added a couple of libraries from LuaForge: luabit and stringtools.
* Made fetchModuleFromParser() return null on error instead of throwing an
  exception, to more easily support the desired behaviour of the package loader,
  which needs to return null on error.
* Renamed mw.setupEnvironment() to mw.setup() since it is setting up things
  other than the environment now.
* In MWServer:handleRegisterLibrary(), remove the feature which interprets dots
  in library names, since LuaSandbox doesn't support this.

Improved module isolation and related refactoring:

* Expose restricted versions of getfenv() and setfenv() to user Lua code.
  Requires luasandbox r114952.
* Don't cache the export list returned by module execution for later function
  calls. This breaks isolation of #invoke calls, since the local variables are
  persistent.
* Removed ScribuntoFunctionBase and its children, since it doesn't really have
  a purpose if it can't cache anything. Instead, invoke functions using a module
  method called invoke().
* Removed Module::initialize(), replaced it with a validate() function. This is
  a more elegant interface and works better with the new module caching scheme.
* Use a Status object for the return value of Engine::validate() instead of an
  array. Use the formatting facilities of the Status class.

Other:

* Removed "too many returns" error, doesn't fit in with Lua conventions.
* Use the standalone engine by default, so that the extension will work without
  configuration for more people.
* Added an accessor for $engine->interpreter
* Fix mw.clone() to correctly clone metatables
* If the standalone interpreter exits due to an error, there are some contexts
  where the initial error will be caught and ignored, and the user will see the
  error from checkValid() instead. In this case, rethrow the original error for
  a more informative message.
* Load mw.lua into the initial standalone environment, to reduce code
  duplication between mw.lua and MWServer.lua.
* Fixed a bug in Scribunto_LuaStandaloneInterpreter::handleCall() for functions
  that return no results.
* Fixed a bug in encodeLuaVar() for strings with "\r". Added test case.
* In MWServer.lua, don't call error() for internal errors, instead just print
  the error and exit. This avoids a protocol violation when an error is
  encountered from within handleCall().
* Added lots of documentation. Lua doc comments are in LuaDoc format.

Change-Id: Ie2fd572c362bedf02f45d3fa5352a5280e034740
2012-04-18 13:46:18 +10:00
tstarling 54cedd69b8 Introduced standalone interpreter, implemented module isolation
* Introduced a Lua implementation based on shelling out to a standard Lua binary.
* Bundled several Lua binaries for common platforms. I haven't added a 32-bit Linux binary yet, but that will come.
* Refactored the existing Lua class, bringing out functionality common to all Lua implementations into a set of common base classes.
* Moved the bulk of the implementation-specific functionality into a set of "interpreter" classes.
* Renamed LuaSandboxEngine to Scribunto_LuaSandboxEngine
* Don't create an engine object unconditionally when the ParserLimitReport hook is called.
* Implemented isolation of module global variable namespaces. This means that separate {{#invoke}} calls can't pass data to each other -- this was a desired feature in planning since it allows more flexibility in wikitext parser design. Isolation for mw.import() means that modules cannot accidentally create global variables which affect other modules -- exports are solely via the return value.

Change-Id: I3fa35651fe5b1fbfd85adeadc220b1ea31cd6f0b
2012-04-13 20:45:26 +10:00
Tim Starling 30622e86fe More changes for extension rename 2012-04-06 05:04:30 +00:00
Tim Starling 925045a669 * Removed scriptlinks table. It just seemed the same as templatelinks to me, and tl_namespace can be used if you want to separate out modules.
* Used Parser::fetchTemplateAndTitle() to get modules and register them in templatelinks. Most of the logic was previously duplicated.
* Changed the configuration and factory functions to allow for the possibility of multiple engines coexisting on the one wiki.
* Made the $parser parameter optional, to improve debugging in the case where a parser is needed but parsing has not started. Removed all $wgParser references.
* Renamed Scripting::getEngine() to getParserEngine() and resetEngine() to resetParserEngine()
* Removed setOptions() and updateOptions(). If you want to change the options, you can always make a new instance.
* Renamed getModule() to fetchModuleFromParser()
* Simplified module constructor parameters and member variable list
* Fixed spelling error langauge -> language
* Renamed a few variables for clarity: $module -> $moduleName, $function -> $functionName
* Renamed getLimitsReport() to getLimitReport() as it is in Parser
* Use an accessor for getting LuaSandboxEngineModule::$contents
* Renamed configuration variable maxCPU to cpuLimit
* Include the full message name as a parameter to ScriptingException. This makes it easier to find messages in the i18n file, and it makes it easier to find invocation points when a translator wants to know how a message is used. Adding the message name as a comment on the same line seems like a waste of space when you can just make it an actual parameter.
* Reduce the number of formal parameters to ScriptingException::__construct(), since there is already too many and we may want to add more things later, such as backtraces with hyperlinks and other such stuff.
* Include the code location as $2 unconditionally so that there is less chance of getting the parameters wrong
* Shortened some message names. Wrote English text for messages without it.
2012-04-05 07:58:02 +00:00
Tim Starling 64474eb0fa * Remove old-fashioned "m" prefix from member variables
* Make ScriptingEngineBase::getDefaultOptions() non-abstract since there is a reasonable default behaviour which can be implemented
2012-04-05 03:53:05 +00:00
Tim Starling c8f4d0a213 First-pass cleanup:
* Removed ScriptingEngineBase::load(), inappropriate interface specification, only used by child classes and more properly defined by them
* Fixed inappropriate use of final
* Fixed case of a class constant to conform with MediaWiki conventions
* Use a factory function interface for module creation instead of a class name accessor
* Don't pass unnecessary $engine parameter to ScriptingFunctionBase::__construct(). Pass parent object as the first parameter per convention.
* Fixed unnecessary reference parameter in doRunHook()
* Have LuaSandboxEngineFunction::call() return the first result or null, per the base class documentation, instead of imploding. 
* Use strval() to avoid a warning in case call() returns an array or object
* Improved some comments
2012-04-04 06:10:32 +00:00
vvv 03bf6ce779 Add integration with CodeEditor extension. 2012-02-06 22:14:47 +00:00
vvv b960075a55 Commiting the initial revision of the Scripting extension, a framework that allows programming languages to be embedded regardless of what are those languages actually are and how they are interpreted.
This is a very raw version, and it misses most messages (even in English!) and probably needs some more work.
2012-01-28 16:22:18 +00:00